summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rw-r--r--apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java99
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java14
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java52
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java6
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java34
-rw-r--r--cmds/svc/src/com/android/commands/svc/UsbCommand.java72
-rw-r--r--core/api/current.txt38
-rw-r--r--core/api/module-lib-current.txt2
-rw-r--r--core/api/system-current.txt9
-rw-r--r--core/api/test-current.txt3
-rw-r--r--core/java/android/app/Activity.java14
-rw-r--r--core/java/android/app/ActivityManagerInternal.java27
-rw-r--r--core/java/android/app/Dialog.java14
-rw-r--r--core/java/android/app/GameManager.java15
-rw-r--r--core/java/android/app/IGameManagerService.aidl1
-rw-r--r--core/java/android/app/Instrumentation.java111
-rw-r--r--core/java/android/app/UiAutomationConnection.java34
-rw-r--r--core/java/android/content/Context.java48
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java3
-rw-r--r--core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java28
-rw-r--r--core/java/android/content/res/Configuration.java45
-rw-r--r--core/java/android/hardware/biometrics/BiometricConstants.java23
-rw-r--r--core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java26
-rw-r--r--core/java/android/hardware/face/FaceManager.java17
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintManager.java18
-rw-r--r--core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl15
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl7
-rw-r--r--core/java/android/hardware/input/InputManager.java54
-rw-r--r--core/java/android/hardware/input/InputManagerInternal.java9
-rw-r--r--core/java/android/hardware/usb/IUsbManager.aidl2
-rw-r--r--core/java/android/hardware/usb/UsbManager.java4
-rw-r--r--core/java/android/hardware/usb/UsbOperationInternal.java38
-rw-r--r--core/java/android/hardware/usb/UsbPort.java85
-rw-r--r--core/java/android/os/GraphicsEnvironment.java7
-rw-r--r--core/java/android/os/SystemProperties.java5
-rw-r--r--core/java/android/os/UserManager.java6
-rw-r--r--core/java/android/os/image/DynamicSystemManager.java18
-rw-r--r--core/java/android/os/image/IDynamicSystemService.aidl4
-rw-r--r--core/java/android/provider/DeviceConfig.java9
-rw-r--r--core/java/android/service/carrier/OWNERS6
-rw-r--r--core/java/android/service/dreams/DreamService.java4
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java11
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java5
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletService.java8
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java16
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java4
-rw-r--r--core/java/android/text/TextUtils.java47
-rw-r--r--core/java/android/util/SparseSetArray.java19
-rw-r--r--core/java/android/view/IDisplayWindowInsetsController.aidl4
-rw-r--r--core/java/android/view/IWindowManager.aidl11
-rw-r--r--core/java/android/view/InsetsController.java4
-rw-r--r--core/java/android/view/InsetsState.java11
-rw-r--r--core/java/android/view/SurfaceControl.java23
-rw-r--r--core/java/android/view/SurfaceView.java64
-rw-r--r--core/java/android/view/View.java72
-rw-r--r--core/java/android/view/ViewGroup.java22
-rw-r--r--core/java/android/view/ViewParent.java17
-rw-r--r--core/java/android/view/ViewRootImpl.java17
-rw-r--r--core/java/android/view/ViewRootInsetsControllerHost.java9
-rw-r--r--core/java/android/view/Window.java9
-rw-r--r--core/java/android/view/WindowManager.java2
-rw-r--r--core/java/android/view/animation/Animation.java92
-rw-r--r--core/java/android/widget/Editor.java7
-rw-r--r--core/java/android/widget/MediaController.java7
-rw-r--r--core/java/android/widget/TextView.java11
-rw-r--r--core/java/android/window/ITaskFragmentOrganizerController.aidl6
-rw-r--r--core/java/android/window/OnBackAnimationCallback.java61
-rw-r--r--core/java/android/window/OnBackInvokedCallback.java59
-rw-r--r--core/java/android/window/OnBackInvokedDispatcher.java10
-rw-r--r--core/java/android/window/OnBackInvokedDispatcherOwner.java33
-rw-r--r--core/java/android/window/ProxyOnBackInvokedDispatcher.java56
-rw-r--r--core/java/android/window/TaskFragmentOrganizer.java13
-rw-r--r--core/java/android/window/TransitionRequestInfo.java22
-rw-r--r--core/java/android/window/WindowOnBackInvokedDispatcher.java32
-rw-r--r--core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java15
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java16
-rw-r--r--core/java/com/android/internal/app/LocalePickerWithRegion.java7
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java14
-rw-r--r--core/java/com/android/internal/app/SuggestedLocaleAdapter.java4
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java13
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java6
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl2
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl2
-rw-r--r--core/java/com/android/internal/widget/BigPictureNotificationImageView.java38
-rw-r--r--core/java/com/android/server/SystemConfig.java40
-rw-r--r--core/jni/android_hardware_input_InputApplicationHandle.cpp5
-rw-r--r--core/jni/android_hardware_input_InputWindowHandle.cpp11
-rw-r--r--core/jni/android_view_SurfaceControl.cpp11
-rw-r--r--core/jni/android_window_WindowInfosListener.cpp2
-rw-r--r--core/res/AndroidManifest.xml2
-rw-r--r--core/res/OWNERS3
-rw-r--r--core/res/res/layout/accessibility_enable_service_warning.xml (renamed from core/res/res/layout/accessibility_enable_service_encryption_warning.xml)8
-rw-r--r--core/res/res/values-af/strings.xml3
-rw-r--r--core/res/res/values-am/strings.xml3
-rw-r--r--core/res/res/values-as/strings.xml9
-rw-r--r--core/res/res/values-be/strings.xml3
-rw-r--r--core/res/res/values-bg/strings.xml3
-rw-r--r--core/res/res/values-bn/strings.xml3
-rw-r--r--core/res/res/values-bs/strings.xml2
-rw-r--r--core/res/res/values-ca/strings.xml7
-rw-r--r--core/res/res/values-cs/strings.xml12
-rw-r--r--core/res/res/values-da/strings.xml3
-rw-r--r--core/res/res/values-el/strings.xml12
-rw-r--r--core/res/res/values-en-rAU/strings.xml9
-rw-r--r--core/res/res/values-en-rCA/strings.xml9
-rw-r--r--core/res/res/values-en-rGB/strings.xml9
-rw-r--r--core/res/res/values-en-rIN/strings.xml9
-rw-r--r--core/res/res/values-en-rXC/strings.xml9
-rw-r--r--core/res/res/values-es-rUS/strings.xml3
-rw-r--r--core/res/res/values-es/strings.xml3
-rw-r--r--core/res/res/values-et/strings.xml3
-rw-r--r--core/res/res/values-eu/strings.xml6
-rw-r--r--core/res/res/values-fa/strings.xml3
-rw-r--r--core/res/res/values-fi/strings.xml3
-rw-r--r--core/res/res/values-fr-rCA/strings.xml3
-rw-r--r--core/res/res/values-fr/strings.xml3
-rw-r--r--core/res/res/values-gl/strings.xml3
-rw-r--r--core/res/res/values-hu/strings.xml3
-rw-r--r--core/res/res/values-hy/strings.xml3
-rw-r--r--core/res/res/values-in/strings.xml3
-rw-r--r--core/res/res/values-is/strings.xml3
-rw-r--r--core/res/res/values-it/strings.xml3
-rw-r--r--core/res/res/values-iw/strings.xml6
-rw-r--r--core/res/res/values-ja/strings.xml12
-rw-r--r--core/res/res/values-ka/strings.xml3
-rw-r--r--core/res/res/values-kk/strings.xml3
-rw-r--r--core/res/res/values-km/strings.xml3
-rw-r--r--core/res/res/values-ko/strings.xml3
-rw-r--r--core/res/res/values-ky/strings.xml3
-rw-r--r--core/res/res/values-lo/strings.xml3
-rw-r--r--core/res/res/values-lt/strings.xml3
-rw-r--r--core/res/res/values-lv/strings.xml3
-rw-r--r--core/res/res/values-ml/strings.xml9
-rw-r--r--core/res/res/values-mn/strings.xml9
-rw-r--r--core/res/res/values-mr/strings.xml5
-rw-r--r--core/res/res/values-my/strings.xml3
-rw-r--r--core/res/res/values-nb/strings.xml3
-rw-r--r--core/res/res/values-ne/strings.xml3
-rw-r--r--core/res/res/values-nl/strings.xml3
-rw-r--r--core/res/res/values-or/strings.xml3
-rw-r--r--core/res/res/values-pa/strings.xml3
-rw-r--r--core/res/res/values-pl/strings.xml3
-rw-r--r--core/res/res/values-pt-rBR/strings.xml12
-rw-r--r--core/res/res/values-pt-rPT/strings.xml3
-rw-r--r--core/res/res/values-pt/strings.xml12
-rw-r--r--core/res/res/values-ru/strings.xml3
-rw-r--r--core/res/res/values-si/strings.xml3
-rw-r--r--core/res/res/values-sk/strings.xml12
-rw-r--r--core/res/res/values-sl/strings.xml12
-rw-r--r--core/res/res/values-sq/strings.xml3
-rw-r--r--core/res/res/values-sv/strings.xml3
-rw-r--r--core/res/res/values-sw/strings.xml3
-rw-r--r--core/res/res/values-th/strings.xml9
-rw-r--r--core/res/res/values-tl/strings.xml9
-rw-r--r--core/res/res/values-tr/strings.xml3
-rw-r--r--core/res/res/values-uk/strings.xml3
-rw-r--r--core/res/res/values-uz/strings.xml3
-rw-r--r--core/res/res/values-vi/strings.xml3
-rw-r--r--core/res/res/values-zh-rCN/strings.xml3
-rw-r--r--core/res/res/values-zh-rHK/strings.xml3
-rw-r--r--core/res/res/values-zh-rTW/strings.xml3
-rw-r--r--core/res/res/values/attrs.xml8
-rw-r--r--core/res/res/values/config.xml84
-rw-r--r--core/res/res/values/config_telephony.xml112
-rw-r--r--core/res/res/values/public-staging.xml5
-rw-r--r--core/res/res/values/strings.xml15
-rw-r--r--core/res/res/values/symbols.xml23
-rw-r--r--core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java28
-rw-r--r--core/tests/coretests/src/android/text/TextUtilsTest.java76
-rw-r--r--core/tests/coretests/src/android/window/BackNavigationTest.java7
-rw-r--r--core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java4
-rw-r--r--core/tests/coretests/src/com/android/internal/widget/OWNERS4
-rw-r--r--data/etc/platform.xml56
-rw-r--r--data/etc/privapp-permissions-platform.xml20
-rw-r--r--data/etc/services.core.protolog.json6
-rw-r--r--framework-jarjar-rules.txt3
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java27
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java)74
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java21
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java114
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java6
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java32
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java25
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java15
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java4
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/util/PriorityDataProducer.java56
-rw-r--r--libs/WindowManager/Jetpack/tests/OWNERS2
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java91
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java8
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java95
-rw-r--r--libs/WindowManager/Shell/res/drawable/home_icon.xml45
-rw-r--r--libs/WindowManager/Shell/res/drawable/tv_pip_menu_background.xml23
-rw-r--r--libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml23
-rw-r--r--libs/WindowManager/Shell/res/layout/tv_pip_menu.xml63
-rw-r--r--libs/WindowManager/Shell/res/layout/tv_pip_menu_background.xml28
-rw-r--r--libs/WindowManager/Shell/res/values-tvdpi/dimen.xml16
-rw-r--r--libs/WindowManager/Shell/res/values/colors_tv.xml6
-rw-r--r--libs/WindowManager/Shell/res/values/styles.xml9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java76
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/CenteredImageSpan.java76
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt70
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java250
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java171
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java130
-rw-r--r--libs/WindowManager/Shell/tests/OWNERS2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java49
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java14
-rw-r--r--location/java/android/location/LocationDeviceConfig.java32
-rw-r--r--media/Android.bp9
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/.hash1
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioChannelLayout.aidl134
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioConfig.aidl41
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioConfigBase.aidl41
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioContentType.aidl44
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDevice.aidl40
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceAddress.aidl43
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceDescription.aidl52
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceType.aidl71
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationMetadataType.aidl41
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationMode.aidl42
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationType.aidl40
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioFormatDescription.aidl41
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioFormatType.aidl42
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGain.aidl47
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGainConfig.aidl43
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGainMode.aidl41
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioInputFlags.aidl47
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioIoFlags.aidl40
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicy.aidl42
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicyInfo.aidl40
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicyType.aidl40
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMode.aidl47
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioOffloadInfo.aidl50
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioOutputFlags.aidl56
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPort.aidl45
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortConfig.aidl46
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortDeviceExt.aidl42
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortExt.aidl42
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortMixExt.aidl43
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortMixExtUseCase.aidl41
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioProfile.aidl43
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioSource.aidl54
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioStandard.aidl40
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioStreamType.aidl55
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioUsage.aidl61
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioUuid.aidl43
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/ExtraAudioDescriptor.aidl41
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/Int.aidl39
-rw-r--r--media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/PcmType.aidl45
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/.hash1
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/AudioCapabilities.aidl40
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ConfidenceLevel.aidl40
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ModelParameter.aidl40
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ModelParameterRange.aidl40
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Phrase.aidl43
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseRecognitionEvent.aidl40
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseRecognitionExtra.aidl42
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseSoundModel.aidl40
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Properties.aidl53
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionConfig.aidl42
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionEvent.aidl47
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionMode.aidl42
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionStatus.aidl43
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/SoundModel.aidl43
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/SoundModelType.aidl41
-rw-r--r--media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Status.aidl45
-rw-r--r--media/java/android/media/AudioManager.java10
-rw-r--r--media/tests/aidltests/Android.bp1
-rw-r--r--mms/OWNERS18
-rw-r--r--packages/CarrierDefaultApp/OWNERS17
-rw-r--r--packages/CompanionDeviceManager/res/values-af/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-am/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-be/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-bg/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-bn/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-bs/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ca/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-cs/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-da/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-el/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-es-rUS/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-es/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-et/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-eu/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-fa/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-fi/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-fr/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-gl/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-hu/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-hy/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-in/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-is/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-it/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-iw/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-ja/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-ka/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-kk/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-km/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-ko/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-ky/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-lo/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-lt/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-lv/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-mr/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-my/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-nb/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-ne/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-nl/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-or/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-pa/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-pl/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-pt/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-ru/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-si/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-sk/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-sl/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-sq/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-sv/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-sw/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-tr/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-uk/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-uz/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-vi/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml9
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml9
-rw-r--r--packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java7
-rw-r--r--packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags1
-rw-r--r--packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java93
-rw-r--r--packages/SettingsLib/AndroidManifest.xml10
-rw-r--r--packages/SettingsLib/HelpUtils/res/values-ar/strings.xml2
-rw-r--r--packages/SettingsLib/res/drawable-v31/settingslib_tabs_background.xml8
-rw-r--r--packages/SettingsLib/res/drawable-v31/settingslib_tabs_indicator_background.xml2
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml28
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml35
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml35
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml8
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java230
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java225
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java31
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeActivity.java109
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeBaseActivity.java46
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeController.java82
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeFragment.java235
-rw-r--r--packages/Shell/AndroidManifest.xml3
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java10
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java5
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java6
-rw-r--r--packages/SystemUI/res-keyguard/layout/fgs_footer.xml7
-rw-r--r--packages/SystemUI/res-keyguard/layout/footer_actions.xml111
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml19
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml19
-rw-r--r--packages/SystemUI/res-keyguard/layout/new_footer_actions.xml97
-rw-r--r--packages/SystemUI/res/drawable/fgs_dot.xml (renamed from packages/SystemUI/res/drawable/new_fgs_dot.xml)0
-rw-r--r--packages/SystemUI/res/drawable/overlay_cancel.xml2
-rw-r--r--packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml42
-rw-r--r--packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml35
-rw-r--r--packages/SystemUI/res/drawable/qs_footer_action_circle.xml2
-rw-r--r--packages/SystemUI/res/drawable/qs_footer_action_circle_color.xml2
-rw-r--r--packages/SystemUI/res/layout/clipboard_overlay.xml1
-rw-r--r--packages/SystemUI/res/layout/media_output_dialog.xml1
-rw-r--r--packages/SystemUI/res/layout/media_session_view.xml4
-rw-r--r--packages/SystemUI/res/layout/qs_footer_impl.xml15
-rw-r--r--packages/SystemUI/res/layout/qs_panel.xml9
-rw-r--r--packages/SystemUI/res/layout/qs_tile_label.xml6
-rw-r--r--packages/SystemUI/res/layout/quick_settings_security_footer.xml19
-rw-r--r--packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml12
-rw-r--r--packages/SystemUI/res/layout/screenshot_static.xml1
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_shelf.xml1
-rw-r--r--packages/SystemUI/res/layout/udfps_view.xml6
-rw-r--r--packages/SystemUI/res/values-af/strings.xml55
-rw-r--r--packages/SystemUI/res/values-am/strings.xml55
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml58
-rw-r--r--packages/SystemUI/res/values-as/strings.xml48
-rw-r--r--packages/SystemUI/res/values-az/strings.xml55
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml58
-rw-r--r--packages/SystemUI/res/values-be/strings.xml58
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml58
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml58
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml57
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml58
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml51
-rw-r--r--packages/SystemUI/res/values-da/strings.xml55
-rw-r--r--packages/SystemUI/res/values-de/strings.xml58
-rw-r--r--packages/SystemUI/res/values-el/strings.xml51
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml32
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml32
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml32
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml32
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml32
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml55
-rw-r--r--packages/SystemUI/res/values-es/strings.xml55
-rw-r--r--packages/SystemUI/res/values-et/strings.xml62
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml58
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml58
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml58
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml58
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml60
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml58
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml58
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml58
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml55
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml55
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml58
-rw-r--r--packages/SystemUI/res/values-in/strings.xml58
-rw-r--r--packages/SystemUI/res/values-is/strings.xml58
-rw-r--r--packages/SystemUI/res/values-it/strings.xml58
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml58
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml55
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml55
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml60
-rw-r--r--packages/SystemUI/res/values-km/strings.xml58
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml55
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml58
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml59
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml58
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml58
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml58
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml55
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml51
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml48
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml57
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml58
-rw-r--r--packages/SystemUI/res/values-my/strings.xml60
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml58
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml55
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml57
-rw-r--r--packages/SystemUI/res/values-or/strings.xml58
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml58
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml58
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml48
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml58
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml48
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml55
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml58
-rw-r--r--packages/SystemUI/res/values-si/strings.xml58
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml51
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml51
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml58
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml58
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml58
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml58
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml55
-rw-r--r--packages/SystemUI/res/values-te/strings.xml55
-rw-r--r--packages/SystemUI/res/values-th/strings.xml48
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml48
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml58
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml58
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml58
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml58
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml58
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml58
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml58
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml58
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml55
-rw-r--r--packages/SystemUI/res/values/attrs.xml6
-rw-r--r--packages/SystemUI/res/values/colors.xml4
-rw-r--r--packages/SystemUI/res/values/config.xml4
-rw-r--r--packages/SystemUI/res/values/dimens.xml15
-rw-r--r--packages/SystemUI/res/values/strings.xml9
-rw-r--r--packages/SystemUI/res/values/styles.xml10
-rw-r--r--packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt20
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java8
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java19
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java19
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java9
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java172
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java12
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmTypes.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java145
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt55
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java210
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeLog.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java56
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/dump/DumpsysTableLogger.kt125
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt122
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHost.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt79
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooter.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java100
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/TileLayout.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt120
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt86
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt94
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityState.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalController.java71
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/DualHeightHorizontalLinearLayout.kt183
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java39
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java97
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt49
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java73
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt67
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java73
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java69
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt146
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt39
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt87
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaResumeListenerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt109
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt85
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt62
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt169
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java119
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java7
-rw-r--r--services/core/Android.bp1
-rw-r--r--services/core/java/com/android/server/DynamicSystemService.java11
-rw-r--r--services/core/java/com/android/server/EntropyMixer.java255
-rw-r--r--services/core/java/com/android/server/RandomBlock.java101
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java6
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java14
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java68
-rw-r--r--services/core/java/com/android/server/am/AnrHelper.java5
-rw-r--r--services/core/java/com/android/server/am/AppBatteryExemptionTracker.java6
-rw-r--r--services/core/java/com/android/server/am/AppBatteryTracker.java184
-rw-r--r--services/core/java/com/android/server/am/AppBindServiceEventsTracker.java6
-rw-r--r--services/core/java/com/android/server/am/AppBroadcastEventsTracker.java6
-rw-r--r--services/core/java/com/android/server/am/AppFGSTracker.java30
-rw-r--r--services/core/java/com/android/server/am/AppMediaSessionTracker.java6
-rw-r--r--services/core/java/com/android/server/am/AppPermissionTracker.java6
-rw-r--r--services/core/java/com/android/server/am/AppRestrictionController.java711
-rw-r--r--services/core/java/com/android/server/am/BaseAppStateTracker.java8
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java7
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java9
-rw-r--r--services/core/java/com/android/server/app/GameManagerService.java69
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java6
-rw-r--r--services/core/java/com/android/server/audio/AudioEventLogger.java36
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java50
-rw-r--r--services/core/java/com/android/server/audio/SpatializerHelper.java155
-rw-r--r--services/core/java/com/android/server/biometrics/AuthSession.java10
-rw-r--r--services/core/java/com/android/server/biometrics/log/BiometricLogger.java20
-rw-r--r--services/core/java/com/android/server/biometrics/log/CallbackWithProbe.java2
-rw-r--r--services/core/java/com/android/server/biometrics/log/Probe.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/LockoutCache.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/LockoutTracker.java7
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java17
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java17
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java6
-rw-r--r--services/core/java/com/android/server/display/BrightnessMappingStrategy.java122
-rw-r--r--services/core/java/com/android/server/display/DensityMapping.java (renamed from services/core/java/com/android/server/display/DensityMap.java)35
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java28
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java18
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java34
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java6
-rw-r--r--services/core/java/com/android/server/hdmi/AbsoluteVolumeAudioStatusAction.java103
-rw-r--r--services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java67
-rw-r--r--services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapperInterface.java61
-rw-r--r--services/core/java/com/android/server/hdmi/AudioStatus.java67
-rw-r--r--services/core/java/com/android/server/hdmi/Constants.java3
-rwxr-xr-xservices/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java66
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java1
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java23
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecMessage.java2
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecNetwork.java7
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java434
-rw-r--r--services/core/java/com/android/server/hdmi/SendKeyAction.java15
-rw-r--r--services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java7
-rw-r--r--services/core/java/com/android/server/hdmi/SystemAudioAction.java7
-rw-r--r--services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java4
-rw-r--r--services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java112
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java90
-rw-r--r--services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java16
-rw-r--r--services/core/java/com/android/server/locales/LocaleManagerService.java20
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java17
-rw-r--r--services/core/java/com/android/server/location/injector/SettingsHelper.java14
-rw-r--r--services/core/java/com/android/server/location/injector/SystemSettingsHelper.java30
-rw-r--r--services/core/java/com/android/server/location/provider/LocationProviderManager.java17
-rw-r--r--services/core/java/com/android/server/logcat/LogcatManagerService.java11
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java2
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java31
-rw-r--r--services/core/java/com/android/server/pm/AppDataHelper.java56
-rw-r--r--services/core/java/com/android/server/pm/AppsFilter.java (renamed from services/core/java/com/android/server/pm/AppsFilterImpl.java)876
-rw-r--r--services/core/java/com/android/server/pm/AppsFilterSnapshot.java86
-rw-r--r--services/core/java/com/android/server/pm/BroadcastHelper.java12
-rw-r--r--services/core/java/com/android/server/pm/Computer.java3
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java13
-rw-r--r--services/core/java/com/android/server/pm/DexOptHelper.java26
-rw-r--r--services/core/java/com/android/server/pm/InitAppsHelper.java4
-rw-r--r--services/core/java/com/android/server/pm/IntentResolverInterceptor.java64
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceInjector.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java2
-rw-r--r--services/core/java/com/android/server/pm/Settings.java4
-rw-r--r--services/core/java/com/android/server/pm/SharedUidMigration.java2
-rw-r--r--services/core/java/com/android/server/pm/StorageEventHelper.java13
-rw-r--r--services/core/java/com/android/server/pm/dex/ArtManagerService.java40
-rw-r--r--services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java13
-rw-r--r--services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java10
-rw-r--r--services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java223
-rw-r--r--services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw3Compat.java20
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java4
-rw-r--r--services/core/java/com/android/server/telecom/OWNERS7
-rw-r--r--services/core/java/com/android/server/utils/WatchedArrayList.java7
-rw-r--r--services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java20
-rw-r--r--services/core/java/com/android/server/utils/WatchedSparseSetArray.java177
-rw-r--r--services/core/java/com/android/server/vcn/VcnGatewayConnection.java14
-rw-r--r--services/core/java/com/android/server/vibrator/AbstractVibratorStep.java10
-rw-r--r--services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java59
-rw-r--r--services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java103
-rw-r--r--services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java11
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java11
-rw-r--r--services/core/java/com/android/server/wm/AnimationAdapter.java4
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java2
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java20
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java10
-rw-r--r--services/core/java/com/android/server/wm/InputManagerCallback.java4
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java4
-rw-r--r--services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java118
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java7
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java4
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java29
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java31
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimationSpec.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java65
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java76
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp33
-rw-r--r--services/core/jni/gnss/Gnss.cpp10
-rw-r--r--services/core/jni/gnss/Gnss.h15
-rw-r--r--services/core/xsd/display-device-config/display-device-config.xsd4
-rw-r--r--services/core/xsd/display-device-config/schema/current.txt8
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java8
-rw-r--r--services/midi/java/com/android/server/midi/MidiService.java12
-rw-r--r--services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt7
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java125
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java57
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DensityMappingTest.java (renamed from services/tests/mockingservicestests/src/com/android/server/display/DensityMapTest.java)66
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java148
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java21
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java17
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt2
-rw-r--r--services/tests/servicestests/src/com/android/server/EntropyMixerTest.java106
-rw-r--r--services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java16
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java21
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeControlTest.java570
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/FakeAudioDeviceVolumeManagerWrapper.java72
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java56
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvcTest.java107
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvcTest.java110
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/TvToAudioSystemAvcTest.java66
-rw-r--r--services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java31
-rw-r--r--services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java51
-rw-r--r--services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java)215
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java98
-rw-r--r--services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java150
-rw-r--r--services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java313
-rw-r--r--services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java23
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/WatcherTest.java61
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java123
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java18
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java36
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java43
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java77
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java21
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java4
-rw-r--r--services/usb/java/com/android/server/usb/UsbPortManager.java6
-rw-r--r--services/usb/java/com/android/server/usb/UsbService.java7
-rw-r--r--services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java6
-rw-r--r--services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java4
-rw-r--r--services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java3
-rw-r--r--telecomm/OWNERS2
-rw-r--r--telecomm/java/android/telecom/Connection.java9
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java27
-rw-r--r--telecomm/java/com/android/internal/telecom/ITelecomService.aidl7
-rw-r--r--telephony/OWNERS5
-rw-r--r--telephony/java/android/service/euicc/OWNERS6
-rw-r--r--telephony/java/android/service/sms/OWNERS5
-rw-r--r--telephony/java/android/telephony/OWNERS5
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java138
-rw-r--r--telephony/java/android/telephony/cdma/OWNERS5
-rw-r--r--telephony/java/android/telephony/data/OWNERS7
-rw-r--r--telephony/java/android/telephony/emergency/OWNERS6
-rw-r--r--telephony/java/android/telephony/euicc/OWNERS8
-rw-r--r--telephony/java/android/telephony/gsm/OWNERS5
-rw-r--r--telephony/java/android/telephony/ims/OWNERS3
-rw-r--r--telephony/java/android/telephony/ims/aidl/OWNERS5
-rw-r--r--telephony/java/android/telephony/ims/compat/OWNERS5
-rw-r--r--telephony/java/android/telephony/ims/compat/feature/OWNERS5
-rw-r--r--telephony/java/android/telephony/ims/compat/stub/OWNERS5
-rw-r--r--telephony/java/android/telephony/ims/feature/OWNERS5
-rw-r--r--telephony/java/android/telephony/ims/stub/OWNERS5
-rw-r--r--telephony/java/android/telephony/mbms/OWNERS6
-rw-r--r--telephony/java/android/telephony/mbms/vendor/OWNERS5
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl9
-rw-r--r--test-legacy/Android.mk4
-rw-r--r--tests/FlickerTests/OWNERS2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt10
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTestShellTransit.kt)16
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt7
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest_ShellTransit.kt80
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest_ShellTransit.kt)26
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt53
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt16
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest_ShellTransit.kt82
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java6
-rw-r--r--tools/aapt2/Android.mk2
-rw-r--r--tools/aapt2/util/Files.cpp2
954 files changed, 21670 insertions, 8394 deletions
diff --git a/Android.bp b/Android.bp
index cd110deb8a17..8ac7de944fe7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -324,6 +324,7 @@ java_defaults {
"av-types-aidl-java",
"tv_tuner_resource_manager_aidl_interface-java",
"soundtrigger_middleware-aidl-java",
+ "modules-utils-build",
"modules-utils-preconditions",
"modules-utils-synchronous-result-receiver",
"modules-utils-os",
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index c4795f55fc8a..53a388913118 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -32,6 +32,8 @@ import android.annotation.SystemService;
import android.annotation.UserHandleAware;
import android.content.Context;
+import com.android.internal.util.FrameworkStatsLog;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
@@ -451,6 +453,62 @@ public class PowerExemptionManager {
@Retention(RetentionPolicy.SOURCE)
public @interface ReasonCode {}
+ private static final int EXEMPTION_REASON_SYSTEM_UID = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_UID;
+ private static final int EXEMPTION_REASON_ALLOWLISTED_PACKAGE = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ALLOWLISTED_PACKAGE;
+ private static final int EXEMPTION_REASON_COMPANION_DEVICE_MANAGER = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_COMPANION_DEVICE_MANAGER;
+ private static final int EXEMPTION_REASON_DEVICE_DEMO_MODE = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DEVICE_DEMO_MODE;
+ private static final int EXEMPTION_REASON_DEVICE_OWNER = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DEVICE_OWNER;
+ private static final int EXEMPTION_REASON_PROFILE_OWNER = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROFILE_OWNER;
+ private static final int EXEMPTION_REASON_PROC_STATE_PERSISTENT = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROC_STATE_PERSISTENT;
+ private static final int EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROC_STATE_PERSISTENT_UI;
+ private static final int EXEMPTION_REASON_OP_ACTIVATE_VPN = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_OP_ACTIVATE_VPN;
+ private static final int EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_OP_ACTIVATE_PLATFORM_VPN;
+ private static final int EXEMPTION_REASON_SYSTEM_MODULE = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_MODULE;
+ private static final int EXEMPTION_REASON_CARRIER_PRIVILEGED_APP = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_CARRIER_PRIVILEGED_APP;
+ private static final int EXEMPTION_REASON_SYSTEM_ALLOW_LISTED = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_ALLOW_LISTED;
+ private static final int EXEMPTION_REASON_ROLE_DIALER = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ROLE_DIALER;
+ private static final int EXEMPTION_REASON_ROLE_EMERGENCY = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ROLE_EMERGENCY;
+ private static final int EXEMPTION_REASON_DENIED = FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DENIED;
+ /**
+ * List of exemption reason codes used for statsd logging in AppBackgroundRestrictionsInfo atom.
+ * @hide
+ */
+ @IntDef(prefix = { "EXEMPTION_REASON_" }, value = {
+ EXEMPTION_REASON_SYSTEM_UID,
+ EXEMPTION_REASON_ALLOWLISTED_PACKAGE,
+ EXEMPTION_REASON_COMPANION_DEVICE_MANAGER,
+ EXEMPTION_REASON_DEVICE_DEMO_MODE,
+ EXEMPTION_REASON_DEVICE_OWNER,
+ EXEMPTION_REASON_PROFILE_OWNER,
+ EXEMPTION_REASON_PROC_STATE_PERSISTENT,
+ EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI,
+ EXEMPTION_REASON_OP_ACTIVATE_VPN,
+ EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN,
+ EXEMPTION_REASON_SYSTEM_MODULE,
+ EXEMPTION_REASON_CARRIER_PRIVILEGED_APP,
+ EXEMPTION_REASON_SYSTEM_ALLOW_LISTED,
+ EXEMPTION_REASON_ROLE_DIALER,
+ EXEMPTION_REASON_ROLE_EMERGENCY,
+ EXEMPTION_REASON_DENIED,
+ })
+ public @interface ExemptionReason {}
+
/**
* @hide
*/
@@ -618,6 +676,47 @@ public class PowerExemptionManager {
}
/**
+ * @hide
+ * @return the reason code mapped to statsd for the AppBackgroundRestrictionsInfo atom.
+ */
+ public static @ExemptionReason int getExemptionReasonForStatsd(@ReasonCode int reasonCode) {
+ switch (reasonCode) {
+ case REASON_SYSTEM_UID:
+ return EXEMPTION_REASON_SYSTEM_UID;
+ case REASON_ALLOWLISTED_PACKAGE:
+ return EXEMPTION_REASON_ALLOWLISTED_PACKAGE;
+ case REASON_COMPANION_DEVICE_MANAGER:
+ return EXEMPTION_REASON_COMPANION_DEVICE_MANAGER;
+ case REASON_DEVICE_DEMO_MODE:
+ return EXEMPTION_REASON_DEVICE_DEMO_MODE;
+ case REASON_DEVICE_OWNER:
+ return EXEMPTION_REASON_DEVICE_OWNER;
+ case REASON_PROFILE_OWNER:
+ return EXEMPTION_REASON_PROFILE_OWNER;
+ case REASON_PROC_STATE_PERSISTENT:
+ return EXEMPTION_REASON_PROC_STATE_PERSISTENT;
+ case REASON_PROC_STATE_PERSISTENT_UI:
+ return EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI;
+ case REASON_OP_ACTIVATE_VPN:
+ return EXEMPTION_REASON_OP_ACTIVATE_VPN;
+ case REASON_OP_ACTIVATE_PLATFORM_VPN:
+ return EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN;
+ case REASON_SYSTEM_MODULE:
+ return EXEMPTION_REASON_SYSTEM_MODULE;
+ case REASON_CARRIER_PRIVILEGED_APP:
+ return EXEMPTION_REASON_CARRIER_PRIVILEGED_APP;
+ case REASON_SYSTEM_ALLOW_LISTED:
+ return EXEMPTION_REASON_SYSTEM_ALLOW_LISTED;
+ case REASON_ROLE_DIALER:
+ return EXEMPTION_REASON_ROLE_DIALER;
+ case REASON_ROLE_EMERGENCY:
+ return EXEMPTION_REASON_ROLE_EMERGENCY;
+ default:
+ return EXEMPTION_REASON_DENIED;
+ }
+ }
+
+ /**
* Return string name of the integer reason code.
* @hide
* @param reasonCode
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 30fdb1e9ad4e..91fa3c4fdc95 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
@@ -1311,8 +1311,15 @@ public final class JobStatus {
if (mExpeditedQuotaApproved == state) {
return false;
}
+ final boolean wasReady = !state && isReady();
mExpeditedQuotaApproved = state;
updateExpeditedDependencies();
+ final boolean isReady = isReady();
+ if (wasReady && !isReady) {
+ mReasonReadyToUnready = JobParameters.STOP_REASON_QUOTA;
+ } else if (!wasReady && isReady) {
+ mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;
+ }
return true;
}
@@ -1326,8 +1333,15 @@ public final class JobStatus {
if (mExpeditedTareApproved == state) {
return false;
}
+ final boolean wasReady = !state && isReady();
mExpeditedTareApproved = state;
updateExpeditedDependencies();
+ final boolean isReady = isReady();
+ if (wasReady && !isReady) {
+ mReasonReadyToUnready = JobParameters.STOP_REASON_QUOTA;
+ } else if (!wasReady && isReady) {
+ mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;
+ }
return true;
}
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 fdcd2fc82ecc..c6ba1eac56c0 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
@@ -307,7 +307,7 @@ public final class QuotaController extends StateController {
private final SparseBooleanArray mTempAllowlistCache = new SparseBooleanArray();
/**
- * Mapping of UIDs to the when their temp allowlist grace period ends (in the elapsed
+ * Mapping of UIDs to when their temp allowlist grace period ends (in the elapsed
* realtime timebase).
*/
private final SparseLongArray mTempAllowlistGraceCache = new SparseLongArray();
@@ -606,7 +606,7 @@ public final class QuotaController extends StateController {
final boolean isWithinQuota = isWithinQuotaLocked(jobStatus);
final boolean isWithinEJQuota =
jobStatus.isRequestedExpeditedJob() && isWithinEJQuotaLocked(jobStatus);
- setConstraintSatisfied(jobStatus, nowElapsed, isWithinQuota || isWithinEJQuota);
+ setConstraintSatisfied(jobStatus, nowElapsed, isWithinQuota, isWithinEJQuota);
final boolean outOfEJQuota;
if (jobStatus.isRequestedExpeditedJob()) {
setExpeditedQuotaApproved(jobStatus, nowElapsed, isWithinEJQuota);
@@ -815,6 +815,19 @@ public final class QuotaController extends StateController {
jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
}
+ private boolean hasTempAllowlistExemptionLocked(int sourceUid, int standbyBucket,
+ long nowElapsed) {
+ if (standbyBucket == RESTRICTED_INDEX || standbyBucket == NEVER_INDEX) {
+ // Don't let RESTRICTED apps get free quota from the temp allowlist.
+ // TODO: consider granting the exemption to RESTRICTED apps if the temp allowlist allows
+ // them to start FGS
+ return false;
+ }
+ final long tempAllowlistGracePeriodEndElapsed = mTempAllowlistGraceCache.get(sourceUid);
+ return mTempAllowlistCache.get(sourceUid)
+ || nowElapsed < tempAllowlistGracePeriodEndElapsed;
+ }
+
/** @return true if the job is within expedited job quota. */
@GuardedBy("mLock")
public boolean isWithinEJQuotaLocked(@NonNull final JobStatus jobStatus) {
@@ -833,11 +846,8 @@ public final class QuotaController extends StateController {
}
final long nowElapsed = sElapsedRealtimeClock.millis();
- final long tempAllowlistGracePeriodEndElapsed =
- mTempAllowlistGraceCache.get(jobStatus.getSourceUid());
- final boolean hasTempAllowlistExemption = mTempAllowlistCache.get(jobStatus.getSourceUid())
- || nowElapsed < tempAllowlistGracePeriodEndElapsed;
- if (hasTempAllowlistExemption) {
+ if (hasTempAllowlistExemptionLocked(jobStatus.getSourceUid(),
+ jobStatus.getEffectiveStandbyBucket(), nowElapsed)) {
return true;
}
@@ -1627,13 +1637,13 @@ public final class QuotaController extends StateController {
// An app in the ACTIVE bucket may be out of quota while the job could be in quota
// for some reason. Therefore, avoid setting the real value here and check each job
// individually.
- if (setConstraintSatisfied(js, nowElapsed, isWithinEJQuota || realInQuota)) {
+ if (setConstraintSatisfied(js, nowElapsed, realInQuota, isWithinEJQuota)) {
changedJobs.add(js);
}
} else {
// This job is somehow exempted. Need to determine its own quota status.
if (setConstraintSatisfied(js, nowElapsed,
- isWithinEJQuota || isWithinQuotaLocked(js))) {
+ isWithinQuotaLocked(js), isWithinEJQuota)) {
changedJobs.add(js);
}
}
@@ -1676,7 +1686,7 @@ public final class QuotaController extends StateController {
isWithinEJQuota = false;
}
if (setConstraintSatisfied(jobStatus, mUpdateTimeElapsed,
- isWithinEJQuota || isWithinQuotaLocked(jobStatus))) {
+ isWithinQuotaLocked(jobStatus), isWithinEJQuota)) {
changedJobs.add(jobStatus);
}
if (setExpeditedQuotaApproved(jobStatus, mUpdateTimeElapsed, isWithinEJQuota)) {
@@ -1833,12 +1843,24 @@ public final class QuotaController extends StateController {
}
private boolean setConstraintSatisfied(@NonNull JobStatus jobStatus, long nowElapsed,
- boolean isWithinQuota) {
- if (!isWithinQuota && jobStatus.getWhenStandbyDeferred() == 0) {
+ boolean isWithinQuota, boolean isWithinEjQuota) {
+ final boolean isSatisfied;
+ if (jobStatus.startedAsExpeditedJob) {
+ // If the job started as an EJ, then we should only consider EJ quota for the constraint
+ // satisfaction.
+ isSatisfied = isWithinEjQuota;
+ } else if (mService.isCurrentlyRunningLocked(jobStatus)) {
+ // Job is running but didn't start as an EJ, so only the regular quota should be
+ // considered.
+ isSatisfied = isWithinQuota;
+ } else {
+ isSatisfied = isWithinEjQuota || isWithinQuota;
+ }
+ if (!isSatisfied && jobStatus.getWhenStandbyDeferred() == 0) {
// Mark that the job is being deferred due to buckets.
jobStatus.setWhenStandbyDeferred(nowElapsed);
}
- return jobStatus.setQuotaConstraintSatisfied(nowElapsed, isWithinQuota);
+ return jobStatus.setQuotaConstraintSatisfied(nowElapsed, isSatisfied);
}
/**
@@ -2115,10 +2137,8 @@ public final class QuotaController extends StateController {
final long nowElapsed = sElapsedRealtimeClock.millis();
final int standbyBucket = JobSchedulerService.standbyBucketForPackage(mPkg.packageName,
mPkg.userId, nowElapsed);
- final long tempAllowlistGracePeriodEndElapsed = mTempAllowlistGraceCache.get(mUid);
final boolean hasTempAllowlistExemption = !mRegularJobTimer
- && (mTempAllowlistCache.get(mUid)
- || nowElapsed < tempAllowlistGracePeriodEndElapsed);
+ && hasTempAllowlistExemptionLocked(mUid, standbyBucket, nowElapsed);
final long topAppGracePeriodEndElapsed = mTopAppGraceCache.get(mUid);
final boolean hasTopAppExemption = !mRegularJobTimer
&& (mTopAppCache.get(mUid) || nowElapsed < topAppGracePeriodEndElapsed);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java
index 223091a27ee1..a1a541f92b38 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java
@@ -528,7 +528,7 @@ public class TareController extends StateController {
@NonNull
private ActionBill getRunningBill(JobStatus jobStatus) {
// TODO: factor in network cost when available
- if (jobStatus.shouldTreatAsExpeditedJob()) {
+ if (jobStatus.shouldTreatAsExpeditedJob() || jobStatus.startedAsExpeditedJob) {
if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) {
return BILL_JOB_RUNNING_MAX_EXPEDITED;
} else {
@@ -636,10 +636,6 @@ public class TareController extends StateController {
return true;
}
if (mService.isCurrentlyRunningLocked(jobStatus)) {
- if (jobStatus.isRequestedExpeditedJob()) {
- return canAffordBillLocked(jobStatus, getRunningBill(jobStatus))
- || canAffordBillLocked(jobStatus, BILL_JOB_RUNNING_DEFAULT);
- }
return canAffordBillLocked(jobStatus, getRunningBill(jobStatus));
}
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index fde59ea1e5f3..c69e9013fee6 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -281,7 +281,7 @@ public class AppStandbyController
private static final long NETWORK_SCORER_CACHE_DURATION_MILLIS = 5000L;
// Cache the device provisioning package queried from resource config_deviceProvisioningPackage.
- // Note that there is no synchronization on this method which is okay since in the worst case
+ // Note that there is no synchronization on this variable which is okay since in the worst case
// scenario, they might be a few extra reads from resources.
private String mCachedDeviceProvisioningPackage = null;
@@ -394,7 +394,7 @@ public class AppStandbyController
private boolean mAllowRestrictedBucket;
private volatile boolean mAppIdleEnabled;
- private boolean mIsCharging;
+ private volatile boolean mIsCharging;
private boolean mSystemServicesReady = false;
// There was a system update, defaults need to be initialized after services are ready
private boolean mPendingInitializeDefaults;
@@ -721,12 +721,10 @@ public class AppStandbyController
@VisibleForTesting
void setChargingState(boolean isCharging) {
- synchronized (mAppIdleLock) {
- if (mIsCharging != isCharging) {
- if (DEBUG) Slog.d(TAG, "Setting mIsCharging to " + isCharging);
- mIsCharging = isCharging;
- postParoleStateChanged();
- }
+ if (mIsCharging != isCharging) {
+ if (DEBUG) Slog.d(TAG, "Setting mIsCharging to " + isCharging);
+ mIsCharging = isCharging;
+ postParoleStateChanged();
}
}
@@ -1340,16 +1338,12 @@ public class AppStandbyController
@Override
public boolean isAppIdleFiltered(String packageName, int appId, int userId,
long elapsedRealtime) {
- if (getAppMinBucket(packageName, appId, userId) < AppIdleHistory.IDLE_BUCKET_CUTOFF) {
+ if (!mAppIdleEnabled || mIsCharging) {
return false;
- } else {
- synchronized (mAppIdleLock) {
- if (!mAppIdleEnabled || mIsCharging) {
- return false;
- }
- }
- return isAppIdleUnfiltered(packageName, userId, elapsedRealtime);
}
+
+ return isAppIdleUnfiltered(packageName, userId, elapsedRealtime)
+ && getAppMinBucket(packageName, appId, userId) >= AppIdleHistory.IDLE_BUCKET_CUTOFF;
}
static boolean isUserUsage(int reason) {
@@ -1803,7 +1797,7 @@ public class AppStandbyController
}
}
- private boolean isActiveNetworkScorer(String packageName) {
+ private boolean isActiveNetworkScorer(@NonNull String packageName) {
// Validity of network scorer cache is limited to a few seconds. Fetch it again
// if longer since query.
// This is a temporary optimization until there's a callback mechanism for changes to network scorer.
@@ -1813,7 +1807,7 @@ public class AppStandbyController
mCachedNetworkScorer = mInjector.getActiveNetworkScorer();
mCachedNetworkScorerAtMillis = now;
}
- return packageName != null && packageName.equals(mCachedNetworkScorer);
+ return packageName.equals(mCachedNetworkScorer);
}
private void informListeners(String packageName, int userId, int bucket, int reason,
@@ -2322,8 +2316,8 @@ public class AppStandbyController
* Returns {@code true} if the supplied package is the wellbeing app. Otherwise,
* returns {@code false}.
*/
- boolean isWellbeingPackage(String packageName) {
- return mWellbeingApp != null && mWellbeingApp.equals(packageName);
+ boolean isWellbeingPackage(@NonNull String packageName) {
+ return packageName.equals(mWellbeingApp);
}
boolean hasExactAlarmPermission(String packageName, int uid) {
diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
index 115c1f23c521..7d804938dc38 100644
--- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
@@ -16,12 +16,20 @@
package com.android.commands.svc;
+import android.app.ActivityThread;
import android.content.Context;
import android.hardware.usb.IUsbManager;
import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.UsbPortStatus;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
+import java.util.function.Consumer;
+import java.util.concurrent.Executor;
+import java.util.List;
+
public class UsbCommand extends Svc.Command {
public UsbCommand() {
super("usb");
@@ -39,8 +47,9 @@ public class UsbCommand extends Svc.Command {
+ "usage: svc usb setFunctions [function]\n"
+ " Set the current usb function. If function is blank, sets to charging.\n"
+ " svc usb setScreenUnlockedFunctions [function]\n"
- + " Sets the functions which, if the device was charging, become current on"
- + "screen unlock. If function is blank, turn off this feature.\n"
+ + " Sets the functions which, if the device was charging,\n"
+ + " become current on screen unlock.\n"
+ + " If function is blank, turn off this feature.\n"
+ " svc usb getFunctions\n"
+ " Gets the list of currently enabled functions\n"
+ " possible values of [function] are any of 'mtp', 'ptp', 'rndis',\n"
@@ -59,14 +68,28 @@ public class UsbCommand extends Svc.Command {
+ " svc usb getUsbHalVersion\n"
+ " Gets current USB Hal Version\n"
+ " possible values of Hal version are any of 'unknown', 'V1_0', 'V1_1',\n"
- + " 'V1_2', 'V1_3'\n";
+ + " 'V1_2', 'V1_3'\n"
+ + " svc usb resetUsbPort [port number]\n"
+ + " Reset the specified connected usb port\n"
+ + " default: the first connected usb port\n";
}
@Override
public void run(String[] args) {
if (args.length >= 2) {
+ Looper.prepareMainLooper();
+ Context context = ActivityThread.systemMain().getSystemContext();
+ UsbManager usbManager = context.getSystemService(UsbManager.class);
IUsbManager usbMgr = IUsbManager.Stub.asInterface(ServiceManager.getService(
Context.USB_SERVICE));
+
+ Executor executor = context.getMainExecutor();
+ Consumer<Integer> consumer = new Consumer<Integer>(){
+ public void accept(Integer status){
+ System.out.println("Consumer status: " + status);
+ };
+ };
+
if ("setFunctions".equals(args[1])) {
try {
usbMgr.setCurrentFunctions(UsbManager.usbFunctionsFromString(
@@ -134,6 +157,49 @@ public class UsbCommand extends Svc.Command {
System.err.println("Error communicating with UsbManager: " + e);
}
return;
+ } else if ("resetUsbPort".equals(args[1])) {
+ try {
+ int portNum = args.length >= 3 ? Integer.parseInt(args[2]) : -1;
+ UsbPort port = null;
+ UsbPortStatus portStatus = null;
+ List<UsbPort> ports = usbManager.getPorts();
+ final int numPorts = ports.size();
+
+ if (numPorts > 0) {
+ if (portNum != -1 && portNum < numPorts) {
+ portStatus = ports.get(portNum).getStatus();
+ if (portStatus.isConnected()) {
+ port = ports.get(portNum);
+ System.err.println(
+ "Get the USB port: port" + portNum);
+ }
+ } else {
+ for (portNum = 0; portNum < numPorts; portNum++) {
+ UsbPortStatus status = ports.get(portNum).getStatus();
+ if (status.isConnected()) {
+ port = ports.get(portNum);
+ portStatus = status;
+ System.err.println(
+ "Use the default USB port: port" + portNum);
+ break;
+ }
+ }
+ }
+ if (port != null && portStatus.isConnected()) {
+ System.err.println(
+ "Reset the USB port: port" + portNum);
+ port.resetUsbPort(executor, consumer);
+ } else {
+ System.err.println(
+ "There is no available reset USB port");
+ }
+ } else {
+ System.err.println("No USB ports");
+ }
+ } catch (Exception e) {
+ System.err.println("Error communicating with UsbManager: " + e);
+ }
+ return;
}
}
System.err.println(longHelp());
diff --git a/core/api/current.txt b/core/api/current.txt
index 89b994189e92..16d83a4b76fd 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -390,6 +390,7 @@ package android {
field public static final int autoVerify = 16844014; // 0x10104ee
field public static final int autofillHints = 16844118; // 0x1010556
field public static final int autofilledHighlight = 16844136; // 0x1010568
+ field public static final int backdropColor;
field public static final int background = 16842964; // 0x10100d4
field public static final int backgroundDimAmount = 16842802; // 0x1010032
field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -1345,7 +1346,7 @@ package android {
field public static final int shouldDisableView = 16843246; // 0x10101ee
field public static final int shouldUseDefaultUnfoldTransition = 16844364; // 0x101064c
field public static final int showAsAction = 16843481; // 0x10102d9
- field public static final int showBackground;
+ field public static final int showBackdrop;
field public static final int showClockAndComplications;
field public static final int showDefault = 16843258; // 0x10101fa
field public static final int showDividers = 16843561; // 0x1010329
@@ -1651,7 +1652,6 @@ package android {
field public static final int useEmbeddedDex = 16844190; // 0x101059e
field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
field public static final int useLevel = 16843167; // 0x101019f
- field public static final int useTargetActivityForQuickAccess;
field public static final int userVisible = 16843409; // 0x1010291
field public static final int usesCleartextTraffic = 16844012; // 0x10104ec
field public static final int usesPermissionFlags = 16844356; // 0x1010644
@@ -4074,7 +4074,7 @@ package android.app {
method @Deprecated public void onTabUnselected(android.app.ActionBar.Tab, android.app.FragmentTransaction);
}
- @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
ctor public Activity();
method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
method public void closeContextMenu();
@@ -5018,7 +5018,7 @@ package android.app {
method public void onDateSet(android.widget.DatePicker, int, int, int);
}
- public class Dialog implements android.content.DialogInterface android.view.KeyEvent.Callback android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ public class Dialog implements android.content.DialogInterface android.view.KeyEvent.Callback android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
ctor public Dialog(@NonNull @UiContext android.content.Context);
ctor public Dialog(@NonNull @UiContext android.content.Context, @StyleRes int);
ctor protected Dialog(@NonNull @UiContext android.content.Context, boolean, @Nullable android.content.DialogInterface.OnCancelListener);
@@ -43458,7 +43458,7 @@ package android.telephony {
method public int getPhoneType();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState();
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState(boolean, boolean);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState(int);
method @Nullable public android.telephony.SignalStrength getSignalStrength();
method public int getSimCarrierId();
method @Nullable public CharSequence getSimCarrierIdName();
@@ -43513,10 +43513,10 @@ package android.telephony {
method @Deprecated public void listen(android.telephony.PhoneStateListener, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void rebootModem();
method public void registerTelephonyCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
- method public void registerTelephonyCallback(boolean, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
+ method public void registerTelephonyCallback(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback);
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(boolean, @NonNull android.telephony.NetworkScanRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyScanManager.NetworkScanCallback);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(int, @NonNull android.telephony.NetworkScanRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyScanManager.NetworkScanCallback);
method public void sendDialerSpecialCode(String);
method public String sendEnvelopeWithStatus(String);
method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
@@ -43626,6 +43626,9 @@ package android.telephony {
field public static final String EXTRA_STATE_RINGING;
field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.extra.SUBSCRIPTION_ID";
field public static final String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER";
+ field public static final int INCLUDE_LOCATION_DATA_COARSE = 1; // 0x1
+ field public static final int INCLUDE_LOCATION_DATA_FINE = 2; // 0x2
+ field public static final int INCLUDE_LOCATION_DATA_NONE = 0; // 0x0
field public static final String METADATA_HIDE_VOICEMAIL_SETTINGS_MENU = "android.telephony.HIDE_VOICEMAIL_SETTINGS_MENU";
field public static final int MULTISIM_ALLOWED = 0; // 0x0
field public static final int MULTISIM_NOT_SUPPORTED_BY_CARRIER = 2; // 0x2
@@ -49642,6 +49645,7 @@ package android.view {
method @CallSuper public void drawableHotspotChanged(float, float);
method @CallSuper protected void drawableStateChanged();
method public android.view.View findFocus();
+ method @Nullable public final android.window.OnBackInvokedDispatcher findOnBackInvokedDispatcher();
method public final <T extends android.view.View> T findViewById(@IdRes int);
method public final <T extends android.view.View> T findViewWithTag(Object);
method public void findViewsWithText(java.util.ArrayList<android.view.View>, CharSequence, int);
@@ -50819,6 +50823,7 @@ package android.view {
method public void childHasTransientStateChanged(@NonNull android.view.View, boolean);
method public void clearChildFocus(android.view.View);
method public void createContextMenu(android.view.ContextMenu);
+ method @Nullable public default android.window.OnBackInvokedDispatcher findOnBackInvokedDispatcherForChild(@NonNull android.view.View, @NonNull android.view.View);
method public android.view.View focusSearch(android.view.View, int);
method public void focusableViewAvailable(android.view.View);
method public boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
@@ -51082,6 +51087,7 @@ package android.view {
method public android.media.session.MediaController getMediaController();
method @ColorInt public abstract int getNavigationBarColor();
method @ColorInt public int getNavigationBarDividerColor();
+ method @NonNull public android.window.OnBackInvokedDispatcher getOnBackInvokedDispatcher();
method public android.transition.Transition getReenterTransition();
method public android.transition.Transition getReturnTransition();
method @Nullable public android.view.AttachedSurfaceControl getRootSurfaceControl();
@@ -51600,7 +51606,7 @@ package android.view {
field public String packageName;
field public boolean preferMinimalPostProcessing;
field public int preferredDisplayModeId;
- field @Deprecated public float preferredRefreshRate;
+ field public float preferredRefreshRate;
field public int rotationAnimation;
field public float screenBrightness;
field public int screenOrientation;
@@ -52275,7 +52281,8 @@ package android.view.animation {
method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
method public long computeDurationHint();
method protected void ensureInterpolator();
- method @ColorInt public int getBackgroundColor();
+ method @ColorInt public int getBackdropColor();
+ method @Deprecated @ColorInt public int getBackgroundColor();
method @Deprecated public boolean getDetachWallpaper();
method public long getDuration();
method public boolean getFillAfter();
@@ -52284,7 +52291,7 @@ package android.view.animation {
method public int getRepeatCount();
method public int getRepeatMode();
method protected float getScaleFactor();
- method public boolean getShowBackground();
+ method public boolean getShowBackdrop();
method public long getStartOffset();
method public long getStartTime();
method public boolean getTransformation(long, android.view.animation.Transformation);
@@ -52300,7 +52307,8 @@ package android.view.animation {
method public void restrictDuration(long);
method public void scaleCurrentDuration(float);
method public void setAnimationListener(android.view.animation.Animation.AnimationListener);
- method public void setBackgroundColor(@ColorInt int);
+ method public void setBackdropColor(@ColorInt int);
+ method @Deprecated public void setBackgroundColor(@ColorInt int);
method @Deprecated public void setDetachWallpaper(boolean);
method public void setDuration(long);
method public void setFillAfter(boolean);
@@ -52310,7 +52318,7 @@ package android.view.animation {
method public void setInterpolator(android.view.animation.Interpolator);
method public void setRepeatCount(int);
method public void setRepeatMode(int);
- method public void setShowBackground(boolean);
+ method public void setShowBackdrop(boolean);
method public void setStartOffset(long);
method public void setStartTime(long);
method public void setZAdjustment(int);
@@ -57974,7 +57982,7 @@ package android.widget.inline {
package android.window {
public interface OnBackInvokedCallback {
- method public default void onBackInvoked();
+ method public void onBackInvoked();
}
public interface OnBackInvokedDispatcher {
@@ -57984,10 +57992,6 @@ package android.window {
field public static final int PRIORITY_OVERLAY = 1000000; // 0xf4240
}
- public interface OnBackInvokedDispatcherOwner {
- method @NonNull public android.window.OnBackInvokedDispatcher getOnBackInvokedDispatcher();
- }
-
public interface SplashScreen {
method public void clearOnExitAnimationListener();
method public void setOnExitAnimationListener(@NonNull android.window.SplashScreen.OnExitAnimationListener);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 44a79c61e216..b9522163b5d0 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -11,7 +11,7 @@ package android {
package android.app {
- @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
method public final boolean addDumpable(@NonNull android.util.Dumpable);
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 3f8fc5600eb1..650de2e00c3b 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -469,7 +469,7 @@ package android.accounts {
package android.app {
- @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
method public void convertFromTranslucent();
method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions);
method @Deprecated public boolean isBackgroundVisibleBehind();
@@ -5365,7 +5365,7 @@ package android.hardware.usb {
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbData(boolean);
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbDataWhileDocked();
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USB) public android.hardware.usb.UsbPortStatus getStatus();
- method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int resetUsbPort();
+ method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbPort(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_INTERNAL = 1; // 0x1
field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_NOT_SUPPORTED = 2; // 0x2
@@ -5383,6 +5383,11 @@ package android.hardware.usb {
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER = 5; // 0x5
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_PORT_MISMATCH = 3; // 0x3
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS = 0; // 0x0
+ field public static final int RESET_USB_PORT_ERROR_INTERNAL = 1; // 0x1
+ field public static final int RESET_USB_PORT_ERROR_NOT_SUPPORTED = 2; // 0x2
+ field public static final int RESET_USB_PORT_ERROR_OTHER = 4; // 0x4
+ field public static final int RESET_USB_PORT_ERROR_PORT_MISMATCH = 3; // 0x3
+ field public static final int RESET_USB_PORT_SUCCESS = 0; // 0x0
}
public final class UsbPortStatus implements android.os.Parcelable {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 5bb6325d33db..cd5ed213e6a5 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -104,7 +104,7 @@ package android.animation {
package android.app {
- @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
method public final boolean addDumpable(@NonNull android.util.Dumpable);
method public void dumpInternal(@NonNull String, @Nullable java.io.FileDescriptor, @NonNull java.io.PrintWriter, @Nullable String[]);
method public void onMovedToDisplay(int, android.content.res.Configuration);
@@ -2404,7 +2404,6 @@ package android.service.quickaccesswallet {
method public void notifyWalletDismissed();
method public void removeWalletServiceEventListener(@NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
method public void selectWalletCard(@NonNull android.service.quickaccesswallet.SelectWalletCardRequest);
- method public boolean useTargetActivityForQuickAccess();
}
public static interface QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index dff3c076727d..acdab1b97599 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -148,7 +148,6 @@ import android.widget.Toast;
import android.widget.Toolbar;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
-import android.window.OnBackInvokedDispatcherOwner;
import android.window.SplashScreen;
import android.window.WindowOnBackInvokedDispatcher;
@@ -749,8 +748,7 @@ public class Activity extends ContextThemeWrapper
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback,
- ContentCaptureManager.ContentCaptureClient,
- OnBackInvokedDispatcherOwner {
+ ContentCaptureManager.ContentCaptureClient {
private static final String TAG = "Activity";
private static final boolean DEBUG_LIFECYCLE = false;
@@ -1663,12 +1661,7 @@ public class Activity extends ContextThemeWrapper
.isOnBackInvokedCallbackEnabled(this);
if (aheadOfTimeBack) {
// Add onBackPressed as default back behavior.
- mDefaultBackCallback = new OnBackInvokedCallback() {
- @Override
- public void onBackInvoked() {
- navigateBack();
- }
- };
+ mDefaultBackCallback = this::navigateBack;
getOnBackInvokedDispatcher().registerSystemOnBackInvokedCallback(mDefaultBackCallback);
}
}
@@ -8998,12 +8991,11 @@ public class Activity extends ContextThemeWrapper
* @throws IllegalStateException if this Activity is not visual.
*/
@NonNull
- @Override
public OnBackInvokedDispatcher getOnBackInvokedDispatcher() {
if (mWindow == null) {
throw new IllegalStateException("OnBackInvokedDispatcher are not available on "
+ "non-visual activities");
}
- return ((OnBackInvokedDispatcherOwner) mWindow).getOnBackInvokedDispatcher();
+ return mWindow.getOnBackInvokedDispatcher();
}
}
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 95ac799e53d1..9c391abe6204 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -562,14 +562,15 @@ public abstract class ActivityManagerInternal {
public abstract void unregisterProcessObserver(IProcessObserver processObserver);
/**
- * Checks if there is an unfinished instrumentation that targets the given uid.
+ * Gets the uid of the instrumentation source if there is an unfinished instrumentation that
+ * targets the given uid.
*
* @param uid The uid to be checked for
*
- * @return True, if there is an instrumentation whose target application uid matches the given
- * uid, false otherwise
+ * @return the uid of the instrumentation source, if there is an instrumentation whose target
+ * application uid matches the given uid, and {@link android.os.Process#INVALID_UID} otherwise.
*/
- public abstract boolean isUidCurrentlyInstrumented(int uid);
+ public abstract int getInstrumentationSourceUid(int uid);
/** Is this a device owner app? */
public abstract boolean isDeviceOwner(int uid);
@@ -791,10 +792,11 @@ public abstract class ActivityManagerInternal {
*
* @param packageName The package name of the process.
* @param uid The UID of the process.
- * @param foregroundId The current foreground service notification ID, a negative value
- * means this notification is being removed.
+ * @param foregroundId The current foreground service notification ID.
+ * @param canceling The given notification is being canceled.
*/
- void onForegroundServiceNotificationUpdated(String packageName, int uid, int foregroundId);
+ void onForegroundServiceNotificationUpdated(String packageName, int uid, int foregroundId,
+ boolean canceling);
}
/**
@@ -842,4 +844,15 @@ public abstract class ActivityManagerInternal {
* Returns some summary statistics of the current PendingIntent queue - sizes and counts.
*/
public abstract List<PendingIntentStats> getPendingIntentStats();
+
+ /**
+ * Register the UidObserver for NetworkPolicyManager service.
+ *
+ * This is equivalent to calling
+ * {@link IActivityManager#registerUidObserver(IUidObserver, int, int, String)} but having a
+ * separate method for NetworkPolicyManager service so that it's UidObserver can be called
+ * separately outside the usual UidObserver flow.
+ */
+ public abstract void registerNetworkPolicyUidObserver(@NonNull IUidObserver observer,
+ int which, int cutpoint, @NonNull String callingPackage);
}
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 72c7fe4c5b40..f0af9bad2864 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -62,7 +62,6 @@ import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
-import android.window.OnBackInvokedDispatcherOwner;
import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.R;
@@ -98,8 +97,7 @@ import java.lang.ref.WeakReference;
* </div>
*/
public class Dialog implements DialogInterface, Window.Callback,
- KeyEvent.Callback, OnCreateContextMenuListener, Window.OnWindowDismissedCallback,
- OnBackInvokedDispatcherOwner {
+ KeyEvent.Callback, OnCreateContextMenuListener, Window.OnWindowDismissedCallback {
private static final String TAG = "Dialog";
@UnsupportedAppUsage
private Activity mOwnerActivity;
@@ -459,12 +457,7 @@ public class Dialog implements DialogInterface, Window.Callback,
if (mContext != null
&& WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
// Add onBackPressed as default back behavior.
- mDefaultBackCallback = new OnBackInvokedCallback() {
- @Override
- public void onBackInvoked() {
- onBackPressed();
- }
- };
+ mDefaultBackCallback = this::onBackPressed;
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT, mDefaultBackCallback);
mDefaultBackCallback = null;
@@ -1474,8 +1467,7 @@ public class Dialog implements DialogInterface, Window.Callback,
* Returns null if the dialog is not attached to a window with a decor.
*/
@NonNull
- @Override
public OnBackInvokedDispatcher getOnBackInvokedDispatcher() {
- return ((OnBackInvokedDispatcherOwner) mWindow).getOnBackInvokedDispatcher();
+ return mWindow.getOnBackInvokedDispatcher();
}
}
diff --git a/core/java/android/app/GameManager.java b/core/java/android/app/GameManager.java
index a138fa1f6fd5..a5adaa4e0196 100644
--- a/core/java/android/app/GameManager.java
+++ b/core/java/android/app/GameManager.java
@@ -200,6 +200,21 @@ public final class GameManager {
}
/**
+ * Set up the automatic power boost if appropriate.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
+ public void notifyGraphicsEnvironmentSetup() {
+ try {
+ mService.notifyGraphicsEnvironmentSetup(
+ mContext.getPackageName(), mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Called by games to communicate the current state to the platform.
* @param gameState An object set to the current state.
*/
diff --git a/core/java/android/app/IGameManagerService.aidl b/core/java/android/app/IGameManagerService.aidl
index 7035ac078334..e60a74acdc1c 100644
--- a/core/java/android/app/IGameManagerService.aidl
+++ b/core/java/android/app/IGameManagerService.aidl
@@ -27,6 +27,7 @@ interface IGameManagerService {
void setGameMode(String packageName, int gameMode, int userId);
int[] getAvailableGameModes(String packageName);
boolean isAngleEnabled(String packageName, int userId);
+ void notifyGraphicsEnvironmentSetup(String packageName, int userId);
void setGameState(String packageName, in GameState gameState, int userId);
GameModeInfo getGameModeInfo(String packageName, int userId);
void setGameServiceProvider(String packageName);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 995a9f31b341..e9df50f1d987 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1058,10 +1058,11 @@ public class Instrumentation {
}
/**
- * Sends the key events corresponding to the text to the app being
- * instrumented.
- *
- * @param text The text to be sent.
+ * Sends the key events that result in the given text being typed into the currently focused
+ * window, and waits for it to be processed.
+ *
+ * @param text The text to be sent.
+ * @see #sendKeySync(KeyEvent)
*/
public void sendStringSync(String text) {
if (text == null) {
@@ -1084,11 +1085,12 @@ public class Instrumentation {
}
/**
- * Send a key event to the currently focused window/view and wait for it to
- * be processed. Finished at some point after the recipient has returned
- * from its event processing, though it may <em>not</em> have completely
- * finished reacting from the event -- for example, if it needs to update
- * its display as a result, it may still be in the process of doing that.
+ * Sends a key event to the currently focused window, and waits for it to be processed.
+ * <p>
+ * This method blocks until the recipient has finished handling the event. Note that the
+ * recipient may <em>not</em> have completely finished reacting from the event when this method
+ * returns. For example, it may still be in the process of updating its display or UI contents
+ * upon reacting to the injected event.
*
* @param event The event to send to the current focus.
*/
@@ -1116,34 +1118,42 @@ public class Instrumentation {
}
/**
- * Sends an up and down key event sync to the currently focused window.
+ * Sends up and down key events with the given key code to the currently focused window, and
+ * waits for it to be processed.
*
- * @param key The integer keycode for the event.
+ * @param keyCode The key code for the events to send.
+ * @see #sendKeySync(KeyEvent)
*/
- public void sendKeyDownUpSync(int key) {
- sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, key));
- sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, key));
+ public void sendKeyDownUpSync(int keyCode) {
+ sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
+ sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
}
/**
- * Higher-level method for sending both the down and up key events for a
- * particular character key code. Equivalent to creating both KeyEvent
- * objects by hand and calling {@link #sendKeySync}. The event appears
- * as if it came from keyboard 0, the built in one.
- *
+ * Sends up and down key events with the given key code to the currently focused window, and
+ * waits for it to be processed.
+ * <p>
+ * Equivalent to {@link #sendKeyDownUpSync(int)}.
+ *
* @param keyCode The key code of the character to send.
+ * @see #sendKeySync(KeyEvent)
*/
public void sendCharacterSync(int keyCode) {
- sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
- sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
+ sendKeyDownUpSync(keyCode);
}
-
+
/**
- * Dispatch a pointer event. Finished at some point after the recipient has
- * returned from its event processing, though it may <em>not</em> have
- * completely finished reacting from the event -- for example, if it needs
- * to update its display as a result, it may still be in the process of
- * doing that.
+ * Dispatches a pointer event into a window owned by the instrumented application, and waits for
+ * it to be processed.
+ * <p>
+ * If the motion event being injected is targeted at a window that is not owned by the
+ * instrumented application, the input injection will fail. See {@link #getUiAutomation()} for
+ * injecting events into all windows.
+ * <p>
+ * This method blocks until the recipient has finished handling the event. Note that the
+ * recipient may <em>not</em> have completely finished reacting from the event when this method
+ * returns. For example, it may still be in the process of updating its display or UI contents
+ * upon reacting to the injected event.
*
* @param event A motion event describing the pointer action. (As noted in
* {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
@@ -1154,28 +1164,55 @@ public class Instrumentation {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
+
+ syncInputTransactionsAndInjectEventIntoSelf(event);
+ }
+
+ private void syncInputTransactionsAndInjectEventIntoSelf(MotionEvent event) {
+ final boolean syncBefore = event.getAction() == MotionEvent.ACTION_DOWN
+ || event.isFromSource(InputDevice.SOURCE_MOUSE);
+ final boolean syncAfter = event.getAction() == MotionEvent.ACTION_UP;
+
try {
- WindowManagerGlobal.getWindowManagerService().injectInputAfterTransactionsApplied(event,
- InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH,
- true /* waitForAnimations */);
+ if (syncBefore) {
+ WindowManagerGlobal.getWindowManagerService()
+ .syncInputTransactions(true /*waitForAnimations*/);
+ }
+
+ // Direct the injected event into windows owned by the instrumentation target.
+ InputManager.getInstance().injectInputEvent(
+ event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT, Process.myUid());
+
+ if (syncAfter) {
+ WindowManagerGlobal.getWindowManagerService()
+ .syncInputTransactions(true /*waitForAnimations*/);
+ }
} catch (RemoteException e) {
+ e.rethrowFromSystemServer();
}
}
/**
- * Dispatch a trackball event. Finished at some point after the recipient has
- * returned from its event processing, though it may <em>not</em> have
- * completely finished reacting from the event -- for example, if it needs
- * to update its display as a result, it may still be in the process of
- * doing that.
- *
+ * Dispatches a trackball event into the currently focused window, and waits for it to be
+ * processed.
+ * <p>
+ * This method blocks until the recipient has finished handling the event. Note that the
+ * recipient may <em>not</em> have completely finished reacting from the event when this method
+ * returns. For example, it may still be in the process of updating its display or UI contents
+ * upon reacting to the injected event.
+ *
* @param event A motion event describing the trackball action. (As noted in
* {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
* {@link SystemClock#uptimeMillis()} as the timebase.
*/
public void sendTrackballEventSync(MotionEvent event) {
validateNotAppThread();
- if ((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
+ if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+ throw new IllegalArgumentException(
+ "Cannot inject pointer events from sendTrackballEventSync()."
+ + " Use sendPointerSync() to inject pointer events.");
+ }
+ if (!event.isFromSource(InputDevice.SOURCE_CLASS_TRACKBALL)) {
event.setSource(InputDevice.SOURCE_TRACKBALL);
}
InputManager.getInstance().injectInputEvent(event,
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index e016027329ac..5d6e2bda0b83 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -36,7 +36,10 @@ import android.os.UserHandle;
import android.permission.IPermissionManager;
import android.util.Log;
import android.view.IWindowManager;
+import android.view.InputDevice;
import android.view.InputEvent;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.WindowAnimationFrameStats;
import android.view.WindowContentFrameStats;
@@ -132,13 +135,36 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
throwIfShutdownLocked();
throwIfNotConnectedLocked();
}
- final int mode = (sync) ? InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
- : InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
+
+ final boolean syncTransactionsBefore;
+ final boolean syncTransactionsAfter;
+ if (event instanceof KeyEvent) {
+ KeyEvent keyEvent = (KeyEvent) event;
+ syncTransactionsBefore = keyEvent.getAction() == KeyEvent.ACTION_DOWN;
+ syncTransactionsAfter = keyEvent.getAction() == KeyEvent.ACTION_UP;
+ } else {
+ MotionEvent motionEvent = (MotionEvent) event;
+ syncTransactionsBefore = motionEvent.getAction() == MotionEvent.ACTION_DOWN
+ || motionEvent.isFromSource(InputDevice.SOURCE_MOUSE);
+ syncTransactionsAfter = motionEvent.getAction() == MotionEvent.ACTION_UP;
+ }
+
final long identity = Binder.clearCallingIdentity();
try {
- return mWindowManager.injectInputAfterTransactionsApplied(event, mode,
- waitForAnimations);
+ if (syncTransactionsBefore) {
+ mWindowManager.syncInputTransactions(waitForAnimations);
+ }
+
+ final boolean result = InputManager.getInstance().injectInputEvent(event,
+ sync ? InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
+ : InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+
+ if (syncTransactionsAfter) {
+ mWindowManager.syncInputTransactions(waitForAnimations);
+ }
+ return result;
} catch (RemoteException e) {
+ e.rethrowFromSystemServer();
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5dd68a9fcfc9..0d258ce6c0fc 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3054,13 +3054,11 @@ public abstract class Context {
*
* @param receiver The BroadcastReceiver to handle the broadcast.
* @param filter Selects the Intent broadcasts to be received.
- * @param flags Additional options for the receiver. For apps targeting
- * {@link android.os.Build.VERSION_CODES#TIRAMISU},
- * either {@link #RECEIVER_EXPORTED} or
- * {@link #RECEIVER_NOT_EXPORTED} must be specified if the receiver isn't being registered
- * for <a href="{@docRoot}guide/components/broadcasts#system-broadcasts">system
- * broadcasts</a> or an exception will be thrown. If
- * {@link #RECEIVER_EXPORTED} is specified, a receiver may additionally
+ * @param flags Additional options for the receiver. In a future release, either
+ * {@link #RECEIVER_EXPORTED} or {@link #RECEIVER_NOT_EXPORTED} must be specified if the
+ * receiver isn't being registered for <a href="{@docRoot}guide/components
+ * /broadcasts#system-broadcasts">system broadcasts</a> or an exception will be
+ * thrown. If {@link #RECEIVER_EXPORTED} is specified, a receiver may additionally
* specify {@link #RECEIVER_VISIBLE_TO_INSTANT_APPS}. For a complete list of
* system broadcast actions, see the BROADCAST_ACTIONS.TXT file in the
* Android SDK. If both {@link #RECEIVER_EXPORTED} and
@@ -3137,13 +3135,11 @@ public abstract class Context {
* no permission is required.
* @param scheduler Handler identifying the thread that will receive
* the Intent. If null, the main thread of the process will be used.
- * @param flags Additional options for the receiver. For apps targeting
- * {@link android.os.Build.VERSION_CODES#TIRAMISU},
- * either {@link #RECEIVER_EXPORTED} or
- * {@link #RECEIVER_NOT_EXPORTED} must be specified if the receiver isn't being registered
- * for <a href="{@docRoot}guide/components/broadcasts#system-broadcasts">system
- * broadcasts</a> or an exception will be thrown. If
- * {@link #RECEIVER_EXPORTED} is specified, a receiver may additionally
+ * @param flags Additional options for the receiver. In a future release, either
+ * {@link #RECEIVER_EXPORTED} or {@link #RECEIVER_NOT_EXPORTED} must be specified if the
+ * receiver isn't being registered for <a href="{@docRoot}guide/components
+ * /broadcasts#system-broadcasts">system broadcasts</a> or an exception will be
+ * thrown. If {@link #RECEIVER_EXPORTED} is specified, a receiver may additionally
* specify {@link #RECEIVER_VISIBLE_TO_INSTANT_APPS}. For a complete list of
* system broadcast actions, see the BROADCAST_ACTIONS.TXT file in the
* Android SDK. If both {@link #RECEIVER_EXPORTED} and
@@ -3207,13 +3203,11 @@ public abstract class Context {
* no permission is required.
* @param scheduler Handler identifying the thread that will receive
* the Intent. If {@code null}, the main thread of the process will be used.
- * @param flags Additional options for the receiver. For apps targeting
- * {@link android.os.Build.VERSION_CODES#TIRAMISU},
- * either {@link #RECEIVER_EXPORTED} or
- * {@link #RECEIVER_NOT_EXPORTED} must be specified if the receiver isn't being registered
- * for <a href="{@docRoot}guide/components/broadcasts#system-broadcasts">system
- * broadcasts</a> or an exception will be thrown. If
- * {@link #RECEIVER_EXPORTED} is specified, a receiver may additionally
+ * @param flags Additional options for the receiver. In a future release, either
+ * {@link #RECEIVER_EXPORTED} or {@link #RECEIVER_NOT_EXPORTED} must be specified if the
+ * receiver isn't being registered for <a href="{@docRoot}guide/components
+ * /broadcasts#system-broadcasts">system broadcasts</a> or an exception will be
+ * thrown. If {@link #RECEIVER_EXPORTED} is specified, a receiver may additionally
* specify {@link #RECEIVER_VISIBLE_TO_INSTANT_APPS}. For a complete list of
* system broadcast actions, see the BROADCAST_ACTIONS.TXT file in the
* Android SDK. If both {@link #RECEIVER_EXPORTED} and
@@ -3282,13 +3276,11 @@ public abstract class Context {
* no permission is required.
* @param scheduler Handler identifying the thread that will receive
* the Intent. If null, the main thread of the process will be used.
- * @param flags Additional options for the receiver. For apps targeting
- * {@link android.os.Build.VERSION_CODES#TIRAMISU},
- * either {@link #RECEIVER_EXPORTED} or
- * {@link #RECEIVER_NOT_EXPORTED} must be specified if the receiver isn't being registered
- * for <a href="{@docRoot}guide/components/broadcasts#system-broadcasts">system
- * broadcasts</a> or an exception will be thrown. If
- * {@link #RECEIVER_EXPORTED} is specified, a receiver may additionally
+ * @param flags Additional options for the receiver. In a future release, either
+ * {@link #RECEIVER_EXPORTED} or {@link #RECEIVER_NOT_EXPORTED} must be specified if the
+ * receiver isn't being registered for <a href="{@docRoot}guide/components
+ * /broadcasts#system-broadcasts">system broadcasts</a> or an exception will be
+ * thrown. If {@link #RECEIVER_EXPORTED} is specified, a receiver may additionally
* specify {@link #RECEIVER_VISIBLE_TO_INSTANT_APPS}. For a complete list of
* system broadcast actions, see the BROADCAST_ACTIONS.TXT file in the
* Android SDK. If both {@link #RECEIVER_EXPORTED} and
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 5680bcd2e2e6..cb55e303e778 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -568,7 +568,8 @@ public class ApkLiteParseUtils {
}
ParseResult<Integer> targetResult = FrameworkParsingPackageUtils.computeTargetSdkVersion(
- targetVer, targetCode, SDK_CODENAMES, input);
+ targetVer, targetCode, SDK_CODENAMES, input,
+ /* allowUnknownCodenames= */ false);
if (targetResult.isError()) {
return input.error(targetResult);
}
diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
index a65b6815f8ad..6d74b819301d 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -36,6 +36,7 @@ import android.util.Slog;
import android.util.apk.ApkSignatureVerifier;
import com.android.internal.util.ArrayUtils;
+import com.android.modules.utils.build.UnboundedSdkLevel;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
@@ -334,8 +335,9 @@ public class FrameworkParsingPackageUtils {
* If {@code targetCode} is not specified, e.g. the value is {@code null}, then the {@code
* targetVers} will be returned unmodified.
* <p>
- * Otherwise, the behavior varies based on whether the current platform is a pre-release
- * version, e.g. the {@code platformSdkCodenames} array has length > 0:
+ * When {@code allowUnknownCodenames} is false, the behavior varies based on whether the
+ * current platform is a pre-release version, e.g. the {@code platformSdkCodenames} array has
+ * length > 0:
* <ul>
* <li>If this is a pre-release platform and the value specified by
* {@code targetCode} is contained within the array of allowed pre-release
@@ -343,22 +345,32 @@ public class FrameworkParsingPackageUtils {
* <li>If this is a released platform, this method will return -1 to
* indicate that the package is not compatible with this platform.
* </ul>
+ * <p>
+ * When {@code allowUnknownCodenames} is true, any codename that is not known (presumed to be
+ * a codename announced after the build of the current device) is allowed and this method will
+ * return {@link Build.VERSION_CODES#CUR_DEVELOPMENT}.
*
- * @param targetVers targetSdkVersion number, if specified in the application
- * manifest, or 0 otherwise
- * @param targetCode targetSdkVersion code, if specified in the application manifest,
- * or {@code null} otherwise
- * @param platformSdkCodenames array of allowed pre-release SDK codenames for this platform
+ * @param targetVers targetSdkVersion number, if specified in the application
+ * manifest, or 0 otherwise
+ * @param targetCode targetSdkVersion code, if specified in the application manifest,
+ * or {@code null} otherwise
+ * @param platformSdkCodenames array of allowed pre-release SDK codenames for this platform
+ * @param allowUnknownCodenames allow unknown codenames, if true this method will accept unknown
+ * (presumed to be future) codenames
* @return the targetSdkVersion to use at runtime if successful
*/
public static ParseResult<Integer> computeTargetSdkVersion(@IntRange(from = 0) int targetVers,
@Nullable String targetCode, @NonNull String[] platformSdkCodenames,
- @NonNull ParseInput input) {
+ @NonNull ParseInput input, boolean allowUnknownCodenames) {
// If it's a release SDK, return the version number unmodified.
if (targetCode == null) {
return input.success(targetVers);
}
+ if (allowUnknownCodenames && UnboundedSdkLevel.isAtMost(targetCode)) {
+ return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
+ }
+
// If it's a pre-release SDK and the codename matches this platform, it
// definitely targets this SDK.
if (matchTargetCode(platformSdkCodenames, targetCode)) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 01bf49eb03a6..dd3ddafd4a09 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -751,11 +751,25 @@ public final class Configuration implements Parcelable, Comparable<Configuration
public static final int SCREEN_WIDTH_DP_UNDEFINED = 0;
/**
- * The current width of the available screen space, in dp units,
- * corresponding to
- * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenWidthQualifier">screen
- * width</a> resource qualifier. Set to
+ * The current width of the available screen space in dp units, excluding
+ * the area occupied by screen decorations at the edges of the display.
+ * Corresponds to the
+ * <a href="{@docRoot}guide/topics/resources/providing-resources.html#AvailableWidthHeightQualifier">
+ * available width</a> resource qualifier. Defaults to
* {@link #SCREEN_WIDTH_DP_UNDEFINED} if no width is specified.
+ *
+ * <p>In multi-window mode, equals the width of the available display area
+ * of the app window, not the available display area of the device screen
+ * (for example, when apps are displayed side by side in split-screen mode
+ * in landscape orientation).
+ *
+ * <p>Differs from {@link android.view.WindowMetrics} by not including
+ * screen decorations in the width measurement and by expressing the
+ * measurement in dp rather than px. Use {@code screenWidthDp} to obtain the
+ * horizontal display area available to the app, excluding the area occupied
+ * by screen decorations. Use {@link android.view.WindowMetrics#getBounds()}
+ * to obtain the width of the display area available to the app, including
+ * the area occupied by screen decorations.
*/
public int screenWidthDp;
@@ -766,11 +780,26 @@ public final class Configuration implements Parcelable, Comparable<Configuration
public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0;
/**
- * The current height of the available screen space, in dp units,
- * corresponding to
- * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenHeightQualifier">screen
- * height</a> resource qualifier. Set to
+ * The current height of the available screen space in dp units, excluding
+ * the area occupied by screen decorations at the edges of the display (such
+ * as the status bar, navigation bar, and cutouts). Corresponds to the
+ * <a href="{@docRoot}guide/topics/resources/providing-resources.html#AvailableWidthHeightQualifier">
+ * available height</a> resource qualifier. Defaults to
* {@link #SCREEN_HEIGHT_DP_UNDEFINED} if no height is specified.
+ *
+ * <p>In multi-window mode, equals the height of the available display area
+ * of the app window, not the available display area of the device screen
+ * (for example, when apps are displayed one above another in split-screen
+ * mode in portrait orientation).
+ *
+ * <p>Differs from {@link android.view.WindowMetrics} by not including
+ * screen decorations in the height measurement and by expressing the
+ * measurement in dp rather than px. Use {@code screenHeightDp} to obtain
+ * the vertical display area available to the app, excluding the area
+ * occupied by screen decorations. Use
+ * {@link android.view.WindowMetrics#getBounds()} to obtain the height of
+ * the display area available to the app, including the area occupied by
+ * screen decorations.
*/
public int screenHeightDp;
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 28046c56b9f8..99e4febe205d 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -268,4 +268,27 @@ public interface BiometricConstants {
*/
int BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL = 1;
+ /**
+ * No lockout.
+ * @hide
+ */
+ int BIOMETRIC_LOCKOUT_NONE = 0;
+ /**
+ * The biometric is in a temporary lockout state that will expire after some time.
+ * @hide
+ */
+ int BIOMETRIC_LOCKOUT_TIMED = 1;
+ /**
+ * The biometric is locked out until a reset occurs. Resets are typically triggered by
+ * successfully authenticating via a stronger method than the one that is locked out.
+ * @hide
+ */
+ int BIOMETRIC_LOCKOUT_PERMANENT = 2;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({BIOMETRIC_LOCKOUT_NONE, BIOMETRIC_LOCKOUT_TIMED, BIOMETRIC_LOCKOUT_PERMANENT})
+ @interface LockoutMode {}
}
diff --git a/core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java b/core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java
index 4ec6f0d2509e..de93234445ca 100644
--- a/core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java
+++ b/core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java
@@ -32,21 +32,33 @@ import android.provider.Settings;
*/
public class ParentalControlsUtilsInternal {
- private static final String TEST_ALWAYS_REQUIRE_CONSENT =
- "android.hardware.biometrics.ParentalControlsUtilsInternal.always_require_consent";
+ private static final String TEST_ALWAYS_REQUIRE_CONSENT_PACKAGE =
+ "android.hardware.biometrics.ParentalControlsUtilsInternal.require_consent_package";
+ private static final String TEST_ALWAYS_REQUIRE_CONSENT_CLASS =
+ "android.hardware.biometrics.ParentalControlsUtilsInternal.require_consent_class";
- public static boolean isTestModeEnabled(@NonNull Context context) {
+ /**
+ * ComponentName of Parent Consent activity for testing Biometric authentication disabled by
+ * Parental Controls.
+ *
+ * <p>Component could be defined by values of {@link #TEST_ALWAYS_REQUIRE_CONSENT_PACKAGE} and
+ * {@link #TEST_ALWAYS_REQUIRE_CONSENT_CLASS} Secure settings.
+ */
+ public static ComponentName getTestComponentName(@NonNull Context context, int userId) {
if (Build.IS_USERDEBUG || Build.IS_ENG) {
- return Settings.Secure.getInt(context.getContentResolver(),
- TEST_ALWAYS_REQUIRE_CONSENT, 0) != 0;
+ final String pkg = Settings.Secure.getStringForUser(context.getContentResolver(),
+ TEST_ALWAYS_REQUIRE_CONSENT_PACKAGE, userId);
+ final String cls = Settings.Secure.getStringForUser(context.getContentResolver(),
+ TEST_ALWAYS_REQUIRE_CONSENT_CLASS, userId);
+ return pkg != null && cls != null ? new ComponentName(pkg, cls) : null;
}
- return false;
+ return null;
}
public static boolean parentConsentRequired(@NonNull Context context,
@NonNull DevicePolicyManager dpm, @BiometricAuthenticator.Modality int modality,
@NonNull UserHandle userHandle) {
- if (isTestModeEnabled(context)) {
+ if (getTestComponentName(context, userHandle.getIdentifier()) != null) {
return true;
}
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index b97055976e3e..31f3b6aef251 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -19,6 +19,7 @@ package android.hardware.face;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -676,6 +677,22 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
* @hide
*/
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
+ @BiometricConstants.LockoutMode
+ public int getLockoutModeForUser(int sensorId, int userId) {
+ if (mService != null) {
+ try {
+ return mService.getLockoutModeForUser(sensorId, userId);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+ return BIOMETRIC_LOCKOUT_NONE;
+ }
+
+ /**
+ * @hide
+ */
+ @RequiresPermission(USE_BIOMETRIC_INTERNAL)
public void addLockoutResetCallback(final LockoutResetCallback callback) {
if (mService != null) {
try {
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 6d2cdf3cfadc..60c4b523094e 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -23,6 +23,7 @@ import static android.Manifest.permission.TEST_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.Manifest.permission.USE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON;
import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_AUTHENTICATE;
@@ -41,6 +42,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricTestSession;
@@ -1097,6 +1099,22 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
/**
* @hide
*/
+ @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+ @BiometricConstants.LockoutMode
+ public int getLockoutModeForUser(int sensorId, int userId) {
+ if (mService != null) {
+ try {
+ return mService.getLockoutModeForUser(sensorId, userId);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+ return BIOMETRIC_LOCKOUT_NONE;
+ }
+
+ /**
+ * @hide
+ */
public void addLockoutResetCallback(final LockoutResetCallback callback) {
if (mService != null) {
try {
diff --git a/core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl b/core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl
index f4d22dac3b72..9c2aa6699334 100644
--- a/core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl
+++ b/core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl
@@ -24,31 +24,20 @@ package android.hardware.fingerprint;
* @hide
*/
oneway interface IUdfpsHbmListener {
-
- /** HBM that applies to the whole screen. */
- const int GLOBAL_HBM = 0;
-
- /** HBM that only applies to a portion of the screen. */
- const int LOCAL_HBM = 1;
-
/**
* UdfpsController will call this method when the HBM is enabled.
*
- * @param hbmType The type of HBM that was enabled. See
- * {@link com.android.systemui.biometrics.UdfpsHbmTypes}.
* @param displayId The displayId for which the HBM is enabled. See
* {@link android.view.Display#getDisplayId()}.
*/
- void onHbmEnabled(int hbmType, int displayId);
+ void onHbmEnabled(int displayId);
/**
* UdfpsController will call this method when the HBM is disabled.
*
- * @param hbmType The type of HBM that was disabled. See
- * {@link com.android.systemui.biometrics.UdfpsHbmTypes}.
* @param displayId The displayId for which the HBM is disabled. See
* {@link android.view.Display#getDisplayId()}.
*/
- void onHbmDisabled(int hbmType, int displayId);
+ void onHbmDisabled(int displayId);
}
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index e1ffd4a6761d..57e84bdb686d 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -57,10 +57,11 @@ interface IInputManager {
// Temporarily changes the pointer speed.
void tryPointerSpeed(int speed);
- // Injects an input event into the system. To inject into windows owned by other
- // applications, the caller must have the INJECT_EVENTS permission.
+ // Injects an input event into the system. The caller must have the INJECT_EVENTS permission.
+ // The caller can target windows owned by a certain UID by providing a valid UID, or by
+ // providing {@link android.os.Process#INVALID_UID} to target all windows.
@UnsupportedAppUsage
- boolean injectInputEvent(in InputEvent ev, int mode);
+ boolean injectInputEvent(in InputEvent ev, int mode, int targetUid);
VerifiedInputEvent verifyInputEvent(in InputEvent ev);
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index c38a847dfb9f..0bcabddddf51 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -45,6 +45,7 @@ import android.os.IVibratorStateListener;
import android.os.InputEventInjectionSync;
import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
@@ -1107,14 +1108,18 @@ public final class InputManager {
}
}
-
/**
- * Injects an input event into the event system on behalf of an application.
+ * Injects an input event into the event system, targeting windows owned by the provided uid.
+ *
+ * If a valid targetUid is provided, the system will only consider injecting the input event
+ * into windows owned by the provided uid. If the input event is targeted at a window that is
+ * not owned by the provided uid, input injection will fail and a RemoteException will be
+ * thrown.
+ *
* The synchronization mode determines whether the method blocks while waiting for
* input injection to proceed.
* <p>
- * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into
- * windows that are owned by other applications.
+ * Requires the {@link android.Manifest.permission.INJECT_EVENTS} permission.
* </p><p>
* Make sure you correctly set the event time and input source of the event
* before calling this method.
@@ -1125,12 +1130,14 @@ public final class InputManager {
* {@link android.os.InputEventInjectionSync.NONE},
* {@link android.os.InputEventInjectionSync.WAIT_FOR_RESULT}, or
* {@link android.os.InputEventInjectionSync.WAIT_FOR_FINISHED}.
+ * @param targetUid The uid to target, or {@link android.os.Process#INVALID_UID} to target all
+ * windows.
* @return True if input event injection succeeded.
*
* @hide
*/
- @UnsupportedAppUsage
- public boolean injectInputEvent(InputEvent event, int mode) {
+ @RequiresPermission(Manifest.permission.INJECT_EVENTS)
+ public boolean injectInputEvent(InputEvent event, int mode, int targetUid) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
@@ -1141,13 +1148,39 @@ public final class InputManager {
}
try {
- return mIm.injectInputEvent(event, mode);
+ return mIm.injectInputEvent(event, mode, targetUid);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
/**
+ * Injects an input event into the event system on behalf of an application.
+ * The synchronization mode determines whether the method blocks while waiting for
+ * input injection to proceed.
+ * <p>
+ * Requires the {@link android.Manifest.permission.INJECT_EVENTS} permission.
+ * </p><p>
+ * Make sure you correctly set the event time and input source of the event
+ * before calling this method.
+ * </p>
+ *
+ * @param event The event to inject.
+ * @param mode The synchronization mode. One of:
+ * {@link android.os.InputEventInjectionSync.NONE},
+ * {@link android.os.InputEventInjectionSync.WAIT_FOR_RESULT}, or
+ * {@link android.os.InputEventInjectionSync.WAIT_FOR_FINISHED}.
+ * @return True if input event injection succeeded.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.INJECT_EVENTS)
+ @UnsupportedAppUsage
+ public boolean injectInputEvent(InputEvent event, int mode) {
+ return injectInputEvent(event, mode, Process.INVALID_UID);
+ }
+
+ /**
* Verify the details of an {@link android.view.InputEvent} that came from the system.
* If the event did not come from the system, or its details could not be verified, then this
* will return {@code null}. Receiving {@code null} does not mean that the event did not
@@ -1421,8 +1454,11 @@ public final class InputManager {
}
mInputDevices = new SparseArray<InputDevice>();
- for (int i = 0; i < ids.length; i++) {
- mInputDevices.put(ids[i], null);
+ // TODO(b/223905476): remove when the rootcause is fixed.
+ if (ids != null) {
+ for (int i = 0; i < ids.length; i++) {
+ mInputDevices.put(ids[i], null);
+ }
}
}
}
diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java
index 3f20002c8028..b37c27c2a9e7 100644
--- a/core/java/android/hardware/input/InputManagerInternal.java
+++ b/core/java/android/hardware/input/InputManagerInternal.java
@@ -21,7 +21,6 @@ import android.graphics.PointF;
import android.hardware.display.DisplayViewport;
import android.os.IBinder;
import android.view.InputChannel;
-import android.view.InputEvent;
import java.util.List;
@@ -31,14 +30,6 @@ import java.util.List;
* @hide Only for use within the system server.
*/
public abstract class InputManagerInternal {
- /**
- * Inject an input event.
- *
- * @param event The InputEvent to inject
- * @param mode Synchronous or asynchronous mode
- * @return True if injection has succeeded
- */
- public abstract boolean injectInputEvent(InputEvent event, int mode);
/**
* Called by the display manager to set information about the displays as needed
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index b617e056774b..5a442445d832 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -137,7 +137,7 @@ interface IUsbManager
void resetUsbGadget();
/* Resets the USB port. */
- boolean resetUsbPort(in String portId, int operationId, in IUsbOperationInternal callback);
+ void resetUsbPort(in String portId, int operationId, in IUsbOperationInternal callback);
/* Set USB data on or off */
boolean enableUsbData(in String portId, boolean enable, int operationId, in IUsbOperationInternal callback);
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 4fb6abdae5ff..2c38f7031eff 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -1360,11 +1360,11 @@ public class UsbManager {
* @hide
*/
@RequiresPermission(Manifest.permission.MANAGE_USB)
- boolean resetUsbPort(@NonNull UsbPort port, int operationId,
+ void resetUsbPort(@NonNull UsbPort port, int operationId,
IUsbOperationInternal callback) {
Objects.requireNonNull(port, "resetUsbPort: port must not be null. opId:" + operationId);
try {
- return mService.resetUsbPort(port.getId(), operationId, callback);
+ mService.resetUsbPort(port.getId(), operationId, callback);
} catch (RemoteException e) {
Log.e(TAG, "resetUsbPort: failed. ", e);
try {
diff --git a/core/java/android/hardware/usb/UsbOperationInternal.java b/core/java/android/hardware/usb/UsbOperationInternal.java
index 9bc2b3892a1e..5b6dbbfbe5d7 100644
--- a/core/java/android/hardware/usb/UsbOperationInternal.java
+++ b/core/java/android/hardware/usb/UsbOperationInternal.java
@@ -15,6 +15,7 @@
*/
package android.hardware.usb;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.hardware.usb.IUsbOperationInternal;
import android.hardware.usb.UsbPort;
@@ -24,7 +25,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
/**
* UsbOperationInternal allows UsbPort to support both synchronous and
* asynchronous function irrespective of whether the underlying hal
@@ -39,6 +42,10 @@ public final class UsbOperationInternal extends IUsbOperationInternal.Stub {
private final String mId;
// True implies operation did not timeout.
private boolean mOperationComplete;
+ private boolean mAsynchronous = false;
+ private Executor mExecutor;
+ private Consumer<Integer> mConsumer;
+ private int mResult = 0;
private @UsbOperationStatus int mStatus;
final ReentrantLock mLock = new ReentrantLock();
final Condition mOperationWait = mLock.newCondition();
@@ -78,6 +85,15 @@ public final class UsbOperationInternal extends IUsbOperationInternal.Stub {
@Retention(RetentionPolicy.SOURCE)
@interface UsbOperationStatus{}
+ UsbOperationInternal(int operationID, String id,
+ Executor executor, Consumer<Integer> consumer) {
+ this.mOperationID = operationID;
+ this.mId = id;
+ this.mExecutor = executor;
+ this.mConsumer = consumer;
+ this.mAsynchronous = true;
+ }
+
UsbOperationInternal(int operationID, String id) {
this.mOperationID = operationID;
this.mId = id;
@@ -94,7 +110,27 @@ public final class UsbOperationInternal extends IUsbOperationInternal.Stub {
mOperationComplete = true;
mStatus = status;
Log.i(TAG, "Port:" + mId + " opID:" + mOperationID + " status:" + mStatus);
- mOperationWait.signal();
+ if (mAsynchronous) {
+ switch (mStatus) {
+ case USB_OPERATION_SUCCESS:
+ mResult = UsbPort.RESET_USB_PORT_SUCCESS;
+ break;
+ case USB_OPERATION_ERROR_INTERNAL:
+ mResult = UsbPort.RESET_USB_PORT_ERROR_INTERNAL;
+ break;
+ case USB_OPERATION_ERROR_NOT_SUPPORTED:
+ mResult = UsbPort.RESET_USB_PORT_ERROR_NOT_SUPPORTED;
+ break;
+ case USB_OPERATION_ERROR_PORT_MISMATCH:
+ mResult = UsbPort.RESET_USB_PORT_ERROR_PORT_MISMATCH;
+ break;
+ default:
+ mResult = UsbPort.RESET_USB_PORT_ERROR_OTHER;
+ }
+ mExecutor.execute(() -> mConsumer.accept(mResult));
+ } else {
+ mOperationWait.signal();
+ }
} finally {
mLock.unlock();
}
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index 7b695e79018c..7c5a4c6d2b87 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -48,6 +48,7 @@ import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE;
import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_DEBUG;
import android.Manifest;
+import android.annotation.CallbackExecutor;
import android.annotation.CheckResult;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -65,6 +66,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* Represents a physical USB port and describes its characteristics.
@@ -128,9 +131,6 @@ public final class UsbPort {
@Retention(RetentionPolicy.SOURCE)
@interface EnableUsbDataStatus{}
- @Retention(RetentionPolicy.SOURCE)
- @interface ResetUsbPortStatus{}
-
/**
* The {@link #enableLimitPowerTransfer} request was successfully completed.
*/
@@ -197,6 +197,42 @@ public final class UsbPort {
*/
public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER = 5;
+ /**
+ * The {@link #resetUsbPort} request was successfully completed.
+ */
+ public static final int RESET_USB_PORT_SUCCESS = 0;
+
+ /**
+ * The {@link #resetUsbPort} request failed due to internal error.
+ */
+ public static final int RESET_USB_PORT_ERROR_INTERNAL = 1;
+
+ /**
+ * The {@link #resetUsbPort} request failed as it's not supported.
+ */
+ public static final int RESET_USB_PORT_ERROR_NOT_SUPPORTED = 2;
+
+ /**
+ * The {@link #resetUsbPort} request failed as port id mismatched.
+ */
+ public static final int RESET_USB_PORT_ERROR_PORT_MISMATCH = 3;
+
+ /**
+ * The {@link #resetUsbPort} request failed due to other reasons.
+ */
+ public static final int RESET_USB_PORT_ERROR_OTHER = 4;
+
+ /** @hide */
+ @IntDef(prefix = { "RESET_USB_PORT_" }, value = {
+ RESET_USB_PORT_SUCCESS,
+ RESET_USB_PORT_ERROR_INTERNAL,
+ RESET_USB_PORT_ERROR_NOT_SUPPORTED,
+ RESET_USB_PORT_ERROR_PORT_MISMATCH,
+ RESET_USB_PORT_ERROR_OTHER
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface ResetUsbPortStatus{}
+
/** @hide */
@IntDef(prefix = { "ENABLE_USB_DATA_WHILE_DOCKED_" }, value = {
ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS,
@@ -324,38 +360,29 @@ public final class UsbPort {
/**
* Reset Usb data on the port.
*
- * @return {@link #ENABLE_USB_DATA_SUCCESS} when request completes successfully or
- * {@link #ENABLE_USB_DATA_ERROR_INTERNAL} when request fails due to internal
- * error or
- * {@link ENABLE_USB_DATA_ERROR_NOT_SUPPORTED} when not supported or
- * {@link ENABLE_USB_DATA_ERROR_PORT_MISMATCH} when request fails due to port id
- * mismatch or
- * {@link ENABLE_USB_DATA_ERROR_OTHER} when fails due to other reasons.
+ * @param executor Executor for the callback.
+ * @param consumer A consumer that consumes the reset result.
+ * {@link #RESET_USB_PORT_SUCCESS} when request completes
+ * successfully or
+ * {@link #RESET_USB_PORT_ERROR_INTERNAL} when request
+ * fails due to internal error or
+ * {@link RESET_USB_PORT_ERROR_NOT_SUPPORTED} when not
+ * supported or
+ * {@link RESET_USB_PORT_ERROR_PORT_MISMATCH} when request
+ * fails due to port id mismatch or
+ * {@link RESET_USB_PORT_ERROR_OTHER} when fails due to
+ * other reasons.
*/
@CheckResult
@RequiresPermission(Manifest.permission.MANAGE_USB)
- public @ResetUsbPortStatus int resetUsbPort() {
+ public void resetUsbPort(@NonNull @CallbackExecutor Executor executor,
+ @NonNull @ResetUsbPortStatus Consumer<Integer> consumer) {
// UID is added To minimize operationID overlap between two different packages.
int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
- Log.i(TAG, "resetUsbData opId:" + operationId);
+ Log.i(TAG, "resetUsbPort opId:" + operationId);
UsbOperationInternal opCallback =
- new UsbOperationInternal(operationId, mId);
- if (mUsbManager.resetUsbPort(this, operationId, opCallback) == true) {
- opCallback.waitForOperationComplete();
- }
- int result = opCallback.getStatus();
- switch (result) {
- case USB_OPERATION_SUCCESS:
- return ENABLE_USB_DATA_SUCCESS;
- case USB_OPERATION_ERROR_INTERNAL:
- return ENABLE_USB_DATA_ERROR_INTERNAL;
- case USB_OPERATION_ERROR_NOT_SUPPORTED:
- return ENABLE_USB_DATA_ERROR_NOT_SUPPORTED;
- case USB_OPERATION_ERROR_PORT_MISMATCH:
- return ENABLE_USB_DATA_ERROR_PORT_MISMATCH;
- default:
- return ENABLE_USB_DATA_ERROR_OTHER;
- }
+ new UsbOperationInternal(operationId, mId, executor, consumer);
+ mUsbManager.resetUsbPort(this, operationId, opCallback);
}
/**
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 0c3514fce76e..c6cf09789899 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -157,6 +157,13 @@ public class GraphicsEnvironment {
}
}
Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
+
+ Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "notifyGraphicsEnvironmentSetup");
+ if (mGameManager != null
+ && appInfoWithMetaData.category == ApplicationInfo.CATEGORY_GAME) {
+ mGameManager.notifyGraphicsEnvironmentSetup();
+ }
+ Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
}
/**
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 82d4443ea724..aa283a2d019b 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -226,9 +226,10 @@ public class SystemProperties {
*/
@UnsupportedAppUsage
public static void set(@NonNull String key, @Nullable String val) {
- if (val != null && !key.startsWith("ro.") && val.length() > PROP_VALUE_MAX) {
+ if (val != null && !key.startsWith("ro.") && val.getBytes(StandardCharsets.UTF_8).length
+ > PROP_VALUE_MAX) {
throw new IllegalArgumentException("value of system property '" + key
- + "' is longer than " + PROP_VALUE_MAX + " characters: " + val);
+ + "' is longer than " + PROP_VALUE_MAX + " bytes: " + val);
}
if (TRACK_KEY_ACCESS) onKeyAccess(key);
native_set(key, val);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index c4cb3195e485..a64e63eacd56 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -300,6 +300,10 @@ public class UserManager {
* When it is set by any of these owners, it prevents all users from using
* Wi-Fi tethering. Other forms of tethering are not affected.
*
+ * This user restriction disables only Wi-Fi tethering.
+ * Use {@link #DISALLOW_CONFIG_TETHERING} to limit all forms of tethering.
+ * When {@link #DISALLOW_CONFIG_TETHERING} is set, this user restriction becomes obsolete.
+ *
* <p>The default value is <code>false</code>.
*
* <p>Key for user restrictions.
@@ -735,7 +739,7 @@ public class UserManager {
public static final String DISALLOW_CONFIG_DATE_TIME = "no_config_date_time";
/**
- * Specifies if a user is disallowed from configuring Tethering and portable hotspots
+ * Specifies if a user is disallowed from using and configuring Tethering and portable hotspots
* via Settings.
*
* <p>This restriction can only be set by a device owner, a profile owner on the primary
diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java
index e8e47857ecba..9610b16a312c 100644
--- a/core/java/android/os/image/DynamicSystemManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -16,13 +16,16 @@
package android.os.image;
+import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.gsi.AvbPublicKey;
import android.gsi.GsiProgress;
+import android.gsi.IGsiService;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.util.Pair;
/**
* The DynamicSystemManager offers a mechanism to use a new system image temporarily. After the
@@ -138,17 +141,18 @@ public class DynamicSystemManager {
* @param name The DSU partition name
* @param size Size of the DSU image in bytes
* @param readOnly True if the partition is read only, e.g. system.
- * @return {@code true} if the call succeeds. {@code false} either the device does not contain
- * enough space or a DynamicSystem is currently in use where the {@link #isInUse} would be
- * true.
+ * @return {@code Integer} an IGsiService.INSTALL_* status code. {@link Session} an installation
+ * session object if successful, otherwise {@code null}.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
- public Session createPartition(String name, long size, boolean readOnly) {
+ public @NonNull Pair<Integer, Session> createPartition(
+ String name, long size, boolean readOnly) {
try {
- if (mService.createPartition(name, size, readOnly)) {
- return new Session();
+ int status = mService.createPartition(name, size, readOnly);
+ if (status == IGsiService.INSTALL_OK) {
+ return new Pair<>(status, new Session());
} else {
- return null;
+ return new Pair<>(status, null);
}
} catch (RemoteException e) {
throw new RuntimeException(e.toString());
diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl
index 4e69952fac2f..755368a85c40 100644
--- a/core/java/android/os/image/IDynamicSystemService.aidl
+++ b/core/java/android/os/image/IDynamicSystemService.aidl
@@ -35,10 +35,10 @@ interface IDynamicSystemService
* @param name The DSU partition name
* @param size Size of the DSU image in bytes
* @param readOnly True if this partition is readOnly
- * @return true if the call succeeds
+ * @return IGsiService.INSTALL_* status code
*/
@EnforcePermission("MANAGE_DYNAMIC_SYSTEM")
- boolean createPartition(@utf8InCpp String name, long size, boolean readOnly);
+ int createPartition(@utf8InCpp String name, long size, boolean readOnly);
/**
* Complete the current partition installation.
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 47315047b6c4..d25e456270ae 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -915,7 +915,8 @@ public final class DeviceConfig {
* @param name The name of the property to create or update.
* @param value The value to store for the property.
* @param makeDefault Whether to make the new value the default one.
- * @return True if the value was set, false if the storage implementation throws errors.
+ * @return {@code true} if the value was set, {@code false} if the storage implementation throws
+ * errors.
* @hide
* @see #resetToDefaults(int, String).
*/
@@ -939,7 +940,7 @@ public final class DeviceConfig {
*
* @param properties the complete set of properties to set for a specific namespace.
* @throws BadConfigException if the provided properties are banned by RescueParty.
- * @return True if the values were set, false otherwise.
+ * @return {@code true} if the values were set, {@code false} otherwise.
* @hide
*/
@SystemApi
@@ -955,8 +956,8 @@ public final class DeviceConfig {
*
* @param namespace The namespace containing the property to delete.
* @param name The name of the property to delete.
- * @return True if the property was deleted or it did not exist in the first place.
- * False if the storage implementation throws errors.
+ * @return {@code true} if the property was deleted or it did not exist in the first place.
+ * Return {@code false} if the storage implementation throws errors.
* @hide
*/
@SystemApi
diff --git a/core/java/android/service/carrier/OWNERS b/core/java/android/service/carrier/OWNERS
index d768ef476206..447cd512da20 100644
--- a/core/java/android/service/carrier/OWNERS
+++ b/core/java/android/service/carrier/OWNERS
@@ -1,5 +1,3 @@
-# Bug component: 20868
+set noparent
-rgreenwalt@google.com
-tgunn@google.com
-fionaxu@google.com
+file:platform/frameworks/base:/telephony/OWNERS
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 001707d228b6..d4f8a3beb89b 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -1038,14 +1038,14 @@ public class DreamService extends Service implements Window.Callback {
}
mFinished = true;
+ mOverlayConnection.unbind(this);
+
if (mDreamToken == null) {
Slog.w(mTag, "Finish was called before the dream was attached.");
stopSelf();
return;
}
- mOverlayConnection.unbind(this);
-
try {
// finishSelf will unbind the dream controller from the dream service. This will
// trigger DreamService.this.onDestroy and DreamService.this will die.
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
index 091bf797e24b..faa5b2fe3488 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
@@ -240,15 +240,4 @@ public interface QuickAccessWalletClient extends Closeable {
*/
@Nullable
CharSequence getShortcutLongLabel();
-
- /**
- * Return whether the system should use the component specified by the
- * {@link android:targetActivity} or
- * {@link QuickAccessWalletService#getTargetActivityPendingIntent()}
- * as the "quick access" , invoked directly by the system.
- * If false, the system will use the built-in UI instead of the component specified
- * in {@link android:targetActivity} or
- * {@link QuickAccessWalletService#getTargetActivityPendingIntent()}.
- */
- boolean useTargetActivityForQuickAccess();
}
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
index a3304a9ca386..024660bde6fe 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
@@ -350,11 +350,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
return mServiceInfo == null ? null : mServiceInfo.getShortcutLongLabel(mContext);
}
- @Override
- public boolean useTargetActivityForQuickAccess() {
- return mServiceInfo.getUseTargetActivityForQuickAccess();
- }
-
private void connect() {
mHandler.post(this::connectInternal);
}
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
index 70ccd6fbd590..d004f34bc721 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
@@ -336,6 +336,14 @@ public abstract class QuickAccessWalletService extends Service {
mHandler.post(() -> sendWalletServiceEventInternal(serviceEvent));
}
+ /**
+ * Specify a {@link PendingIntent} to be launched as the "Quick Access" activity.
+ *
+ * This activity will be launched directly by the system in lieu of the card switcher activity
+ * provided by the system.
+ *
+ * In order to use the system-provided card switcher activity, return null from this method.
+ */
@Nullable
public PendingIntent getTargetActivityPendingIntent() {
return null;
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
index cf4be739e05a..0d290eee5777 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
@@ -144,23 +144,20 @@ class QuickAccessWalletServiceInfo {
private final CharSequence mShortcutShortLabel;
@Nullable
private final CharSequence mShortcutLongLabel;
- private final boolean mUseTargetActivityForQuickAccess;
private static ServiceMetadata empty() {
- return new ServiceMetadata(null, null, null, null, false);
+ return new ServiceMetadata(null, null, null, null);
}
private ServiceMetadata(
String targetActivity,
String settingsActivity,
CharSequence shortcutShortLabel,
- CharSequence shortcutLongLabel,
- boolean useTargetActivityForQuickAccess) {
+ CharSequence shortcutLongLabel) {
mTargetActivity = targetActivity;
mSettingsActivity = settingsActivity;
mShortcutShortLabel = shortcutShortLabel;
mShortcutLongLabel = shortcutLongLabel;
- mUseTargetActivityForQuickAccess = useTargetActivityForQuickAccess;
}
}
@@ -194,11 +191,8 @@ class QuickAccessWalletServiceInfo {
R.styleable.QuickAccessWalletService_shortcutShortLabel);
CharSequence shortcutLongLabel = afsAttributes.getText(
R.styleable.QuickAccessWalletService_shortcutLongLabel);
- boolean useTargetActivityForQuickAccess = afsAttributes.getBoolean(
- R.styleable.QuickAccessWalletService_useTargetActivityForQuickAccess,
- false);
return new ServiceMetadata(targetActivity, settingsActivity, shortcutShortLabel,
- shortcutLongLabel, useTargetActivityForQuickAccess);
+ shortcutLongLabel);
} finally {
if (afsAttributes != null) {
afsAttributes.recycle();
@@ -277,8 +271,4 @@ class QuickAccessWalletServiceInfo {
CharSequence getServiceLabel(Context context) {
return mServiceInfo.loadLabel(context.getPackageManager());
}
-
- boolean getUseTargetActivityForQuickAccess() {
- return mServiceMetadata.mUseTargetActivityForQuickAccess;
- }
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index dd0ac2e4e3a2..5131e4e58f54 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -1632,6 +1632,7 @@ public abstract class WallpaperService extends Service {
float finalXOffsetStep = xOffsetStep;
float finalXOffset = xOffset;
mHandler.post(() -> {
+ Trace.beginSection("WallpaperService#processLocalColors");
resetWindowPages();
int xPage = xCurrentPage;
EngineWindowPage current;
@@ -1662,6 +1663,7 @@ public abstract class WallpaperService extends Service {
}
current = mWindowPages[xPage];
updatePage(current, xPage, xPages, finalXOffsetStep);
+ Trace.endSection();
});
}
@@ -1734,6 +1736,7 @@ public abstract class WallpaperService extends Service {
private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages,
float xOffsetStep) {
if (page.getBitmap() == null) return;
+ Trace.beginSection("WallpaperService#updatePageColors");
if (DEBUG) {
Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas "
+ page.getAreas().size() + " and bitmap size of "
@@ -1779,6 +1782,7 @@ public abstract class WallpaperService extends Service {
}
}
}
+ Trace.endSection();
}
private RectF generateSubRect(RectF in, int pageInx, int numPages) {
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 28f5c2114b1d..7ac6ae186cc3 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -350,6 +350,53 @@ public class TextUtils {
return ret;
}
+
+ /**
+ * Returns the longest prefix of a string for which the UTF-8 encoding fits into the given
+ * number of bytes, with the additional guarantee that the string is not truncated in the middle
+ * of a valid surrogate pair.
+ *
+ * <p>Unpaired surrogates are counted as taking 3 bytes of storage. However, a subsequent
+ * attempt to actually encode a string containing unpaired surrogates is likely to be rejected
+ * by the UTF-8 implementation.
+ *
+ * (copied from google/thirdparty)
+ *
+ * @param str a string
+ * @param maxbytes the maximum number of UTF-8 encoded bytes
+ * @return the beginning of the string, so that it uses at most maxbytes bytes in UTF-8
+ * @throws IndexOutOfBoundsException if maxbytes is negative
+ *
+ * @hide
+ */
+ public static String truncateStringForUtf8Storage(String str, int maxbytes) {
+ if (maxbytes < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ int bytes = 0;
+ for (int i = 0, len = str.length(); i < len; i++) {
+ char c = str.charAt(i);
+ if (c < 0x80) {
+ bytes += 1;
+ } else if (c < 0x800) {
+ bytes += 2;
+ } else if (c < Character.MIN_SURROGATE
+ || c > Character.MAX_SURROGATE
+ || str.codePointAt(i) < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ bytes += 3;
+ } else {
+ bytes += 4;
+ i += (bytes > maxbytes) ? 0 : 1;
+ }
+ if (bytes > maxbytes) {
+ return str.substring(0, i);
+ }
+ }
+ return str;
+ }
+
+
/**
* Returns a string containing the tokens joined by delimiters.
*
diff --git a/core/java/android/util/SparseSetArray.java b/core/java/android/util/SparseSetArray.java
index eb53b425a228..f5025f7a9e99 100644
--- a/core/java/android/util/SparseSetArray.java
+++ b/core/java/android/util/SparseSetArray.java
@@ -21,26 +21,9 @@ package android.util;
* @hide
*/
public class SparseSetArray<T> {
- private final SparseArray<ArraySet<T>> mData;
+ private final SparseArray<ArraySet<T>> mData = new SparseArray<>();
public SparseSetArray() {
- mData = new SparseArray<>();
- }
-
- /**
- * Copy constructor
- */
- public SparseSetArray(SparseSetArray<T> src) {
- final int arraySize = src.size();
- mData = new SparseArray<>(arraySize);
- for (int i = 0; i < arraySize; i++) {
- final int key = src.keyAt(i);
- final ArraySet<T> set = src.get(key);
- final int setSize = set.size();
- for (int j = 0; j < setSize; j++) {
- add(key, set.valueAt(j));
- }
- }
}
/**
diff --git a/core/java/android/view/IDisplayWindowInsetsController.aidl b/core/java/android/view/IDisplayWindowInsetsController.aidl
index a0d4a6587bcf..f4a0dfaa4432 100644
--- a/core/java/android/view/IDisplayWindowInsetsController.aidl
+++ b/core/java/android/view/IDisplayWindowInsetsController.aidl
@@ -18,6 +18,7 @@ package android.view;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.view.InsetsVisibilities;
/**
* Singular controller of insets to use when there isn't another obvious controller available.
@@ -30,8 +31,9 @@ oneway interface IDisplayWindowInsetsController {
* Called when top focused window changes to determine whether or not to take over insets
* control. Won't be called if config_remoteInsetsControllerControlsSystemBars is false.
* @param packageName: Passes the top package name
+ * @param requestedVisibilities The insets visibilities requested by the focussed window.
*/
- void topFocusedWindowChanged(String packageName);
+ void topFocusedWindowChanged(String packageName, in InsetsVisibilities insetsVisibilities);
/**
* @see IWindow#insetsChanged
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index a35a195c50b1..5ce5477daa0f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -677,17 +677,6 @@ interface IWindowManager
void setDisplayImePolicy(int displayId, int imePolicy);
/**
- * Waits for transactions to get applied before injecting input, optionally waiting for
- * animations to complete. This includes waiting for the input windows to get sent to
- * InputManager.
- *
- * This is needed for testing since the system add windows and injects input
- * quick enough that the windows don't have time to get sent to InputManager.
- */
- boolean injectInputAfterTransactionsApplied(in InputEvent ev, int mode,
- boolean waitForAnimations);
-
- /**
* Waits until input information has been sent from WindowManager to native InputManager,
* optionally waiting for animations to complete.
*
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index a4841f6f0d95..7b6a0d64f980 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1310,8 +1310,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
private void cancelAnimation(InsetsAnimationControlRunner control, boolean invokeCallback) {
- if (DEBUG) Log.d(TAG, String.format("cancelAnimation of types: %d, animType: %d",
- control.getTypes(), control.getAnimationType()));
+ if (DEBUG) Log.d(TAG, String.format("cancelAnimation of types: %d, animType: %d, host: %s",
+ control.getTypes(), control.getAnimationType(), mHost.getRootViewTitle()));
if (invokeCallback) {
control.cancel();
}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 5500fb8c26a0..b1b630ed7353 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -432,6 +432,17 @@ public class InsetsState implements Parcelable {
processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
insets, Type.SYSTEM_GESTURES);
}
+ if (type == Type.CAPTION_BAR) {
+ // Caption should also be gesture and tappable elements. This should not be needed when
+ // the caption is added from the shell, as the shell can add other types at the same
+ // time.
+ processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+ insets, Type.SYSTEM_GESTURES);
+ processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+ insets, Type.MANDATORY_SYSTEM_GESTURES);
+ processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+ insets, Type.TAPPABLE_ELEMENT);
+ }
}
private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index da582c5b4b2f..b5bbc7537391 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -221,6 +221,8 @@ public final class SurfaceControl implements Parcelable {
@DataSpace.NamedDataSpace int dataSpace);
private static native void nativeSetDamageRegion(long transactionObj, long nativeObject,
Region region);
+ private static native void nativeSetDimmingEnabled(long transactionObj, long nativeObject,
+ boolean dimmingEnabled);
private static native void nativeOverrideHdrTypes(IBinder displayToken, int[] modes);
@@ -3838,6 +3840,27 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * Set if the layer can be dimmed.
+ *
+ * <p>Dimming is to adjust brightness of the layer.
+ * Default value is {@code true}, which means the layer can be dimmed.
+ * Disabling dimming means the brightness of the layer can not be changed, i.e.,
+ * keep the white point for the layer same as the display brightness.</p>
+ *
+ * @param sc The SurfaceControl on which to enable or disable dimming.
+ * @param dimmingEnabled The dimming flag.
+ * @return this.
+ *
+ * @hide
+ */
+ public @NonNull Transaction setDimmingEnabled(@NonNull SurfaceControl sc,
+ boolean dimmingEnabled) {
+ checkPreconditions(sc);
+ nativeSetDimmingEnabled(mNativeObject, sc.mNativeObject, dimmingEnabled);
+ return this;
+ }
+
+ /**
* Set the color space for the SurfaceControl. The supported color spaces are SRGB
* and Display P3, other color spaces will be treated as SRGB. This can only be used for
* SurfaceControls that were created as type {@link #FX_SURFACE_BLAST}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index c04b0964a7a4..ed57136b1d35 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -966,13 +966,16 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|| (mVisible && !mDrawFinished);
- final TransactionCallback transactionCallback =
- redrawNeeded ? new TransactionCallback() : null;
- if (redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInSync()) {
+ boolean shouldSyncBuffer =
+ redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInSync();
+ SyncBufferTransactionCallback syncBufferTransactionCallback = null;
+ if (shouldSyncBuffer) {
+ syncBufferTransactionCallback = new SyncBufferTransactionCallback();
mBlastBufferQueue.syncNextTransaction(
false /* acquireSingleBuffer */,
- transactionCallback::onTransactionReady);
+ syncBufferTransactionCallback::onTransactionReady);
}
+
final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
@@ -1011,7 +1014,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
if (redrawNeeded) {
- redrawNeeded(callbacks, transactionCallback);
+ if (DEBUG) {
+ Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
+ }
+ if (callbacks == null) {
+ callbacks = getSurfaceCallbacks();
+ }
+
+ if (shouldSyncBuffer) {
+ handleSyncBufferCallback(callbacks, syncBufferTransactionCallback);
+ } else {
+ redrawNeededAsync(callbacks, this::onDrawFinished);
+ }
}
}
} finally {
@@ -1030,38 +1044,30 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
- private void redrawNeeded(SurfaceHolder.Callback[] callbacks,
- @Nullable TransactionCallback transactionCallback) {
- if (DEBUG) {
- Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
- }
- final SurfaceHolder.Callback[] capturedCallbacks =
- callbacks == null ? getSurfaceCallbacks() : callbacks;
+ /**
+ * If SV is trying to be part of the VRI sync, we need to add SV to the VRI sync before
+ * invoking the redrawNeeded call to the owner. This is to ensure we can set up the SV in
+ * the sync before the SV owner knows it needs to draw a new frame.
+ * Once the redrawNeeded callback is invoked, we can stop the continuous sync transaction
+ * call which will invoke the syncTransaction callback that contains the buffer. The
+ * code waits until we can retrieve the transaction that contains the buffer before
+ * notifying the syncer that the buffer is ready.
+ */
+ private void handleSyncBufferCallback(SurfaceHolder.Callback[] callbacks,
+ SyncBufferTransactionCallback syncBufferTransactionCallback) {
- ViewRootImpl viewRoot = getViewRootImpl();
- boolean isVriSync = viewRoot.addToSync(syncBufferCallback ->
- redrawNeededAsync(capturedCallbacks, () -> {
+ getViewRootImpl().addToSync(syncBufferCallback ->
+ redrawNeededAsync(callbacks, () -> {
+ Transaction t = null;
if (mBlastBufferQueue != null) {
mBlastBufferQueue.stopContinuousSyncTransaction();
+ t = syncBufferTransactionCallback.waitForTransaction();
}
- Transaction t = null;
- if (transactionCallback != null && mBlastBufferQueue != null) {
- t = transactionCallback.waitForTransaction();
- }
- // If relayout was requested, then a callback from BBQ will
- // be invoked with the sync transaction. onDrawFinished will be
- // called in there
syncBufferCallback.onBufferReady(t);
onDrawFinished();
}));
- // If isVriSync, then everything was setup in the addToSync.
- if (isVriSync) {
- return;
- }
-
- redrawNeededAsync(capturedCallbacks, this::onDrawFinished);
}
private void redrawNeededAsync(SurfaceHolder.Callback[] callbacks,
@@ -1070,7 +1076,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
}
- private static class TransactionCallback {
+ private static class SyncBufferTransactionCallback {
private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
private Transaction mTransaction;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7d823b1c100d..d7940e2de98c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -162,6 +162,7 @@ import android.view.translation.ViewTranslationResponse;
import android.widget.Checkable;
import android.widget.FrameLayout;
import android.widget.ScrollBarDrawable;
+import android.window.OnBackInvokedDispatcher;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
@@ -12048,13 +12049,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Compute the view's coordinate within the surface.
+ * Gets the coordinates of this view in the coordinate space of the
+ * {@link Surface} that contains the view.
*
- * <p>Computes the coordinates of this view in its surface. The argument
- * must be an array of two integers. After the method returns, the array
- * contains the x and y location in that order.</p>
+ * <p>After the method returns, the argument array contains the x- and
+ * y-coordinates of the view relative to the view's left and top edges,
+ * respectively.
*
- * @param location an array of two integers in which to hold the coordinates
+ * @param location A two-element integer array in which the view coordinates
+ * are stored. The x-coordinate is at index 0; the y-coordinate, at
+ * index 1.
*/
public void getLocationInSurface(@NonNull @Size(2) int[] location) {
getLocationInWindow(location);
@@ -12098,6 +12102,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return null;
}
+
+ /**
+ * Walk up the View hierarchy to find the nearest {@link OnBackInvokedDispatcher}.
+ *
+ * @return The {@link OnBackInvokedDispatcher} from this or the nearest
+ * ancestor, or null if this view is both not attached and have no ancestor providing an
+ * {@link OnBackInvokedDispatcher}.
+ */
+ @Nullable
+ public final OnBackInvokedDispatcher findOnBackInvokedDispatcher() {
+ ViewParent parent = getParent();
+ if (parent != null) {
+ return parent.findOnBackInvokedDispatcherForChild(this, this);
+ }
+ return null;
+ }
+
/**
* @hide Compute the insets that should be consumed by this view and the ones
* that should propagate to those under it.
@@ -25553,11 +25574,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * <p>Computes the coordinates of this view on the screen. The argument
- * must be an array of two integers. After the method returns, the array
- * contains the x and y location in that order.</p>
+ * Gets the global coordinates of this view. The coordinates are in the
+ * coordinate space of the device screen, irrespective of system decorations
+ * and whether the system is in multi-window mode.
+ *
+ * <p>In multi-window mode, the global coordinate space encompasses the
+ * entire device screen, ignoring the bounds of the app window. For
+ * example, if the view is in the bottom portion of a horizontal split
+ * screen, the top edge of the screen&mdash;not the top edge of the
+ * window&mdash;is the origin from which the y-coordinate is calculated.
*
- * @param outLocation an array of two integers in which to hold the coordinates
+ * <p><b>Note:</b> In multiple-screen scenarios, the global coordinate space
+ * is restricted to the screen on which the view is displayed. The
+ * coordinate space does not span multiple screens.
+ *
+ * <p>After the method returns, the argument array contains the x- and
+ * y-coordinates of the view relative to the view's left and top edges,
+ * respectively.
+ *
+ * @param outLocation A two-element integer array in which the view
+ * coordinates are stored. The x-coordinate is at index 0; the
+ * y-coordinate, at index 1.
*/
public void getLocationOnScreen(@Size(2) int[] outLocation) {
getLocationInWindow(outLocation);
@@ -25570,11 +25607,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * <p>Computes the coordinates of this view in its window. The argument
- * must be an array of two integers. After the method returns, the array
- * contains the x and y location in that order.</p>
+ * Gets the coordinates of this view in the coordinate space of the window
+ * that contains the view, irrespective of system decorations.
+ *
+ * <p>In multi-window mode, the origin of the coordinate space is the
+ * top left corner of the window that contains the view. In full screen
+ * mode, the origin is the top left corner of the device screen.
+ *
+ * <p>After the method returns, the argument array contains the x- and
+ * y-coordinates of the view relative to the view's left and top edges,
+ * respectively.
*
- * @param outLocation an array of two integers in which to hold the coordinates
+ * @param outLocation A two-element integer array in which the view
+ * coordinates are stored. The x-coordinate is at index 0; the
+ * y-coordinate, at index 1.
*/
public void getLocationInWindow(@Size(2) int[] outLocation) {
if (outLocation == null || outLocation.length < 2) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index fe672327346a..9f0ad1169a8e 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -72,6 +72,7 @@ import android.view.inspector.InspectableProperty.EnumEntry;
import android.view.translation.TranslationCapability;
import android.view.translation.TranslationSpec.DataFormat;
import android.view.translation.ViewTranslationRequest;
+import android.window.OnBackInvokedDispatcher;
import com.android.internal.R;
@@ -9296,4 +9297,25 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
requests);
}
}
+
+ /**
+ * Walk up the View hierarchy to find the nearest {@link OnBackInvokedDispatcher}.
+ *
+ * @return The {@link OnBackInvokedDispatcher} from this or the nearest
+ * ancestor, or null if the view is both not attached and have no ancestor providing an
+ * {@link OnBackInvokedDispatcher}.
+ *
+ * @param child The direct child of this view for which to find a dispatcher.
+ * @param requester The requester that will use the dispatcher. Can be the same as child.
+ */
+ @Nullable
+ @Override
+ public OnBackInvokedDispatcher findOnBackInvokedDispatcherForChild(@NonNull View child,
+ @NonNull View requester) {
+ ViewParent parent = getParent();
+ if (parent != null) {
+ return parent.findOnBackInvokedDispatcherForChild(this, requester);
+ }
+ return null;
+ }
}
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 128da314e907..1020d2ef02be 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -22,6 +22,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle;
import android.view.accessibility.AccessibilityEvent;
+import android.window.OnBackInvokedDispatcher;
/**
* Defines the responsibilities for a class that will be a parent of a View.
@@ -697,4 +698,20 @@ public interface ViewParent {
getParent().onDescendantUnbufferedRequested();
}
}
+
+ /**
+ * Walk up the View hierarchy to find the nearest {@link OnBackInvokedDispatcher}.
+ *
+ * @return The {@link OnBackInvokedDispatcher} from this or the nearest
+ * ancestor, or null if the view is both not attached and have no ancestor providing an
+ * {@link OnBackInvokedDispatcher}.
+ *
+ * @param child The direct child of this view for which to find a dispatcher.
+ * @param requester The requester that will use the dispatcher. Can be the same as child.
+ */
+ @Nullable
+ default OnBackInvokedDispatcher findOnBackInvokedDispatcherForChild(@NonNull View child,
+ @NonNull View requester) {
+ return null;
+ }
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 931ae2748785..7b3fed74a9be 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -197,7 +197,6 @@ import android.widget.Scroller;
import android.window.ClientWindowFrames;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
-import android.window.OnBackInvokedDispatcherOwner;
import android.window.SurfaceSyncer;
import android.window.WindowOnBackInvokedDispatcher;
@@ -240,7 +239,7 @@ import java.util.concurrent.CountDownLatch;
@SuppressWarnings({"EmptyCatchBlock", "PointlessBooleanExpression"})
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks,
- AttachedSurfaceControl, OnBackInvokedDispatcherOwner {
+ AttachedSurfaceControl {
private static final String TAG = "ViewRootImpl";
private static final boolean DBG = false;
private static final boolean LOCAL_LOGV = false;
@@ -10736,6 +10735,13 @@ public final class ViewRootImpl implements ViewParent,
return mOnBackInvokedDispatcher;
}
+ @NonNull
+ @Override
+ public OnBackInvokedDispatcher findOnBackInvokedDispatcherForChild(
+ @NonNull View child, @NonNull View requester) {
+ return getOnBackInvokedDispatcher();
+ }
+
/**
* When this ViewRootImpl is added to the window manager, transfers the first
* {@link OnBackInvokedCallback} to be called to the server.
@@ -10743,7 +10749,7 @@ public final class ViewRootImpl implements ViewParent,
private void registerBackCallbackOnWindow() {
if (OnBackInvokedDispatcher.DEBUG) {
Log.d(OnBackInvokedDispatcher.TAG, TextUtils.formatSimple(
- "ViewRootImpl.registerBackCallbackOnWindow. Callback:%s Package:%s "
+ "ViewRootImpl.registerBackCallbackOnWindow. Dispatcher:%s Package:%s "
+ "IWindow:%s Session:%s",
mOnBackInvokedDispatcher, mBasePackageName, mWindow, mWindowSession));
}
@@ -10765,12 +10771,9 @@ public final class ViewRootImpl implements ViewParent,
}
private void registerCompatOnBackInvokedCallback() {
- mCompatOnBackInvokedCallback = new OnBackInvokedCallback() {
- @Override
- public void onBackInvoked() {
+ mCompatOnBackInvokedCallback = () -> {
sendBackKeyEvent(KeyEvent.ACTION_DOWN);
sendBackKeyEvent(KeyEvent.ACTION_UP);
- }
};
mOnBackInvokedDispatcher.registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCompatOnBackInvokedCallback);
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index 4387701f7a24..d960ba1489ca 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -125,10 +125,11 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
if (mApplier == null) {
mApplier = new SyncRtSurfaceTransactionApplier(mViewRoot.mView);
}
- if (mViewRoot.mView.isHardwareAccelerated()) {
+ if (mViewRoot.mView.isHardwareAccelerated() && isVisibleToUser()) {
mApplier.scheduleApply(params);
} else {
- // Window doesn't support hardware acceleration, no synchronization for now.
+ // Synchronization requires hardware acceleration for now.
+ // If the window isn't visible, drawing is paused and the applier won't run.
// TODO(b/149342281): use mViewRoot.mSurface.getNextFrameNumber() to sync on every
// frame instead.
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
@@ -269,4 +270,8 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
}
return null;
}
+
+ private boolean isVisibleToUser() {
+ return mViewRoot.getHostVisibility() == View.VISIBLE;
+ }
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 8401b7cdb243..555fd434e4d9 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -56,6 +56,7 @@ import android.transition.TransitionManager;
import android.util.Pair;
import android.view.View.OnApplyWindowInsetsListener;
import android.view.accessibility.AccessibilityEvent;
+import android.window.OnBackInvokedDispatcher;
import java.util.Collections;
import java.util.List;
@@ -2798,4 +2799,12 @@ public abstract class Window {
public @Nullable AttachedSurfaceControl getRootSurfaceControl() {
return null;
}
+
+ /**
+ * Returns the {@link OnBackInvokedDispatcher} instance associated with this window.
+ */
+ @NonNull
+ public OnBackInvokedDispatcher getOnBackInvokedDispatcher() {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 45169efd7d35..8e9f9d9fb4f3 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -3107,9 +3107,7 @@ public interface WindowManager extends ViewManager {
* This value is ignored if {@link #preferredDisplayModeId} is set.
*
* @see Display#getSupportedRefreshRates()
- * @deprecated use {@link #preferredDisplayModeId} instead
*/
- @Deprecated
public float preferredRefreshRate;
/**
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 464414d861fd..09306c791537 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -196,9 +196,9 @@ public abstract class Animation implements Cloneable {
private int mZAdjustment;
/**
- * Desired background color behind animation.
+ * The desired color of the backdrop to show behind the animation.
*/
- private int mBackgroundColor;
+ private int mBackdropColor;
/**
* scalefactor to apply to pivot points, etc. during animation. Subclasses retrieve the
@@ -211,10 +211,10 @@ public abstract class Animation implements Cloneable {
/**
* Whether to show a background behind the windows during the animation.
- * @see #getShowBackground()
- * @see #setShowBackground(boolean)
+ * @see #getShowBackdrop()
+ * @see #setShowBackdrop(boolean)
*/
- private boolean mShowBackground;
+ private boolean mShowBackdrop;
private boolean mMore = true;
private boolean mOneMoreTime = true;
@@ -265,7 +265,7 @@ public abstract class Animation implements Cloneable {
setZAdjustment(a.getInt(com.android.internal.R.styleable.Animation_zAdjustment, ZORDER_NORMAL));
- setBackgroundColor(a.getInt(com.android.internal.R.styleable.Animation_background, 0));
+ setBackdropColor(a.getInt(com.android.internal.R.styleable.Animation_backdropColor, 0));
setDetachWallpaper(
a.getBoolean(com.android.internal.R.styleable.Animation_detachWallpaper, false));
@@ -273,8 +273,8 @@ public abstract class Animation implements Cloneable {
a.getBoolean(com.android.internal.R.styleable.Animation_showWallpaper, false));
setHasRoundedCorners(
a.getBoolean(com.android.internal.R.styleable.Animation_hasRoundedCorners, false));
- setShowBackground(
- a.getBoolean(com.android.internal.R.styleable.Animation_showBackground, false));
+ setShowBackdrop(
+ a.getBoolean(com.android.internal.R.styleable.Animation_showBackdrop, false));
final int resID = a.getResourceId(com.android.internal.R.styleable.Animation_interpolator, 0);
@@ -646,9 +646,12 @@ public abstract class Animation implements Cloneable {
* @param bg The background color. If 0, no background. Currently must
* be black, with any desired alpha level.
*
+ * @deprecated None of window animations are running with background color.
+ * @see #setBackdropColor(int) for an alternative.
*/
+ @Deprecated
public void setBackgroundColor(@ColorInt int bg) {
- mBackgroundColor = bg;
+ // The background color is not needed any more, do nothing.
}
/**
@@ -705,21 +708,35 @@ public abstract class Animation implements Cloneable {
}
/**
- * If showBackground is {@code true} and this animation is applied on a window, then the windows
+ * If showBackdrop is {@code true} and this animation is applied on a window, then the windows
* in the animation will animate with the background associated with this window behind them.
*
- * The background comes from the {@link android.R.styleable#Theme_colorBackground} that is
- * applied to this window through its theme.
+ * If no backdrop color is explicitly set, the backdrop's color comes from the
+ * {@link android.R.styleable#Theme_colorBackground} that is applied to this window through its
+ * theme.
*
- * If multiple animating windows have showBackground set to {@code true} during an animation,
- * the top most window with showBackground set to {@code true} and a valid background color
+ * If multiple animating windows have showBackdrop set to {@code true} during an animation,
+ * the top most window with showBackdrop set to {@code true} and a valid background color
* takes precedence.
*
- * @param showBackground Whether to show a background behind the windows during the animation.
- * @attr ref android.R.styleable#Animation_showBackground
+ * @param showBackdrop Whether to show a background behind the windows during the animation.
+ * @attr ref android.R.styleable#Animation_showBackdrop
+ */
+ public void setShowBackdrop(boolean showBackdrop) {
+ mShowBackdrop = showBackdrop;
+ }
+
+ /**
+ * Set the color to use for the backdrop shown behind the animating windows.
+ *
+ * Will only show the backdrop if showBackdrop was set to true.
+ * See {@link #setShowBackdrop(boolean)}.
+ *
+ * @param backdropColor The backdrop color. If 0, the backdrop color will not apply.
+ * @attr ref android.R.styleable#Animation_backdropColor
*/
- public void setShowBackground(boolean showBackground) {
- mShowBackground = showBackground;
+ public void setBackdropColor(@ColorInt int backdropColor) {
+ mBackdropColor = backdropColor;
}
/**
@@ -822,10 +839,14 @@ public abstract class Animation implements Cloneable {
/**
* Returns the background color behind the animation.
+ *
+ * @deprecated None of window animations are running with background color.
+ * @see #getBackdropColor() for an alternative.
*/
+ @Deprecated
@ColorInt
public int getBackgroundColor() {
- return mBackgroundColor;
+ return 0;
}
/**
@@ -869,21 +890,36 @@ public abstract class Animation implements Cloneable {
}
/**
- * If showBackground is {@code true} and this animation is applied on a window, then the windows
+ * If showBackdrop is {@code true} and this animation is applied on a window, then the windows
* in the animation will animate with the background associated with this window behind them.
*
- * The background comes from the {@link android.R.styleable#Theme_colorBackground} that is
- * applied to this window through its theme.
+ * If no backdrop color is explicitly set, the backdrop's color comes from the
+ * {@link android.R.styleable#Theme_colorBackground} that is applied to this window
+ * through its theme.
*
- * If multiple animating windows have showBackground set to {@code true} during an animation,
- * the top most window with showBackground set to {@code true} and a valid background color
+ * If multiple animating windows have showBackdrop set to {@code true} during an animation,
+ * the top most window with showBackdrop set to {@code true} and a valid background color
* takes precedence.
*
- * @return if the background of this window should be shown behind the animating windows.
- * @attr ref android.R.styleable#Animation_showBackground
+ * @return if a backdrop should be shown behind the animating windows.
+ * @attr ref android.R.styleable#Animation_showBackdrop
+ */
+ public boolean getShowBackdrop() {
+ return mShowBackdrop;
+ }
+
+ /**
+ * Returns the background color to show behind the animating windows.
+ *
+ * Will only show the background if showBackdrop was set to true.
+ * See {@link #setShowBackdrop(boolean)}.
+ *
+ * @return The backdrop color. If 0, the backdrop color will not apply.
+ * @attr ref android.R.styleable#Animation_backdropColor
*/
- public boolean getShowBackground() {
- return mShowBackground;
+ @ColorInt
+ public int getBackdropColor() {
+ return mBackdropColor;
}
/**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index dbfcca9d632a..285a40779b90 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -240,12 +240,7 @@ public class Editor {
private final boolean mHapticTextHandleEnabled;
/** Handles OnBackInvokedCallback back dispatch */
- private final OnBackInvokedCallback mBackCallback = new OnBackInvokedCallback() {
- @Override
- public void onBackInvoked() {
- stopTextActionMode();
- }
- };
+ private final OnBackInvokedCallback mBackCallback = this::stopTextActionMode;
private boolean mBackCallbackRegistered;
@Nullable
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index f1dc5e7050fb..ab2d0056df6b 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -122,12 +122,7 @@ public class MediaController extends FrameLayout {
private final AccessibilityManager mAccessibilityManager;
private boolean mBackCallbackRegistered;
/** Handles back invocation */
- private final OnBackInvokedCallback mBackCallback = new OnBackInvokedCallback() {
- @Override
- public void onBackInvoked() {
- hide();
- }
- };
+ private final OnBackInvokedCallback mBackCallback = this::hide;
/** Handles decor view attach state change */
private final OnAttachStateChangeListener mAttachStateListener =
new OnAttachStateChangeListener() {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f9c964158e2e..54c0d7c9af32 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -12617,7 +12617,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (start >= 0 && start <= end && end <= text.length()) {
requestFocusOnNonEditableSelectableText();
Selection.setSelection((Spannable) text, start, end);
- hideAccessibilitySelectionControllers();
+ // Make sure selection mode is engaged.
+ if (mEditor != null) {
+ mEditor.startSelectionActionModeAsync(false);
+ }
return true;
}
}
@@ -13760,12 +13763,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Selection.removeSelection((Spannable) text);
}
// Hide all selection controllers used for adjusting selection
- // since we are doing so explicitly by other means and these
+ // since we are doing so explicitlty by other means and these
// controllers interact with how selection behaves.
- hideAccessibilitySelectionControllers();
- }
-
- private void hideAccessibilitySelectionControllers() {
if (mEditor != null) {
mEditor.hideCursorAndSpanControllers();
mEditor.stopTextActionMode();
diff --git a/core/java/android/window/ITaskFragmentOrganizerController.aidl b/core/java/android/window/ITaskFragmentOrganizerController.aidl
index 4399207fcc27..8407d10bc3ea 100644
--- a/core/java/android/window/ITaskFragmentOrganizerController.aidl
+++ b/core/java/android/window/ITaskFragmentOrganizerController.aidl
@@ -35,15 +35,15 @@ interface ITaskFragmentOrganizerController {
/**
* Registers remote animations per transition type for the organizer. It will override the
* animations if the transition only contains windows that belong to the organized
- * TaskFragments.
+ * TaskFragments in the given Task.
*/
- void registerRemoteAnimations(in ITaskFragmentOrganizer organizer,
+ void registerRemoteAnimations(in ITaskFragmentOrganizer organizer, int taskId,
in RemoteAnimationDefinition definition);
/**
* Unregisters remote animations per transition type for the organizer.
*/
- void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer);
+ void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer, int taskId);
/**
* Checks if an activity organized by a {@link android.window.TaskFragmentOrganizer} and
diff --git a/core/java/android/window/OnBackAnimationCallback.java b/core/java/android/window/OnBackAnimationCallback.java
new file mode 100644
index 000000000000..1a37e57df403
--- /dev/null
+++ b/core/java/android/window/OnBackAnimationCallback.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.annotation.NonNull;
+import android.app.Activity;
+import android.app.Dialog;
+import android.view.View;
+
+/**
+ * Interface for applications to register back animation callbacks along their custom back
+ * handling.
+ * <p>
+ * This allows the client to customize various back behaviors by overriding the corresponding
+ * callback methods.
+ * <p>
+ * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, held
+ * by classes that implement {@link OnBackInvokedDispatcherOwner} (such as {@link Activity},
+ * {@link Dialog} and {@link View}).
+ * <p>
+ * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
+ * they are added within the same priority. Between different priorities, callbacks with higher
+ * priority are invoked first.
+ * <p>
+ * @see OnBackInvokedCallback
+ * @hide
+ */
+public interface OnBackAnimationCallback extends OnBackInvokedCallback {
+ /**
+ * Called when a back gesture has been started, or back button has been pressed down.
+ */
+ default void onBackStarted() { }
+
+ /**
+ * Called on back gesture progress.
+ *
+ * @param backEvent An {@link BackEvent} object describing the progress event.
+ *
+ * @see BackEvent
+ */
+ default void onBackProgressed(@NonNull BackEvent backEvent) { }
+
+ /**
+ * Called when a back gesture or back button press has been cancelled.
+ */
+ default void onBackCancelled() { }
+}
diff --git a/core/java/android/window/OnBackInvokedCallback.java b/core/java/android/window/OnBackInvokedCallback.java
index 400a56f2c485..6e2d4f9edbc1 100644
--- a/core/java/android/window/OnBackInvokedCallback.java
+++ b/core/java/android/window/OnBackInvokedCallback.java
@@ -18,52 +18,31 @@ package android.window;
import android.app.Activity;
import android.app.Dialog;
-import android.view.View;
+import android.view.Window;
/**
- * Interface for applications to register back invocation callbacks. This allows the client
- * to customize various back behaviors by overriding the corresponding callback methods.
- *
- * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, held
- * by classes that implement {@link OnBackInvokedDispatcherOwner} (such as {@link Activity},
- * {@link Dialog} and {@link View}).
- *
- * Under the hood callbacks are registered at window level. When back is triggered,
- * callbacks on the in-focus window are invoked in reverse order in which they are added
- * within the same priority. Between different pirorities, callbacks with higher priority
- * are invoked first.
- *
- * See {@link OnBackInvokedDispatcher#registerOnBackInvokedCallback(int, OnBackInvokedCallback)}
- * for specifying callback priority.
+ * Callback allowing applications to handle back events in place of the system.
+ * <p>
+ * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, which
+ * is held at window level and accessible through {@link Activity#getOnBackInvokedDispatcher()},
+ * {@link Dialog#getOnBackInvokedDispatcher()} and {@link Window#getOnBackInvokedDispatcher()}.
+ * <p>
+ * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
+ * they are added within the same priority. Between different priorities, callbacks with higher
+ * priority are invoked first.
+ * <p>
+ * This replaces {@link Activity#onBackPressed()}, {@link Dialog#onBackPressed()} and
+ * {@link android.view.KeyEvent#KEYCODE_BACK}
+ * <p>
+ * @see OnBackInvokedDispatcher#registerOnBackInvokedCallback(int, OnBackInvokedCallback)
+ * registerOnBackInvokedCallback(priority, OnBackInvokedCallback)
+ * to specify callback priority.
*/
+@SuppressWarnings("deprecation")
public interface OnBackInvokedCallback {
- /**
- * Called when a back gesture has been started, or back button has been pressed down.
- *
- * @hide
- */
- default void onBackStarted() { };
-
- /**
- * Called on back gesture progress.
- *
- * @param backEvent An {@link android.window.BackEvent} object describing the progress event.
- *
- * @see android.window.BackEvent
- * @hide
- */
- default void onBackProgressed(BackEvent backEvent) { };
-
- /**
- * Called when a back gesture or back button press has been cancelled.
- *
- * @hide
- */
- default void onBackCancelled() { };
-
/**
* Called when a back gesture has been completed and committed, or back button pressed
* has been released and committed.
*/
- default void onBackInvoked() { };
+ void onBackInvoked();
}
diff --git a/core/java/android/window/OnBackInvokedDispatcher.java b/core/java/android/window/OnBackInvokedDispatcher.java
index c254a9df3b4c..6bc2b5043e79 100644
--- a/core/java/android/window/OnBackInvokedDispatcher.java
+++ b/core/java/android/window/OnBackInvokedDispatcher.java
@@ -19,7 +19,6 @@ package android.window;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.os.Build;
@@ -93,15 +92,6 @@ public interface OnBackInvokedDispatcher {
void unregisterOnBackInvokedCallback(@NonNull OnBackInvokedCallback callback);
/**
- * Returns the most prioritized callback to receive back dispatch next.
- * @hide
- */
- @Nullable
- default OnBackInvokedCallback getTopCallback() {
- return null;
- }
-
- /**
* Registers a {@link OnBackInvokedCallback} with system priority.
* @hide
*/
diff --git a/core/java/android/window/OnBackInvokedDispatcherOwner.java b/core/java/android/window/OnBackInvokedDispatcherOwner.java
deleted file mode 100644
index dfe06fd39170..000000000000
--- a/core/java/android/window/OnBackInvokedDispatcherOwner.java
+++ /dev/null
@@ -1,33 +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 android.window;
-
-import android.annotation.NonNull;
-
-/**
- * A class that provides an {@link OnBackInvokedDispatcher} that allows you to register
- * an {@link OnBackInvokedCallback} for handling the system back invocation behavior.
- */
-public interface OnBackInvokedDispatcherOwner {
- /**
- * Returns the {@link OnBackInvokedDispatcher} that should dispatch the back invocation
- * to its registered {@link OnBackInvokedCallback}s.
- * Returns null when the root view is not attached to a window or a view tree with a decor.
- */
- @NonNull
- OnBackInvokedDispatcher getOnBackInvokedDispatcher();
-}
diff --git a/core/java/android/window/ProxyOnBackInvokedDispatcher.java b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
index eb776310b8bb..44093971a23e 100644
--- a/core/java/android/window/ProxyOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
@@ -28,8 +28,8 @@ import java.util.List;
* {@link OnBackInvokedDispatcher} only used to hold callbacks while an actual
* dispatcher becomes available. <b>It does not dispatch the back events</b>.
* <p>
- * Once the actual {@link OnBackInvokedDispatcherOwner} becomes available,
- * {@link #setActualDispatcherOwner(OnBackInvokedDispatcherOwner)} needs to
+ * Once the actual {@link OnBackInvokedDispatcher} becomes available,
+ * {@link #setActualDispatcher(OnBackInvokedDispatcher)} needs to
* be called and this {@link ProxyOnBackInvokedDispatcher} will pass the callback registrations
* onto it.
* <p>
@@ -48,14 +48,14 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
*/
private final List<Pair<OnBackInvokedCallback, Integer>> mCallbacks = new ArrayList<>();
private final Object mLock = new Object();
- private OnBackInvokedDispatcherOwner mActualDispatcherOwner = null;
+ private OnBackInvokedDispatcher mActualDispatcher = null;
@Override
public void registerOnBackInvokedCallback(
int priority, @NonNull OnBackInvokedCallback callback) {
if (DEBUG) {
- Log.v(TAG, String.format("Pending register %s. Actual=%s", callback,
- mActualDispatcherOwner));
+ Log.v(TAG, String.format("Proxy register %s. mActualDispatcher=%s", callback,
+ mActualDispatcher));
}
if (priority < 0) {
throw new IllegalArgumentException("Application registered OnBackInvokedCallback "
@@ -74,13 +74,12 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
@NonNull OnBackInvokedCallback callback) {
if (DEBUG) {
Log.v(TAG, String.format("Proxy unregister %s. Actual=%s", callback,
- mActualDispatcherOwner));
+ mActualDispatcher));
}
synchronized (mLock) {
mCallbacks.removeIf((p) -> p.first.equals(callback));
- if (mActualDispatcherOwner != null) {
- mActualDispatcherOwner.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(
- callback);
+ if (mActualDispatcher != null) {
+ mActualDispatcher.unregisterOnBackInvokedCallback(callback);
}
}
}
@@ -89,9 +88,8 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
@NonNull OnBackInvokedCallback callback, int priority) {
synchronized (mLock) {
mCallbacks.add(Pair.create(callback, priority));
- if (mActualDispatcherOwner != null) {
- mActualDispatcherOwner.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
- priority, callback);
+ if (mActualDispatcher != null) {
+ mActualDispatcher.registerOnBackInvokedCallback(priority, callback);
}
}
}
@@ -103,34 +101,30 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
* proxy dispatcher.
*/
private void transferCallbacksToDispatcher() {
- if (mActualDispatcherOwner == null) {
+ if (mActualDispatcher == null) {
return;
}
- OnBackInvokedDispatcher dispatcher =
- mActualDispatcherOwner.getOnBackInvokedDispatcher();
if (DEBUG) {
- Log.v(TAG, String.format("Proxy: transferring %d pending callbacks to %s",
- mCallbacks.size(), dispatcher));
+ Log.v(TAG, String.format("Proxy transferring %d callbacks to %s", mCallbacks.size(),
+ mActualDispatcher));
}
for (Pair<OnBackInvokedCallback, Integer> callbackPair : mCallbacks) {
int priority = callbackPair.second;
if (priority >= 0) {
- dispatcher.registerOnBackInvokedCallback(priority, callbackPair.first);
+ mActualDispatcher.registerOnBackInvokedCallback(priority, callbackPair.first);
} else {
- dispatcher.registerSystemOnBackInvokedCallback(callbackPair.first);
+ mActualDispatcher.registerSystemOnBackInvokedCallback(callbackPair.first);
}
}
mCallbacks.clear();
}
private void clearCallbacksOnDispatcher() {
- if (mActualDispatcherOwner == null) {
+ if (mActualDispatcher == null) {
return;
}
- OnBackInvokedDispatcher onBackInvokedDispatcher =
- mActualDispatcherOwner.getOnBackInvokedDispatcher();
for (Pair<OnBackInvokedCallback, Integer> callback : mCallbacks) {
- onBackInvokedDispatcher.unregisterOnBackInvokedCallback(callback.first);
+ mActualDispatcher.unregisterOnBackInvokedCallback(callback.first);
}
}
@@ -138,7 +132,7 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
* Resets this {@link ProxyOnBackInvokedDispatcher} so it loses track of the currently
* registered callbacks.
* <p>
- * Using this method means that when setting a new {@link OnBackInvokedDispatcherOwner}, the
+ * Using this method means that when setting a new {@link OnBackInvokedDispatcher}, the
* callbacks registered on the old one won't be removed from it and won't be registered on
* the new one.
*/
@@ -152,28 +146,26 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
}
/**
- * Sets the actual {@link OnBackInvokedDispatcherOwner} that will provides the
- * {@link OnBackInvokedDispatcher} onto which the callbacks will be registered.
+ * Sets the actual {@link OnBackInvokedDispatcher} onto which the callbacks will be registered.
* <p>
- * If any dispatcher owner was already present, all the callbacks that were added via this
+ * If any dispatcher was already present, all the callbacks that were added via this
* {@link ProxyOnBackInvokedDispatcher} will be unregistered from the old one and registered
* on the new one if it is not null.
* <p>
* If you do not wish for the previously registered callbacks to be reassigned to the new
* dispatcher, {@link #reset} must be called beforehand.
*/
- public void setActualDispatcherOwner(
- @Nullable OnBackInvokedDispatcherOwner actualDispatcherOwner) {
+ public void setActualDispatcher(@Nullable OnBackInvokedDispatcher actualDispatcher) {
if (DEBUG) {
Log.v(TAG, String.format("Proxy setActual %s. Current %s",
- actualDispatcherOwner, mActualDispatcherOwner));
+ actualDispatcher, mActualDispatcher));
}
synchronized (mLock) {
- if (actualDispatcherOwner == mActualDispatcherOwner) {
+ if (actualDispatcher == mActualDispatcher) {
return;
}
clearCallbacksOnDispatcher();
- mActualDispatcherOwner = actualDispatcherOwner;
+ mActualDispatcher = actualDispatcher;
transferCallbacksToDispatcher();
}
}
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 9c2fde04e4d2..1d1deacf0eb3 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -94,13 +94,16 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
/**
* Registers remote animations per transition type for the organizer. It will override the
* animations if the transition only contains windows that belong to the organized
- * TaskFragments.
+ * TaskFragments in the given Task.
+ *
+ * @param taskId overrides if the transition only contains windows belonging to this Task.
* @hide
*/
@CallSuper
- public void registerRemoteAnimations(@NonNull RemoteAnimationDefinition definition) {
+ public void registerRemoteAnimations(int taskId,
+ @NonNull RemoteAnimationDefinition definition) {
try {
- getController().registerRemoteAnimations(mInterface, definition);
+ getController().registerRemoteAnimations(mInterface, taskId, definition);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -111,9 +114,9 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
* @hide
*/
@CallSuper
- public void unregisterRemoteAnimations() {
+ public void unregisterRemoteAnimations(int taskId) {
try {
- getController().unregisterRemoteAnimations(mInterface);
+ getController().unregisterRemoteAnimations(mInterface, taskId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/window/TransitionRequestInfo.java b/core/java/android/window/TransitionRequestInfo.java
index e0cdb133c4ce..48211a8234ee 100644
--- a/core/java/android/window/TransitionRequestInfo.java
+++ b/core/java/android/window/TransitionRequestInfo.java
@@ -67,6 +67,7 @@ public final class TransitionRequestInfo implements Parcelable {
@Nullable private Rect mEndAbsBounds = null;
private int mStartRotation = WindowConfiguration.ROTATION_UNDEFINED;
private int mEndRotation = WindowConfiguration.ROTATION_UNDEFINED;
+ private boolean mPhysicalDisplayChanged = false;
/** Create empty display-change. */
public DisplayChange(int displayId) {
@@ -121,6 +122,11 @@ public final class TransitionRequestInfo implements Parcelable {
}
@DataClass.Generated.Member
+ public boolean isPhysicalDisplayChanged() {
+ return mPhysicalDisplayChanged;
+ }
+
+ @DataClass.Generated.Member
public @android.annotation.NonNull DisplayChange setStartAbsBounds(@android.annotation.NonNull Rect value) {
mStartAbsBounds = value;
return this;
@@ -144,6 +150,12 @@ public final class TransitionRequestInfo implements Parcelable {
return this;
}
+ @DataClass.Generated.Member
+ public @android.annotation.NonNull DisplayChange setPhysicalDisplayChanged( boolean value) {
+ mPhysicalDisplayChanged = value;
+ return this;
+ }
+
@Override
@DataClass.Generated.Member
public String toString() {
@@ -155,7 +167,8 @@ public final class TransitionRequestInfo implements Parcelable {
"startAbsBounds = " + mStartAbsBounds + ", " +
"endAbsBounds = " + mEndAbsBounds + ", " +
"startRotation = " + mStartRotation + ", " +
- "endRotation = " + mEndRotation +
+ "endRotation = " + mEndRotation + ", " +
+ "physicalDisplayChanged = " + mPhysicalDisplayChanged +
" }";
}
@@ -166,6 +179,7 @@ public final class TransitionRequestInfo implements Parcelable {
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
+ if (mPhysicalDisplayChanged) flg |= 0x20;
if (mStartAbsBounds != null) flg |= 0x2;
if (mEndAbsBounds != null) flg |= 0x4;
dest.writeByte(flg);
@@ -188,6 +202,7 @@ public final class TransitionRequestInfo implements Parcelable {
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
+ boolean physicalDisplayChanged = (flg & 0x20) != 0;
int displayId = in.readInt();
Rect startAbsBounds = (flg & 0x2) == 0 ? null : (Rect) in.readTypedObject(Rect.CREATOR);
Rect endAbsBounds = (flg & 0x4) == 0 ? null : (Rect) in.readTypedObject(Rect.CREATOR);
@@ -199,6 +214,7 @@ public final class TransitionRequestInfo implements Parcelable {
this.mEndAbsBounds = endAbsBounds;
this.mStartRotation = startRotation;
this.mEndRotation = endRotation;
+ this.mPhysicalDisplayChanged = physicalDisplayChanged;
// onConstructed(); // You can define this method to get a callback
}
@@ -218,10 +234,10 @@ public final class TransitionRequestInfo implements Parcelable {
};
@DataClass.Generated(
- time = 1639445520915L,
+ time = 1648141181315L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java",
- inputSignatures = "private final int mDisplayId\nprivate @android.annotation.Nullable android.graphics.Rect mStartAbsBounds\nprivate @android.annotation.Nullable android.graphics.Rect mEndAbsBounds\nprivate int mStartRotation\nprivate int mEndRotation\nclass DisplayChange extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genBuilder=false, genConstructor=false)")
+ inputSignatures = "private final int mDisplayId\nprivate @android.annotation.Nullable android.graphics.Rect mStartAbsBounds\nprivate @android.annotation.Nullable android.graphics.Rect mEndAbsBounds\nprivate int mStartRotation\nprivate int mEndRotation\nprivate boolean mPhysicalDisplayChanged\nclass DisplayChange extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genBuilder=false, genConstructor=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 8811116b25ad..bea2c7885d57 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -175,7 +175,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
}
}
- @Override
public OnBackInvokedCallback getTopCallback() {
if (mAllCallbacks.isEmpty()) {
return null;
@@ -199,36 +198,30 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
@Override
public void onBackStarted() {
Handler.getMain().post(() -> {
- final OnBackInvokedCallback callback = mCallback.get();
- if (callback == null) {
- return;
+ final OnBackAnimationCallback callback = getBackAnimationCallback();
+ if (callback != null) {
+ callback.onBackStarted();
}
-
- callback.onBackStarted();
});
}
@Override
public void onBackProgressed(BackEvent backEvent) {
Handler.getMain().post(() -> {
- final OnBackInvokedCallback callback = mCallback.get();
- if (callback == null) {
- return;
+ final OnBackAnimationCallback callback = getBackAnimationCallback();
+ if (callback != null) {
+ callback.onBackProgressed(backEvent);
}
-
- callback.onBackProgressed(backEvent);
});
}
@Override
public void onBackCancelled() {
Handler.getMain().post(() -> {
- final OnBackInvokedCallback callback = mCallback.get();
- if (callback == null) {
- return;
+ final OnBackAnimationCallback callback = getBackAnimationCallback();
+ if (callback != null) {
+ callback.onBackCancelled();
}
-
- callback.onBackCancelled();
});
}
@@ -243,6 +236,13 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
callback.onBackInvoked();
});
}
+
+ @Nullable
+ private OnBackAnimationCallback getBackAnimationCallback() {
+ OnBackInvokedCallback callback = mCallback.get();
+ return callback instanceof OnBackAnimationCallback ? (OnBackAnimationCallback) callback
+ : null;
+ }
}
/**
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
index 4a20ad0f33f5..fc2c8cca9796 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
@@ -33,7 +33,6 @@ import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build;
-import android.os.storage.StorageManager;
import android.provider.Settings;
import android.text.BidiFormatter;
import android.view.LayoutInflater;
@@ -282,19 +281,7 @@ public final class AccessibilityTargetHelper {
Context.LAYOUT_INFLATER_SERVICE);
final View content = inflater.inflate(
- R.layout.accessibility_enable_service_encryption_warning, /* root= */ null);
-
- final TextView encryptionWarningView = (TextView) content.findViewById(
- R.id.accessibility_encryption_warning);
- if (StorageManager.isNonDefaultBlockEncrypted()) {
- final String text = context.getString(
- R.string.accessibility_enable_service_encryption_warning,
- getServiceName(context, target.getLabel()));
- encryptionWarningView.setText(text);
- encryptionWarningView.setVisibility(View.VISIBLE);
- } else {
- encryptionWarningView.setVisibility(View.GONE);
- }
+ R.layout.accessibility_enable_service_warning, /* root= */ null);
final ImageView dialogIcon = content.findViewById(
R.id.accessibility_permissionDialog_icon);
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 88089b5b85f2..d4a8a164803f 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -167,16 +167,6 @@ public class ChooserActivity extends ResolverActivity implements
public static final String EXTRA_PRIVATE_RETAIN_IN_ON_STOP
= "com.android.internal.app.ChooserActivity.EXTRA_PRIVATE_RETAIN_IN_ON_STOP";
- /**
- * Boolean extra added to "unbundled Sharesheet" delegation intents to signal whether the app
- * prediction service is available. Our query of the service <em>availability</em> depends on
- * privileges that are only available in the system, even though the service itself would then
- * be available to the unbundled component. For now, we just include the query result as part of
- * the handover intent.
- * TODO: investigate whether the privileged query is necessary to determine the availability.
- */
- public static final String EXTRA_IS_APP_PREDICTION_SERVICE_AVAILABLE =
- "com.android.internal.app.ChooserActivity.EXTRA_IS_APP_PREDICTION_SERVICE_AVAILABLE";
/**
* Transition name for the first image preview.
@@ -985,6 +975,12 @@ public class ChooserActivity extends ResolverActivity implements
}
@Override
+ protected void onResume() {
+ super.onResume();
+ Log.d(TAG, "onResume: " + getComponentName().flattenToShortString());
+ }
+
+ @Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
ViewPager viewPager = findViewById(R.id.profile_pager);
diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java
index e7cb43e019ad..52c74cf81508 100644
--- a/core/java/com/android/internal/app/LocalePickerWithRegion.java
+++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java
@@ -264,10 +264,9 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O
}
@Override
- public void onListItemClick(ListView l, View v, int position, long id) {
- SuggestedLocaleAdapter adapter = (SuggestedLocaleAdapter) getListAdapter();
+ public void onListItemClick(ListView parent, View v, int position, long id) {
final LocaleStore.LocaleInfo locale =
- (LocaleStore.LocaleInfo) adapter.getItem(position);
+ (LocaleStore.LocaleInfo) parent.getAdapter().getItem(position);
// Special case for resetting the app locale to equal the system locale.
boolean isSystemLocale = locale.isSystemLocale();
boolean isRegionLocale = locale.getParent() != null;
@@ -280,7 +279,7 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O
} else {
LocalePickerWithRegion selector = LocalePickerWithRegion.createCountryPicker(
getContext(), mListener, locale, mTranslatedOnly /* translate only */,
- adapter.getAppPackageName());
+ mAppPackageName);
if (selector != null) {
getFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index ea8589bddabb..bfd8ff923dc1 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -157,8 +157,6 @@ public class ResolverActivity extends Activity implements
/** See {@link #setRetainInOnStop}. */
private boolean mRetainInOnStop;
- protected static final int REQUEST_CODE_RETURN_FROM_DELEGATE_CHOOSER = 20;
-
private static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args";
private static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
private static final String OPEN_LINKS_COMPONENT_KEY = "app_link_state";
@@ -1374,18 +1372,6 @@ public class ResolverActivity extends Activity implements
.write();
}
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CODE_RETURN_FROM_DELEGATE_CHOOSER:
- // Repeat the delegate's result as our own.
- setResult(resultCode, data);
- finish();
- break;
- default:
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
public void onActivityStarted(TargetInfo cti) {
// Do nothing
diff --git a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
index c3e7920ffc08..2eb104ed215a 100644
--- a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
+++ b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
@@ -348,8 +348,4 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
public Filter getFilter() {
return new FilterByNativeAndUiNames();
}
-
- public String getAppPackageName() {
- return mAppPackageName;
- }
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4b2034799d41..e4dec563f580 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -719,7 +719,7 @@ public class BatteryStatsImpl extends BatteryStats {
int mNumHistoryItems;
private static final int HISTORY_TAG_INDEX_LIMIT = 0x7ffe;
- private static final int MAX_HISTORY_TAG_STRING_LENGTH = 256;
+ private static final int MAX_HISTORY_TAG_STRING_LENGTH = 1024;
final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
private SparseArray<HistoryTag> mHistoryTags;
@@ -3970,6 +3970,12 @@ public class BatteryStatsImpl extends BatteryStats {
Slog.wtfStack(TAG, "writeHistoryTag called with null name");
}
+ final int stringLength = tag.string.length();
+ if (stringLength > MAX_HISTORY_TAG_STRING_LENGTH) {
+ Slog.e(TAG, "Long battery history tag: " + tag.string);
+ tag.string = tag.string.substring(0, MAX_HISTORY_TAG_STRING_LENGTH);
+ }
+
Integer idxObj = mHistoryTagPool.get(tag);
int idx;
if (idxObj != null) {
@@ -3986,11 +3992,6 @@ public class BatteryStatsImpl extends BatteryStats {
tag.poolIdx = idx;
mHistoryTagPool.put(key, idx);
mNextHistoryTagIdx++;
- final int stringLength = key.string.length();
-
- if (stringLength > MAX_HISTORY_TAG_STRING_LENGTH) {
- Slog.wtf(TAG, "Long battery history tag: " + key.string);
- }
mNumHistoryTagChars += stringLength + 1;
if (mHistoryTags != null) {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index b4ba16fef8e2..488fb180723e 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -111,7 +111,6 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.window.OnBackInvokedDispatcher;
-import android.window.OnBackInvokedDispatcherOwner;
import android.window.ProxyOnBackInvokedDispatcher;
import com.android.internal.R;
@@ -137,8 +136,7 @@ import java.util.List;
*
* @hide
*/
-public class PhoneWindow extends Window implements MenuBuilder.Callback,
- OnBackInvokedDispatcherOwner {
+public class PhoneWindow extends Window implements MenuBuilder.Callback {
private final static String TAG = "PhoneWindow";
@@ -2153,7 +2151,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback,
/** Notify when decor view is attached to window and {@link ViewRootImpl} is available. */
void onViewRootImplSet(ViewRootImpl viewRoot) {
viewRoot.setActivityConfigCallback(mActivityConfigCallback);
- mProxyOnBackInvokedDispatcher.setActualDispatcherOwner(viewRoot);
+ mProxyOnBackInvokedDispatcher.setActualDispatcher(viewRoot.getOnBackInvokedDispatcher());
applyDecorFitsSystemWindows();
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 089179dbba27..634063a44b66 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -169,7 +169,7 @@ oneway interface IStatusBar
/**
* Used to hide the authentication dialog, e.g. when the application cancels authentication.
*/
- void hideAuthenticationDialog();
+ void hideAuthenticationDialog(long requestId);
/* Used to notify the biometric service of events that occur outside of an operation. */
void setBiometicContextListener(in IBiometricContextListener listener);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 2ee5e797b4ab..46b463074383 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -131,7 +131,7 @@ interface IStatusBarService
// Used to show an error - the dialog will dismiss after a certain amount of time
void onBiometricError(int modality, int error, int vendorCode);
// Used to hide the authentication dialog, e.g. when the application cancels authentication
- void hideAuthenticationDialog();
+ void hideAuthenticationDialog(long requestId);
// Used to notify the biometric service of events that occur outside of an operation.
void setBiometicContextListener(in IBiometricContextListener listener);
diff --git a/core/java/com/android/internal/widget/BigPictureNotificationImageView.java b/core/java/com/android/internal/widget/BigPictureNotificationImageView.java
index c34a42224f5a..3a7cf74df4a8 100644
--- a/core/java/com/android/internal/widget/BigPictureNotificationImageView.java
+++ b/core/java/com/android/internal/widget/BigPictureNotificationImageView.java
@@ -20,16 +20,16 @@ import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StyleRes;
+import android.app.ActivityManager;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.util.AttributeSet;
-import android.util.Log;
import android.widget.ImageView;
import android.widget.RemoteViews;
-import java.io.IOException;
+import com.android.internal.R;
/**
* An ImageView used by BigPicture Notifications to correctly resolve the Uri in an Icon using the
@@ -41,22 +41,32 @@ public class BigPictureNotificationImageView extends ImageView {
private static final String TAG = BigPictureNotificationImageView.class.getSimpleName();
+ private final int mMaximumDrawableWidth;
+ private final int mMaximumDrawableHeight;
+
public BigPictureNotificationImageView(@NonNull Context context) {
- super(context);
+ this(context, null, 0, 0);
}
public BigPictureNotificationImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
+ this(context, attrs, 0, 0);
}
public BigPictureNotificationImageView(@NonNull Context context, @Nullable AttributeSet attrs,
@AttrRes int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ this(context, attrs, defStyleAttr, 0);
}
public BigPictureNotificationImageView(@NonNull Context context, @Nullable AttributeSet attrs,
@AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ boolean isLowRam = ActivityManager.isLowRamDeviceStatic();
+ mMaximumDrawableWidth = context.getResources().getDimensionPixelSize(
+ isLowRam ? R.dimen.notification_big_picture_max_width_low_ram
+ : R.dimen.notification_big_picture_max_width);
+ mMaximumDrawableHeight = context.getResources().getDimensionPixelSize(
+ isLowRam ? R.dimen.notification_big_picture_max_height_low_ram
+ : R.dimen.notification_big_picture_max_height);
}
@Override
@@ -85,21 +95,17 @@ public class BigPictureNotificationImageView extends ImageView {
private Drawable loadImage(Uri uri) {
if (uri == null) return null;
- try {
- return LocalImageResolver.resolveImage(uri, mContext);
- } catch (IOException ex) {
- Log.d(TAG, "Resolve failed from " + uri, ex);
- return null;
- }
+ return LocalImageResolver.resolveImage(uri, mContext, mMaximumDrawableWidth,
+ mMaximumDrawableHeight);
}
private Drawable loadImage(Icon icon) {
if (icon == null) return null;
- try {
- return LocalImageResolver.resolveImage(icon, mContext);
- } catch (IOException ex) {
- Log.d(TAG, "Resolve failed from " + icon, ex);
- return null;
+ Drawable drawable = LocalImageResolver.resolveImage(icon, mContext, mMaximumDrawableWidth,
+ mMaximumDrawableHeight);
+ if (drawable == null) {
+ return icon.loadDrawable(mContext);
}
+ return drawable;
}
}
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index db41d333e1d4..1feb5d415e16 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -88,8 +88,8 @@ public class SystemConfig {
private static final int ALLOW_HIDDENAPI_WHITELISTING = 0x040;
private static final int ALLOW_ASSOCIATIONS = 0x080;
// ALLOW_OVERRIDE_APP_RESTRICTIONS allows to use "allow-in-power-save-except-idle",
- // "allow-in-power-save", "allow-in-data-usage-save", "allow-unthrottled-location",
- // and "allow-ignore-location-settings".
+ // "allow-in-power-save", "allow-in-data-usage-save","allow-unthrottled-location",
+ // "allow-ignore-location-settings" and "allow-adas-location-settings".
private static final int ALLOW_OVERRIDE_APP_RESTRICTIONS = 0x100;
private static final int ALLOW_IMPLICIT_BROADCASTS = 0x200;
private static final int ALLOW_VENDOR_APEX = 0x400;
@@ -234,6 +234,10 @@ public class SystemConfig {
// without throttling, as read from the configuration files.
final ArraySet<String> mAllowUnthrottledLocation = new ArraySet<>();
+ // These are the packages that are allow-listed to be able to retrieve location when
+ // the location state is driver assistance only.
+ final ArrayMap<String, ArraySet<String>> mAllowAdasSettings = new ArrayMap<>();
+
// These are the packages that are white-listed to be able to retrieve location even when user
// location settings are off, for emergency purposes, as read from the configuration files.
final ArrayMap<String, ArraySet<String>> mAllowIgnoreLocationSettings = new ArrayMap<>();
@@ -394,6 +398,10 @@ public class SystemConfig {
return mAllowUnthrottledLocation;
}
+ public ArrayMap<String, ArraySet<String>> getAllowAdasLocationSettings() {
+ return mAllowAdasSettings;
+ }
+
public ArrayMap<String, ArraySet<String>> getAllowIgnoreLocationSettings() {
return mAllowIgnoreLocationSettings;
}
@@ -1007,6 +1015,34 @@ public class SystemConfig {
}
XmlUtils.skipCurrentTag(parser);
} break;
+ case "allow-adas-location-settings" : {
+ if (allowOverrideAppRestrictions) {
+ String pkgname = parser.getAttributeValue(null, "package");
+ String attributionTag = parser.getAttributeValue(null,
+ "attributionTag");
+ if (pkgname == null) {
+ Slog.w(TAG, "<" + name + "> without package in "
+ + permFile + " at " + parser.getPositionDescription());
+ } else {
+ ArraySet<String> tags = mAllowAdasSettings.get(pkgname);
+ if (tags == null || !tags.isEmpty()) {
+ if (tags == null) {
+ tags = new ArraySet<>(1);
+ mAllowAdasSettings.put(pkgname, tags);
+ }
+ if (!"*".equals(attributionTag)) {
+ if ("null".equals(attributionTag)) {
+ attributionTag = null;
+ }
+ tags.add(attributionTag);
+ }
+ }
+ }
+ } else {
+ logNotAllowedInPartition(name, permFile, parser);
+ }
+ XmlUtils.skipCurrentTag(parser);
+ } break;
case "allow-ignore-location-settings": {
if (allowOverrideAppRestrictions) {
String pkgname = parser.getAttributeValue(null, "package");
diff --git a/core/jni/android_hardware_input_InputApplicationHandle.cpp b/core/jni/android_hardware_input_InputApplicationHandle.cpp
index eab4e1d744cf..24d35316ef20 100644
--- a/core/jni/android_hardware_input_InputApplicationHandle.cpp
+++ b/core/jni/android_hardware_input_InputApplicationHandle.cpp
@@ -105,11 +105,10 @@ std::shared_ptr<InputApplicationHandle> android_view_InputApplicationHandle_getH
jobject android_view_InputApplicationHandle_fromInputApplicationInfo(
JNIEnv* env, gui::InputApplicationInfo inputApplicationInfo) {
- ScopedLocalRef<jobject> binderObject(env,
- javaObjectForIBinder(env, inputApplicationInfo.token));
+ jobject binderObject = javaObjectForIBinder(env, inputApplicationInfo.token);
ScopedLocalRef<jstring> name(env, env->NewStringUTF(inputApplicationInfo.name.data()));
return env->NewObject(gInputApplicationHandleClassInfo.clazz,
- gInputApplicationHandleClassInfo.ctor, binderObject.get(), name.get(),
+ gInputApplicationHandleClassInfo.ctor, binderObject, name.get(),
inputApplicationInfo.dispatchingTimeoutMillis);
}
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index 484d92820b86..973ed29d8e72 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -23,7 +23,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
#include <binder/IPCThreadState.h>
-#include <ftl/cast.h>
+#include <ftl/flags.h>
#include <gui/SurfaceControl.h>
#include <gui/WindowInfo.h>
#include <nativehelper/JNIHelp.h>
@@ -151,7 +151,7 @@ bool NativeInputWindowHandle::updateInfo() {
env->DeleteLocalRef(regionObj);
}
- const auto flags = Flags<WindowInfo::Flag>(
+ const auto flags = ftl::Flags<WindowInfo::Flag>(
env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsFlags));
const auto type = static_cast<WindowInfo::Type>(
env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsType));
@@ -261,8 +261,8 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
}
LOG_ALWAYS_FATAL_IF(inputWindowHandle == nullptr,
"Failed to create new InputWindowHandle object.");
- ScopedLocalRef<jobject> token(env, javaObjectForIBinder(env, windowInfo.token));
- env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.token, token.get());
+ env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.token,
+ javaObjectForIBinder(env, windowInfo.token));
ScopedLocalRef<jstring> name(env, env->NewStringUTF(windowInfo.name.data()));
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.name, name.get());
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.layoutParamsFlags,
@@ -317,9 +317,8 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
ScopedLocalRef<jobject> matrixObj(env, AMatrix_newInstance(env, transformVals));
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.transform, matrixObj.get());
- ScopedLocalRef<jobject> windowToken(env, javaObjectForIBinder(env, windowInfo.windowToken));
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.windowToken,
- windowToken.get());
+ javaObjectForIBinder(env, windowInfo.windowToken));
return inputWindowHandle;
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 39f192b662ee..518fc09dee5a 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -851,6 +851,14 @@ static void nativeSetDamageRegion(JNIEnv* env, jclass clazz, jlong transactionOb
transaction->setSurfaceDamageRegion(surfaceControl, region);
}
+static void nativeSetDimmingEnabled(JNIEnv* env, jclass clazz, jlong transactionObj,
+ jlong nativeObject, jboolean dimmingEnabled) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+ transaction->setDimmingEnabled(ctrl, dimmingEnabled);
+}
+
static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jfloat alpha) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -2095,8 +2103,9 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSetSize },
{"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V",
(void*)nativeSetTransparentRegionHint },
- { "nativeSetDamageRegion", "(JJLandroid/graphics/Region;)V",
+ {"nativeSetDamageRegion", "(JJLandroid/graphics/Region;)V",
(void*)nativeSetDamageRegion },
+ {"nativeSetDimmingEnabled", "(JJZ)V", (void*)nativeSetDimmingEnabled },
{"nativeSetAlpha", "(JJF)V",
(void*)nativeSetAlpha },
{"nativeSetColor", "(JJ[F)V",
diff --git a/core/jni/android_window_WindowInfosListener.cpp b/core/jni/android_window_WindowInfosListener.cpp
index aae2549df429..f2cbe8abae8b 100644
--- a/core/jni/android_window_WindowInfosListener.cpp
+++ b/core/jni/android_window_WindowInfosListener.cpp
@@ -22,6 +22,7 @@
#include <gui/DisplayInfo.h>
#include <gui/SurfaceComposerClient.h>
#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalFrame.h>
#include <utils/Log.h>
#include "android_hardware_input_InputWindowHandle.h"
@@ -95,6 +96,7 @@ struct WindowInfosListener : public gui::WindowInfosListener {
JNIEnv* env = AndroidRuntime::getJNIEnv();
LOG_ALWAYS_FATAL_IF(env == nullptr, "Unable to retrieve JNIEnv in onWindowInfoChanged.");
+ ScopedLocalFrame localFrame(env);
jobject listener = env->NewGlobalRef(mListener);
if (listener == nullptr) {
// Weak reference went out of scope
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 976c02e95098..96fe7e1aa541 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6007,7 +6007,7 @@
<!-- @SystemApi Allows an application to manage the cloudsearch service.
@hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.MANAGE_CLOUDSEARCH"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|privileged|role" />
<!-- @SystemApi Allows an application to manage the music recognition service.
@hide <p>Not for use by third-party applications.</p> -->
diff --git a/core/res/OWNERS b/core/res/OWNERS
index ca8b3f8aa070..95d2712a2b41 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -42,3 +42,6 @@ per-file res/*-watch/* = file:/platform/frameworks/opt/wear:/OWNERS
# PowerProfile
per-file res/xml/power_profile.xml = file:/BATTERY_STATS_OWNERS
per-file res/xml/power_profile_test.xml = file:/BATTERY_STATS_OWNERS
+
+# Telephony
+per-file res/values/config_telephony.xml = file:/platform/frameworks/opt/telephony:/OWNERS
diff --git a/core/res/res/layout/accessibility_enable_service_encryption_warning.xml b/core/res/res/layout/accessibility_enable_service_warning.xml
index 400051660592..01ef10177c5a 100644
--- a/core/res/res/layout/accessibility_enable_service_encryption_warning.xml
+++ b/core/res/res/layout/accessibility_enable_service_warning.xml
@@ -54,14 +54,6 @@
android:fontFamily="google-sans-medium"/>
<TextView
- android:id="@+id/accessibility_encryption_warning"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="10dip"
- android:textAlignment="viewStart"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
-
- <TextView
android:id="@+id/accessibility_permissionDialog_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 5fa7457b2796..cef5e21703a3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Program is nie beskikbaar nie"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nie op die oomblik beskikbaar nie."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> is nie beskikbaar nie"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Toestemming word benodig"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou Android TV-toestel."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou foon."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 4b4ceafaee89..febee72128a0 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> አይገኝም"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ፈቃድ ያስፈልጋል"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በAndroid TV መሣሪያዎ ላይ ይሞክሩ።"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በጡባዊዎ ላይ ይሞክሩ።"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በስልክዎ ላይ ይሞክሩ።"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 5ae12f688463..9479b324c89c 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ক আটাইবোৰ ডিভাইচৰ লগ এক্সেছ কৰাৰ অনুমতি প্ৰদান কৰিবনে?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"কেৱল এইবাৰৰ বাবে"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"অনুমতি নিদিব"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"আপোনাৰ ডিভাইচত কি কি ঘটে সেয়া ডিভাইচ লগে ৰেকৰ্ড কৰে। এপ্‌সমূহে সমস্যা বিচাৰিবলৈ আৰু সমাধান কৰিবলৈ এই লগসমূহ ব্যৱহাৰ কৰিব পাৰে।\n\nকিছুমান লগত সংবেদনশীল তথ্য থাকিব পাৰে, গতিকে কেৱল আপুনি বিশ্বাস কৰা এপকহে আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি দিয়ক। \n\nআপুনি যদি এই এপ্‌টোক আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি নিদিয়ে, তথাপিও ই নিজৰ লগসমূহ এক্সেছ কৰিব পাৰিব। আপোনাৰ ডিভাইচৰ নিৰ্মাতাই তথাপিও হয়তো আপোনাৰ ডিভাইচটোত থকা কিছু লগ অথবা তথ্য এক্সেছ কৰিব পাৰিব। অধিক জানক"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"পুনৰ নেদেখুৱাব"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>এ <xliff:g id="APP_2">%2$s</xliff:g>ৰ অংশ দেখুওৱাব খুজিছে"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"সম্পাদনা কৰক"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> নেপথ্যত চলি আছে আৰু অত্যধিক বেটাৰী খৰচ কৰিছে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> নেপথ্যত দীৰ্ঘ সময় ধৰি চলি আছে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"সক্ৰিয় এপ্‌সমূহ পৰীক্ষা কৰক"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা ফ’নটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা টেবলেটটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
<string name="system_locale_title" msgid="3978041860457277638">"ছিষ্টেমৰ ভাষা"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 500a94acbb2c..0a13a0ab309d 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1935,8 +1935,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недаступна: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Патрабуецца дазвол"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць прыладу Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць планшэт."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць тэлефон."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index eb1571263e36..f89e7210c158 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> не е налице"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Необходимо е разрешение"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от устройството си с Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от таблета си."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от телефона си."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 981fbda23ae6..edfc8c3bafff 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> উপলভ্য নেই"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"অনুমতি প্রয়োজন"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার Android TV ডিভাইস ব্যবহার করে দেখুন।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ট্যাবলেটে ব্যবহার করে দেখুন।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ফোনে ব্যবহার করে দেখুন।"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 2114862b8c7d..b4cb4f08173f 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1934,7 +1934,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Nedostupno: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je dopuštenje"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je odobrenje"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na uređaju Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na telefonu."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 9722ef5cd9c6..b594e347da5e 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -390,7 +390,7 @@
<string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Aquesta aplicació pot mostrar-se a sobre d\'altres aplicacions"</string>
<string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Aquesta aplicació pot mostrar-se a sobre d\'altres aplicacions o d\'altres parts de la pantalla. Això pot interferir en l\'ús normal de les aplicacions i alterar la manera en què es mostren."</string>
<string name="permlab_runInBackground" msgid="541863968571682785">"Executar en segon pla"</string>
- <string name="permdesc_runInBackground" msgid="4344539472115495141">"Aquesta aplicació es pot executar en segon pla. Això consumeix la bateria més ràpidament."</string>
+ <string name="permdesc_runInBackground" msgid="4344539472115495141">"Aquesta aplicació es pot executar en segon pla. Això pot exhaurir la bateria més ràpidament."</string>
<string name="permlab_useDataInBackground" msgid="783415807623038947">"Utilitzar dades en segon pla"</string>
<string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Aquesta aplicació utilitza dades en segon pla. Això incrementa l\'ús de dades."</string>
<string name="permlab_persistentActivity" msgid="464970041740567970">"fes que l\'aplicació s\'executi sempre"</string>
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"L\'aplicació no està disponible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Ara mateix, <xliff:g id="APP_NAME">%1$s</xliff:g> no està disponible."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no està disponible"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permís necessari"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"En aquests moments, no es pot accedir a aquesta aplicació al dispositiu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho al dispositiu Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"En aquests moments, no es pot accedir a aquesta aplicació al dispositiu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho a la tauleta."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"En aquests moments, no es pot accedir a aquesta aplicació al dispositiu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho al telèfon."</string>
@@ -2262,7 +2261,7 @@
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Missatge traduït de <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> a <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activitat en segon pla"</string>
<string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Activitat en segon pla"</string>
- <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla i esgotant la bateria. Toca per revisar-ho."</string>
+ <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla i està exhaurint la bateria. Toca per revisar-ho."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Fa molta estona que <xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla. Toca per revisar-ho."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consulta les aplicacions actives"</string>
<!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 8bcb834b3b26..7b5fbd7fd457 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1935,8 +1935,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikace není k dispozici"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> v tuto chvíli není k dispozici."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> není k dispozici"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Je vyžadováno oprávnění"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na zařízení Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na telefonu."</string>
@@ -2032,8 +2031,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Povolit aplikaci <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> přístup ke všem protokolům zařízení?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Pouze tentokrát"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nepovolovat"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Do protokolů zařízení se zaznamenává, co se na zařízení děje. Aplikace tyto protokoly mohou používat k vyhledání a odstranění problémů.\n\nNěkteré protokoly mohou zahrnovat citlivé údaje. Přístup k protokolům zařízení proto povolte pouze aplikacím, kterým důvěřujete. \n\nPokud této aplikaci nepovolíte přístup ke všem protokolům zařízení, bude mít stále přístup ke svým vlastním protokolům. Výrobce zařízení může mít stále přístup k některým protokolům nebo informacím na vašem zařízení. Další informace"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Příště nezobrazovat"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Aplikace <xliff:g id="APP_0">%1$s</xliff:g> chce zobrazovat ukázky z aplikace <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Upravit"</string>
@@ -2267,9 +2265,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikace <xliff:g id="APP">%1$s</xliff:g> je spuštěna na pozadí a vybíjí baterii. Klepnutím ji zkontrolujete."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikace <xliff:g id="APP">%1$s</xliff:g> je už dlouhou dobu spuštěna na pozadí. Klepnutím ji zkontrolujete."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Zkontrolujte aktivní aplikace"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu telefonu"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu tabletu"</string>
<string name="system_locale_title" msgid="3978041860457277638">"Jazyk systému"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 5a2787d2d11b..9efc568d376a 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgængelig"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgængelig lige nu."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> er ikke understøttet"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Der kræves tilladelse"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Du har ikke adgang til denne app på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din Android TV-enhed i stedet."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Du har ikke adgang til denne app på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din tablet i stedet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Du har ikke adgang til denne app på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din telefon i stedet."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index f4cb633ecec6..3e88ffa8a61b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> δεν διατίθεται"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Απαιτείται άδεια"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στη συσκευή Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στο tablet σας."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στο τηλέφωνό σας."</string>
@@ -2030,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Να επιτρέπεται στην εφαρμογή <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> η πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής;"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Μόνο αυτήν τη φορά"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Να μην επιτραπεί"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Τα αρχεία καταγραφής συσκευής καταγράφουν ό,τι συμβαίνει στη συσκευή σας. Οι εφαρμογές μπορούν να χρησιμοποιούν αυτά τα αρχεία καταγραφής για να εντοπίζουν και να διορθώνουν ζητήματα.\n\nΟρισμένα αρχεία καταγραφής ενδέχεται να περιέχουν ευαίσθητες πληροφορίες. Ως εκ τούτου, επιτρέψτε την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής μόνο στις εφαρμογές που εμπιστεύεστε. \n\nΕάν δεν επιτρέψετε σε αυτήν την εφαρμογή την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής, η εφαρμογή εξακολουθεί να έχει πρόσβαση στα δικά της αρχεία καταγραφής. Ο κατασκευαστής της συσκευής σας ενδέχεται να εξακολουθεί να έχει πρόσβαση σε ορισμένα αρχεία καταγραφής ή ορισμένες πληροφορίες στη συσκευή σας. Μάθετε περισσότερα"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Να μην εμφανισ. ξανά"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Η εφαρμογή <xliff:g id="APP_0">%1$s</xliff:g> θέλει να εμφανίζει τμήματα της εφαρμογής <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Επεξεργασία"</string>
@@ -2265,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Το <xliff:g id="APP">%1$s</xliff:g> εκτελείται στο παρασκήνιο και καταναλώνει μπαταρία. Έλεγχος."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> εκτελείται στο παρασκήνιο για πολύ ώρα. Πατήστε για έλεγχο."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Έλεγχος ενεργών εφαρμογών"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του τηλεφώνου από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του tablet από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="3978041860457277638">"Γλώσσα συστήματος"</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index cdb3dd7b42c7..f79faf9e6da9 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="3978041860457277638">"System language"</string>
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index e816f162e0db..936190a5babd 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="3978041860457277638">"System language"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 63515c252154..303b26a7edda 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="3978041860457277638">"System language"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e2f9440fac87..d0e3504b81fa 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="3978041860457277638">"System language"</string>
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 05545337303d..6a700f659cd1 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎Allow ‎‏‎‎‏‏‎<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ to access all device logs?‎‏‎‎‏‎"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‎‎‎Only this time‎‏‎‎‏‎"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎Don’t allow‎‏‎‎‏‎"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎Device logs record what happens on your device. Apps can use these logs to find and fix issues.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Some logs may contain sensitive info, so only allow apps you trust to access all device logs. ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more‎‏‎‎‏‎"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎Don’t show again‎‏‎‎‏‎"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ wants to show ‎‏‎‎‏‏‎<xliff:g id="APP_2">%2$s</xliff:g>‎‏‎‎‏‏‏‎ slices‎‏‎‎‏‎"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎Edit‎‏‎‎‏‎"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is running in the background and draining battery. Tap to review.‎‏‎‎‏‎"</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is running in the background for a long time. Tap to review.‎‏‎‎‏‎"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎Check active apps‎‏‎‎‏‎"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎Can’t access the phone’s camera from your ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎Can’t access the tablet’s camera from your ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="system_locale_title" msgid="3978041860457277638">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‎System language‎‏‎‎‏‎"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index db06ff278c69..4a0a4bd810c3 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"La app no está disponible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible en este momento."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Se necesitan permisos"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu teléfono."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index dbaf2819a8c0..2ab5696915dd 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"La aplicación no está disponible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"En estos momentos, <xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Se necesita permiso"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu teléfono."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 8eea04870e08..1ee5cb4610dc 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Rakendus ei ole saadaval"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole praegu saadaval."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ei ole saadaval"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Vaja on luba"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma Android TV seadmega."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma tahvelarvutiga."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma telefoniga."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 4d8baccb6d6c..a72d3a8b072a 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikazioa ez dago erabilgarri"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ez dago erabilgarri une honetan."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ez dago erabilgarri"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Baimena behar da"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili Android TV gailua."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili tableta."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili telefonoa."</string>
@@ -2269,6 +2268,5 @@
<skip />
<!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
<skip />
- <!-- no translation found for system_locale_title (3978041860457277638) -->
- <skip />
+ <string name="system_locale_title" msgid="3978041860457277638">"Sistemaren hizkuntza"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 5c435a93b7e0..f4f7258d663e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> دردسترس نیست"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"اجازه لازم است"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"‏درحال‌حاضر نمی‌توان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در دستگاه Android TV امتحان کنید."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"درحال‌حاضر نمی‌توان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در رایانه لوحی‌تان امتحان کنید."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"درحال‌حاضر نمی‌توان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در تلفنتان امتحان کنید."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 4cb8c8c10208..641c58e69849 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Sovellus ei ole käytettävissä"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole nyt käytettävissä."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ei käytettävissä"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Edellyttää käyttöoikeutta"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta Android TV ‑laitteella."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta tabletilla."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta puhelimella."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 32b0639eaa09..932cbed2c1cb 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"L\'application n\'est pas accessible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas accessible pour le moment."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non accessible"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorisation nécessaire"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Impossible d\'accéder à ce contenu sur votre appareil <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre appareil Android TV à la place."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Impossible d\'accéder à ce contenu sur votre appareil <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre tablette à la place."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Impossible d\'accéder à ce contenu sur votre appareil <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre téléphone à la place."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 859ff1387dae..13e24a4c7a69 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Application non disponible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas disponible pour le moment."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponible"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorisation nécessaire"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre appareil Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre tablette."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre téléphone."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index cf0ebb6c46ff..cfa167b5e575 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"A aplicación non está dispoñible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> non está dispoñible neste momento."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non está dispoñible"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Necesítase permiso"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde o dispositivo con Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde a tableta."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde o teléfono."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f47273487e7b..c71ed5c142c2 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Az alkalmazás nem hozzáférhető"</string>
<string name="app_blocked_message" msgid="542972921087873023">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg nem hozzáférhető."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> nem áll rendelkezése"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Engedély szükséges"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra Android TV-eszközén."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra a táblagépén."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra a telefonján."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 88a8e14c17e2..7b67261483c3 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>՝ անհասանելի է"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Անհրաժեշտ է թույլտվություն"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք Android TV սարքում։"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք ձեր պլանշետում։"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք ձեր հեռախոսում։"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index fd9ff4de391b..5ce19c309d1e 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikasi tidak tersedia"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia saat ini."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> tidak tersedia"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Perlu izin"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di perangkat Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di ponsel."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 16af64fdc89f..4725a1725e31 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Forrit er ekki tiltækt"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ekki tiltækt núna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ekki í boði"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Heimildar krafist"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í Android TV tækinu í staðinn."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í spjaldtölvunni í staðinn."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í símanum í staðinn."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index e21c2fd21949..74d9e81b22e9 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"L\'app non è disponibile"</string>
<string name="app_blocked_message" msgid="542972921087873023">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è al momento disponibile."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non disponibile"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"È necessaria l\'autorizzazione"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5a8206ae01c5..4eb2ca8f63d3 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1935,8 +1935,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> לא זמינה"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"דרושה הרשאה"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"‏אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, יש לנסות במכשיר Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, יש לנסות בטאבלט."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, יש לנסות בטלפון."</string>
@@ -2271,6 +2270,5 @@
<skip />
<!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
<skip />
- <!-- no translation found for system_locale_title (3978041860457277638) -->
- <skip />
+ <string name="system_locale_title" msgid="3978041860457277638">"שפת המערכת"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4b15f78687da..007d6744f9be 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>は利用できません"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"権限が必要"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。Android TV デバイスでのアクセスをお試しください。"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。タブレットでのアクセスをお試しください。"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。スマートフォンでのアクセスをお試しください。"</string>
@@ -2030,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> にすべてのデバイスログへのアクセスを許可しますか?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"今回のみ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"許可しない"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"デバイスのログに、このデバイスで発生したことが記録されます。アプリは問題を検出、修正するためにこれらのログを使用することができます。\n\nログによっては機密性の高い情報が含まれている可能性があるため、すべてのデバイスログへのアクセスは信頼できるアプリにのみ許可してください。\n\nすべてのデバイスログへのアクセスを許可しなかった場合も、このアプリはアプリ独自のログにアクセスできます。また、デバイスのメーカーもデバイスの一部のログや情報にアクセスできる可能性があります。詳細"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"次回から表示しない"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"「<xliff:g id="APP_0">%1$s</xliff:g>」が「<xliff:g id="APP_2">%2$s</xliff:g>」のスライスの表示をリクエストしています"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"編集"</string>
@@ -2265,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> がバックグラウンドでバッテリーを消費しています。タップして確認。"</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> がバックグラウンドで長時間実行されています。タップしてご確認ください。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"有効なアプリをチェック"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> からスマートフォンのカメラにアクセスできません"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> からタブレットのカメラにアクセスできません"</string>
<string name="system_locale_title" msgid="3978041860457277638">"システムの言語"</string>
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 6e3bfebe4a90..86359716d53c 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> მიუწვდომელია"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"საჭიროა ნებართვა"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ Android TV მოწყობილობიდან."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ ტაბლეტიდან."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ ტელეფონიდან."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 6a2064d46f7e..bacb587c1b16 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> қолжетімсіз"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Рұқсат қажет"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына Android TV құрылғысын пайдаланып көріңіз."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына планшетті пайдаланып көріңіз."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына телефонды пайдаланып көріңіз."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index a8225c3d4e41..2d25f5353809 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"មិនអាចប្រើ <xliff:g id="ACTIVITY">%1$s</xliff:g> បានទេ"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"តម្រូវឱ្យមាន​ការអនុញ្ញាត"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"មិនអាចប្រើ​កម្មវិធីនេះ​នៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នក​នៅពេលនេះ​បានទេ។ សូមសាកល្បងប្រើ​នៅលើ​ឧបករណ៍ Android TV របស់អ្នក​ជំនួសវិញ។"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"មិនអាចប្រើ​កម្មវិធីនេះ​នៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នក​នៅពេលនេះ​បានទេ។ សូមសាកល្បងប្រើ​នៅលើ​ថេប្លេត​របស់អ្នក​ជំនួសវិញ។"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"មិនអាចប្រើ​កម្មវិធីនេះ​នៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នក​នៅពេលនេះ​បានទេ។ សូមសាកល្បងប្រើ​នៅលើ​ទូរសព្ទរបស់អ្នក​ជំនួសវិញ។"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 1b657b661c9b..9103f96f39e0 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 사용할 수 없음"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"권한이 필요함"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 Android TV 기기에서 시도해 보세요."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 태블릿에서 시도해 보세요."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 스마트폰에서 시도해 보세요."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 5983ddfb8cd2..a2e925f2795e 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> жеткиликсиз"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Уруксат керек"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Android TV түзмөгүңүздөн аракет кылып көрүңүз."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Планшетиңизден кирип көрүңүз."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Анын ордуна телефондон кирип көрүңүз."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 6ed5f1c5625a..5bc416436433 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"ບໍ່ສາມາດໃຊ້ <xliff:g id="ACTIVITY">%1$s</xliff:g> ໄດ້"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ຕ້ອງມີການອະນຸຍາດ"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງໃຊ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານແທນ."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງຢູ່ແທັບເລັດຂອງທ່ານແທນ."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງຢູ່ໂທລະສັບຂອງທ່ານແທນ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 00089d4fe126..cc52123ae18a 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1935,8 +1935,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Programa nepasiekiama."</string>
<string name="app_blocked_message" msgid="542972921087873023">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ šiuo metu nepasiekiama."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"„<xliff:g id="ACTIVITY">%1$s</xliff:g>“ nepasiekiama"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Reikalingas leidimas"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti „Android TV“ įrenginį."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti planšetinį kompiuterį."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti telefoną."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index db66cea86007..81d5ccf3c0bb 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1934,8 +1934,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Lietotne nav pieejama"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pašlaik nav pieejama."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nav pieejams"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Nepieciešama atļauja"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā Android TV ierīcē."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā planšetdatorā."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā tālrunī."</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index ab701d387e34..f5b51c2f2a4a 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"എല്ലാ ഉപകരണ ലോഗുകളും ആക്‌സസ് ചെയ്യാൻ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"ഇപ്രാവശ്യം മാത്രം"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"അനുവദിക്കരുത്"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"നിങ്ങളുടെ ഉപകരണത്തിൽ എന്തൊക്കെയാണ് സംഭവിക്കുന്നതെന്ന് ഉപകരണ ലോഗുകൾ റെക്കോർഡ് ചെയ്യുന്നു. പ്രശ്‌നങ്ങൾ കണ്ടെത്തി പരിഹരിക്കുന്നതിന് ആപ്പുകൾക്ക് ഈ ലോഗുകൾ ഉപയോഗിക്കാൻ കഴിയും.\n\nചില ലോഗുകളിൽ സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട വിവരങ്ങൾ അടങ്ങിയിരിക്കാൻ സാധ്യതയുള്ളതിനാൽ, നിങ്ങൾക്ക് വിശ്വാസമുള്ള ആപ്പുകൾക്ക് മാത്രമേ എല്ലാ ഉപകരണ ലോഗുകളും ആക്‌സസ് ചെയ്യാൻ അനുമതി നൽകാവൂ. \n\nഎല്ലാ ഉപകരണ ലോഗുകളും ആക്‌സസ് ചെയ്യാൻ നിങ്ങൾ ഈ ആപ്പിനെ അനുവദിക്കുന്നില്ലെങ്കിൽ പോലും, ആപ്പിന് അതിന്റെ സ്വന്തം ലോഗുകൾ ആക്‌സസ് ചെയ്യാനാകും. നിങ്ങളുടെ ഉപകരണ നിർമ്മാതാവിനും നിങ്ങളുടെ ഉപകരണത്തിലെ ചില ലോഗുകളോ വിവരങ്ങളോ തുടർന്നും ആക്‌സസ് ചെയ്യാനായേക്കും. കൂടുതലറിയുക"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"വീണ്ടും കാണിക്കരുത്"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_2">%2$s</xliff:g> സ്ലൈസുകൾ കാണിക്കാൻ <xliff:g id="APP_0">%1$s</xliff:g> താൽപ്പര്യപ്പെടുന്നു"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"എഡിറ്റ് ചെയ്യുക"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ആപ്പ് പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു, ഇത് ബാറ്ററി ഉപയോഗിച്ചുതീർക്കുന്നു. അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"പശ്ചാത്തലത്തിൽ <xliff:g id="APP">%1$s</xliff:g> ആപ്പ് ഒരുപാട് നേരമായി റൺ ചെയ്യുന്നു. അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"സജീവമായ ആപ്പുകൾ പരിശോധിക്കുക"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ഫോണിന്റെ ക്യാമറ ആക്‌സസ് ചെയ്യാനാകില്ല"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ടാബ്‌ലെറ്റിന്റെ ക്യാമറ ആക്‌സസ് ചെയ്യാനാകില്ല"</string>
<string name="system_locale_title" msgid="3978041860457277638">"സിസ്റ്റത്തിന്റെ ഭാഷ"</string>
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 4e382370df4e..506e75f1fffc 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>-д төхөөрөмжийн бүх логт хандахыг зөвшөөрөх үү?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Зөвхөн энэ удаа"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Бүү зөвшөөр"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Төхөөрөмжийн лог нь таны төхөөрөмж дээр юу болж байгааг бичдэг. Аппууд эдгээр логийг асуудлыг олох болон засахад ашиглах боломжтой.\n\nЗарим лог эмзэг мэдээлэл агуулж байж магадгүй тул та зөвхөн итгэдэг аппууддаа төхөөрөмжийн бүх логт хандахыг зөвшөөрнө үү. \n\nХэрэв та энэ аппад төхөөрөмжийн бүх логт хандахыг зөвшөөрөхгүй бол энэ нь өөрийн логт хандах боломжтой хэвээр байх болно. Tаны төхөөрөмж үйлдвэрлэгч таны төхөөрөмж дээрх зарим лог эсвэл мэдээлэлд хандах боломжтой хэвээр байж магадгүй. Нэмэлт мэдээлэл авах"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Дахиж бүү харуул"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g>-н хэсгүүдийг (slices) харуулах хүсэлтэй байна"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Засах"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> дэвсгэрт ажиллаж байгаа бөгөөд батарейг дуусгаж байна. Хянахын тулд товшино уу."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> дэвсгэрт удаан хугацааны турш ажиллаж байна. Хянахын тулд товшино уу."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Идэвхтэй аппуудыг шалгах"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с утасны камерт хандах боломжгүй"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с таблетын камерт хандах боломжгүй"</string>
<string name="system_locale_title" msgid="3978041860457277638">"Системийн хэл"</string>
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index e0aa948bda16..c0742df2a1e8 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1474,7 +1474,7 @@
<string name="forward_intent_to_work" msgid="3620262405636021151">"तुम्ही हा अ‍ॅप आपल्या कार्य प्रोफाईलमध्‍ये वापरत आहात"</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"इनपुट पद्धत"</string>
<string name="sync_binding_label" msgid="469249309424662147">"सिंक करा"</string>
- <string name="accessibility_binding_label" msgid="1974602776545801715">"प्रवेशयोग्यता"</string>
+ <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>
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> उपलब्ध नाही"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"परवानगी आवश्यक आहे"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अ‍ॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या Android TV डिव्हाइसवर अ‍ॅक्सेस करून पहा."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अ‍ॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या टॅबलेटवर अ‍ॅक्सेस करून पहा."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अ‍ॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या फोनवर अ‍ॅक्सेस करून पहा."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index cd8b356538cd..7af1e0acc6ab 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> မရနိုင်ပါ"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ခွင့်ပြုချက်လိုအပ်သည်"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား Android TV စက်တွင် စမ်းကြည့်ပါ။"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား တက်ဘလက်တွင် စမ်းကြည့်ပါ။"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား ဖုန်းတွင် စမ်းကြည့်ပါ။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index efca7cd756ee..da4eb28f392d 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgjengelig"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgjengelig for øyeblikket."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> er utilgjengelig"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Du må gi tillatelse"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på Android TV-enheten din i stedet."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på nettbrettet ditt i stedet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på telefonen din i stedet."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 368fa46e7515..799b45773459 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> उपलब्ध छैन"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"अनुमति चाहिन्छ"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको Android TV डिभाइसमा स्ट्रिम गरी हेर्नुहोस्।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको ट्याब्लेटमा स्ट्रिम गरी हेर्नुहोस्।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको फोनमा स्ट्रिम गरी हेर्नुहोस्।"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 0b5dde11186e..85b7b62f796e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"App is niet beschikbaar"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel niet beschikbaar."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> niet beschikbaar"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Rechten vereist"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je Android TV-apparaat."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je telefoon."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index adf6c8f4b469..98df1dbf9c7a 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ଉପଲବ୍ଧ ନାହିଁ"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ଅନୁମତି ଆବଶ୍ୟକ"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ Android TV ଡିଭାଇସରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଟାବଲେଟରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଫୋନରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 1b3cc29b14cd..9f6120da1142 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਟੈਬਲੈੱਟ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 91f0c89c45c9..bd6cf4d2df51 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1935,8 +1935,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacja jest niedostępna"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest obecnie niedostępna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – brak dostępu"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Wymagane są uprawnienia"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj urządzenia z Androidem TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj telefonu."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 843f533f26fa..88d930aeb364 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
<string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permissão necessária"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu smartphone."</string>
@@ -2030,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Apenas esta vez"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Não permitir"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize apenas os apps em que você confia a acessar os registros. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações. Saiba mais"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Não mostrar novamente"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quer mostrar partes do app <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
@@ -2265,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano e drenando a energia da bateria. Toque para revisar."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano faz muito tempo. Toque para revisar."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativos"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="3978041860457277638">"Idioma do sistema"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c0ac4fd9bdf0..b816fb121b61 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"A app não está disponível"</string>
<string name="app_blocked_message" msgid="542972921087873023">"De momento, a app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorização necessária"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no telemóvel."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 843f533f26fa..88d930aeb364 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
<string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permissão necessária"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu smartphone."</string>
@@ -2030,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Apenas esta vez"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Não permitir"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize apenas os apps em que você confia a acessar os registros. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações. Saiba mais"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Não mostrar novamente"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quer mostrar partes do app <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
@@ -2265,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano e drenando a energia da bateria. Toque para revisar."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano faz muito tempo. Toque para revisar."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativos"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="3978041860457277638">"Idioma do sistema"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d1e40f56e66c..3c7dde5f03f4 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1935,8 +1935,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недоступно: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Требуется разрешение"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Эта функция пока недоступна на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>. Используйте Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Эта функция пока недоступна на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>. Используйте планшет."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Эта функция пока недоступна на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>. Используйте телефон."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index e97fbfc96382..eb91e120d0b7 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> නොතිබේ"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"අවසරය අවශ්‍යයි"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්‍රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ Android TV උපාංගයෙහි උත්සාහ කරන්න."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්‍රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ ටැබ්ලටයෙහි උත්සාහ කරන්න."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්‍රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ දුරකථනයෙහි උත්සාහ කරන්න."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 530f58c2c85f..aadb41d8f770 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1935,8 +1935,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikácia nie je dostupná"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nie je teraz dostupná."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nie je k dispozícii"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Vyžaduje sa povolenie"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste namiesto toho použiť zariadenie Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste namiesto toho použiť tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste namiesto toho použiť telefón."</string>
@@ -2032,8 +2031,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Chcete povoliť aplikácii <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> prístup k všetkým denníkom zariadenia?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Iba tentokrát"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nepovoliť"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Denníky zariadenia zaznamenávajú, čo sa deje vo vašom zariadení. Aplikácie môžu pomocou týchto denníkov vyhľadávať a riešiť problémy.\n\nNiektoré denníky môžu obsahovať citlivé údaje, preto povoľte prístup k všetkým denníkom zariadenia iba dôveryhodným aplikáciám. \n\nAk tejto aplikácii nepovolíte prístup k všetkým denníkom zariadenia, stále bude mať prístup k vlastným denníkom. Výrobca vášho zariadenia bude mať naďalej prístup k niektorým denníkom alebo informáciám vo vašom zariadení. Ďalšie informácie"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Už nezobrazovať"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> chce zobrazovať rezy z aplikácie <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Upraviť"</string>
@@ -2267,9 +2265,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikácie <xliff:g id="APP">%1$s</xliff:g> je spustená na pozadí a vybíja batériu. Skontrolujte to klepnutím."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikácia <xliff:g id="APP">%1$s</xliff:g> je dlhodobo spustená na pozadí. Skontrolujte to klepnutím."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Skontrolovať aktívne aplikácie"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere telefónu"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere tabletu"</string>
<string name="system_locale_title" msgid="3978041860457277638">"Jazyk systému"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index b724c89ee495..4d6c941e5142 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1935,8 +1935,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija ni na voljo"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno ni na voljo."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"»<xliff:g id="ACTIVITY">%1$s</xliff:g>« ni na voljo"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je dovoljenje"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite z napravo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite s tabličnim računalnikom."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite s telefonom."</string>
@@ -2032,8 +2031,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Ali aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> dovolite dostop do vseh dnevnikov naprave?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo tokrat"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne dovoli"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"V dnevnikih naprave se beleži dogajanje v napravi. Aplikacije lahko te dnevnike uporabijo za iskanje in odpravljanje težav.\n\nNekateri dnevniki morda vsebujejo občutljive podatke, zato dostop do vseh dnevnikov naprave omogočite le aplikacijam, ki jim zaupate. \n\nČe tej aplikaciji ne dovolite dostopa do vseh dnevnikov naprave, bo aplikacija kljub temu lahko dostopala do svojih dnevnikov. Proizvajalec naprave bo morda lahko kljub temu dostopal do nekaterih dnevnikov ali podatkov v napravi. Več o tem"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikaži več"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi prikazati izreze aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Uredi"</string>
@@ -2267,9 +2265,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> se izvaja v ozadju in porablja energijo baterije. Dotaknite se za pregled."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> se dolgo časa izvaja v ozadju. Dotaknite se za pregled."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Preverite aktivne aplikacije"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ni mogoče dostopati do fotoaparata telefona prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ni mogoče dostopati do fotoaparata tabličnega računalnika prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
<string name="system_locale_title" msgid="3978041860457277638">"Sistemski jezik"</string>
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index ac155e8462f4..fe17c00f80c7 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacioni nuk ofrohet"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk ofrohet për momentin."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nuk ofrohet"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Kërkohet leje"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në pajisjen Android TV më mirë."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në tablet më mirë."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në telefon më mirë."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 888fdd937b64..122e306de9e8 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Appen är inte tillgänglig"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> är inte tillgängligt just nu."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> är inte tillgänglig"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Behörighet krävs"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med Android TV-enheten i stället."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med surfplattan i stället."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med telefonen i stället."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index cca9d09bf902..9f3663635307 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Programu haipatikani"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> haipatikani hivi sasa."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> haipatikani"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Ruhusa inahitajika"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye kifaa chako cha Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye kompyuta kibao yako."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye simu yako."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 5ab27266700a..e2331becb5ea 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"อนุญาตให้ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> เข้าถึงบันทึกทั้งหมดของอุปกรณ์ใช่ไหม"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"เฉพาะครั้งนี้"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"ไม่อนุญาต"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"บันทึกของอุปกรณ์เก็บข้อมูลสิ่งที่เกิดขึ้นในอุปกรณ์ แอปสามารถใช้บันทึกเหล่านี้เพื่อค้นหาและแก้ไขปัญหา\n\nบันทึกบางรายการอาจมีข้อมูลที่ละเอียดอ่อน คุณจึงควรอนุญาตเฉพาะแอปที่เชื่อถือได้ให้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ \n\nหากคุณไม่อนุญาตให้แอปนี้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ แอปจะยังเข้าถึงบันทึกของตัวเองได้อยู่ ผู้ผลิตอุปกรณ์อาจยังเข้าถึงบันทึกหรือข้อมูลบางรายการในอุปกรณ์ของคุณได้ ดูข้อมูลเพิ่มเติม"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ไม่ต้องแสดงอีก"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ต้องการแสดงส่วนต่างๆ ของ <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"แก้ไข"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> กำลังทำงานอยู่ในเบื้องหลังและทำให้เปลืองแบตเตอรี่ แตะเพื่อตรวจสอบ"</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ทำงานอยู่ในเบื้องหลังเป็นเวลานาน แตะเพื่อตรวจสอบ"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ตรวจสอบแอปที่ใช้งานอยู่"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"เข้าถึงกล้องของโทรศัพท์จาก <xliff:g id="DEVICE">%1$s</xliff:g> ไม่ได้"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"เข้าถึงกล้องของแท็บเล็ตจาก <xliff:g id="DEVICE">%1$s</xliff:g> ไม่ได้"</string>
<string name="system_locale_title" msgid="3978041860457277638">"ภาษาของระบบ"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index aee994b0bef0..dfc161629bdb 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -2029,8 +2029,7 @@
<string name="log_access_confirmation_title" msgid="2343578467290592708">"Payagan ang <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na i-access ang lahat ng log ng device?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Ngayon lang"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Huwag payagan"</string>
- <!-- no translation found for log_access_confirmation_body (6581985716241928135) -->
- <skip />
+ <string name="log_access_confirmation_body" msgid="6581985716241928135">"Nire-record ng mga log ng device kung ano ang nangyayari sa iyong device. Magagamit ng mga app ang mga log na ito para maghanap at mag-ayos ng mga isyu.\n\nPosibleng maglaman ang ilang log ng sensitibong impormasyon, kaya ang mga app lang na pinagkakatiwalaan mo ang payagang maka-access sa lahat ng log ng device. \n\nKung hindi mo papayagan ang app na ito na i-access ang lahat ng log ng device, maa-access pa rin nito ang mga sarili nitong log. Posible pa ring ma-access ng manufacturer ng iyong device ang ilang log o impormasyon sa device mo. Matuto pa"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Huwag ipakita ulit"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Gustong ipakita ng <xliff:g id="APP_0">%1$s</xliff:g> ang mga slice ng <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"I-edit"</string>
@@ -2264,9 +2263,7 @@
<string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Gumagana ang <xliff:g id="APP">%1$s</xliff:g> sa background at gumagamit ito ng baterya I-tap para suriin."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Napakatagal nang gumagana ang <xliff:g id="APP">%1$s</xliff:g> sa background. I-tap para suriin."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tingnan ang mga aktibong app"</string>
- <!-- no translation found for vdm_camera_access_denied (6102378580971542473) -->
- <skip />
- <!-- no translation found for vdm_camera_access_denied (6895968310395249076) -->
- <skip />
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Hindi ma-access ang camera ng telepono mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Hindi ma-access ang camera ng tablet mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="3978041860457277638">"Wika ng system"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index b3624f37329d..153da16c5ec1 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Uygulama kullanılamıyor"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması şu anda kullanılamıyor."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> kullanılamıyor"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"İzin gerekli"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine Android TV cihazınızı kullanmayı deneyin."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine tabletinizi kullanmayı deneyin."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine telefonunuzu kullanmayı deneyin."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 56a53ea202f5..be3ee23002da 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1935,8 +1935,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недоступно: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Потрібен дозвіл"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися пристроєм Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися планшетом."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися телефоном."</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 929d9d35c22b..8c9c8d3630b3 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Ilova ishlamayapti"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Ayni vaqtda <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi ishlamayapti."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> kanali ish faoliyatida emas"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Ruxsat zarur"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Android TV qurilmasi orqali urinib koʻring."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Planshet orqali urinib koʻring."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Telefon orqali urininb koʻring."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e22126d6b851..f5f44ebcaf31 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1933,8 +1933,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Ứng dụng này không dùng được"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện không dùng được."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Không hỗ trợ <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Cần có quyền"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"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 thiết bị Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"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 máy tính bảng."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"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>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 9053195d09c0..a3809fd4c746 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>不可用"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"需要权限"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此内容。您可以尝试在 Android TV 设备上访问。"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此内容。您可以尝试在平板电脑上访问。"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前无法在您的<xliff:g id="DEVICE">%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 90811367d387..605123fe1cab 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"無法使用「<xliff:g id="ACTIVITY">%1$s</xliff:g>」"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"需要權限"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用 Android TV 裝置存取。"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用平板電腦存取。"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用手機存取。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index b257d16c47ac..f7e7243d0e2c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1933,8 +1933,7 @@
<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>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"無法存取「<xliff:g id="ACTIVITY">%1$s</xliff:g>」"</string>
- <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"需要相關權限"</string>
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用 Android TV 裝置。"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用平板電腦。"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用手機。"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 155e9034b96f..d2f31b05313d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -6960,9 +6960,13 @@
<!-- Special option for window animations: whether window should have rounded corners.
@see ScreenDecorationsUtils#getWindowCornerRadius(Resources) -->
<attr name="hasRoundedCorners" format="boolean" />
+ <!-- Special option for window animations: whether to show a background behind the animating
+ windows. By default the window's background is used unless overridden by the
+ animation. -->
+ <attr name="showBackdrop" format="boolean" />
<!-- Special option for window animations: whether the window's background should be used as
a background to the animation. -->
- <attr name="showBackground" format="boolean" />
+ <attr name="backdropColor" format="color" />
</declare-styleable>
<declare-styleable name="AnimationSet">
@@ -8871,8 +8875,6 @@
<attr name="shortcutLongLabel"/>
<!-- Text shown on the button that takes users to the wallet application -->
<attr name="shortcutShortLabel"/>
- <!-- When true, launch the component specified in targetActivity for quick access -->
- <attr name="useTargetActivityForQuickAccess" format="boolean"/>
</declare-styleable>
<!-- Use <code>recognition-service</code> as the root tag of the XML resource that
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 29ca3bffb6aa..60d875c2ca39 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -690,6 +690,11 @@
will apply, regardless of device state. -->
<string-array name="config_perDeviceStateRotationLockDefaults" />
+ <!-- Dock behavior -->
+
+ <!-- Control whether to start dream immediately upon docking even if the lockscreen is unlocked.
+ This defaults to true to be consistent with historical behavior. -->
+ <bool name="config_startDreamImmediatelyOnDock">true</bool>
<!-- Desk dock behavior -->
@@ -1372,10 +1377,6 @@
<integer name="config_screenBrightnessDoze">1</integer>
<item name="config_screenBrightnessDozeFloat" format="float" type="dimen">0.0</item>
- <!-- Delay that allows some content to arrive at the display before switching
- from DOZE to ON. -->
- <integer name="config_wakeUpDelayDoze">0</integer>
-
<!-- Whether or not to skip the initial brightness ramps when the display transitions to
STATE_ON. Setting this to true will skip the brightness ramp to the last stored active
brightness value and will repeat for the following ramp if autobrightness is enabled. -->
@@ -2702,41 +2703,10 @@
<string-array name="config_mobile_tcp_buffers">
</string-array>
- <!-- Configure tcp buffer sizes per network type in the form:
- network-type:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
-
- The network-type must be a valid DataConfigNetworkType value. If no value is found for the
- network-type in use, config_tcp_buffers will be used instead.
- -->
- <string-array name="config_network_type_tcp_buffers">
- </string-array>
-
- <!-- Configure tcp buffer sizes in the form:
- rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
- If this is configured as an empty string, the system default will be applied.
-
- For now this config is used by mobile data only. In the future it should be
- used by Wi-Fi as well.
- -->
- <string name="config_tcp_buffers" translatable="false"></string>
-
<!-- Configure ethernet tcp buffersizes in the form:
rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
<string name="config_ethernet_tcp_buffers" translatable="false">524288,1048576,3145728,524288,1048576,2097152</string>
- <!-- What source to use to estimate link upstream and downstream bandwidth capacities.
- Default is bandwidth_estimator.
- Values are bandwidth_estimator, carrier_config and modem. -->
- <string name="config_bandwidthEstimateSource">bandwidth_estimator</string>
-
- <!-- Whether force to enable telephony new data stack or not -->
- <bool name="config_force_enable_telephony_new_data_stack">true</bool>
-
- <!-- Whether to adopt the predefined handover policies for IWLAN.
- {@see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY}
- -->
- <bool name="config_enable_iwlan_handover_policy">true</bool>
-
<!-- Whether WiFi display is supported by this device.
There are many prerequisites for this feature to work correctly.
Here are a few of them:
@@ -3316,27 +3286,6 @@
<!-- String array containing numbers that shouldn't be logged. Country-specific. -->
<string-array name="unloggable_phone_numbers" />
- <!-- Cellular data service package name to bind to by default. If none is specified in an overlay, an
- empty string is passed in -->
- <string name="config_wwan_data_service_package" translatable="false">com.android.phone</string>
-
- <!-- IWLAN data service package name to bind to by default. If none is specified in an overlay, an
- empty string is passed in -->
- <string name="config_wlan_data_service_package" translatable="false"></string>
-
- <!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec
- tunnels across service restart. If iwlan tunnels are not persisted across restart,
- Framework will clean up dangling data connections when service restarts -->
- <bool name="config_wlan_data_service_conn_persistence_on_restart">true</bool>
-
- <!-- Cellular data service class name to bind to by default. If none is specified in an overlay, an
- empty string is passed in -->
- <string name="config_wwan_data_service_class" translatable="false"></string>
-
- <!-- IWLAN data service class name to bind to by default. If none is specified in an overlay, an
- empty string is passed in -->
- <string name="config_wlan_data_service_class" translatable="false"></string>
-
<bool name="config_networkSamplingWakesDevice">true</bool>
<!--From SmsMessage-->
@@ -3436,11 +3385,6 @@
<item>2</item> <!-- USAGE_SETTING_DATA_CENTRIC -->
</integer-array>
- <!-- When a radio power off request is received, we will delay completing the request until
- either IMS moves to the deregistered state or the timeout defined by this configuration
- elapses. If 0, this feature is disabled and we do not delay radio power off requests.-->
- <integer name="config_delay_for_ims_dereg_millis">0</integer>
-
<!--Thresholds for LTE dbm in status bar-->
<integer-array translatable="false" name="config_lteDbmThresholds">
<item>-140</item> <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
@@ -4404,24 +4348,6 @@
<bool name="config_keepRestrictedProfilesInBackground">true</bool>
- <!-- Cellular network service package name to bind to by default. -->
- <string name="config_wwan_network_service_package" translatable="false">com.android.phone</string>
-
- <!-- Cellular network service class name to bind to by default.-->
- <string name="config_wwan_network_service_class" translatable="false"></string>
-
- <!-- IWLAN network service package name to bind to by default. If none is specified in an overlay, an
- empty string is passed in -->
- <string name="config_wlan_network_service_package" translatable="false"></string>
-
- <!-- IWLAN network service class name to bind to by default. If none is specified in an overlay, an
- empty string is passed in -->
- <string name="config_wlan_network_service_class" translatable="false"></string>
- <!-- Telephony qualified networks service package name to bind to by default. -->
- <string name="config_qualified_networks_service_package" translatable="false"></string>
-
- <!-- Telephony qualified networks service class name to bind to by default. -->
- <string name="config_qualified_networks_service_class" translatable="false"></string>
<!-- Wear devices: Controls the radios affected by Activity Mode. -->
<string-array name="config_wearActivityModeRadios">
<item>"wifi"</item>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
new file mode 100644
index 000000000000..cd3578c727f0
--- /dev/null
+++ b/core/res/res/values/config_telephony.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<resources>
+ <!-- This file defines Android telephony related resources -->
+
+ <!-- Whether force to enable telephony new data stack or not -->
+ <bool name="config_force_enable_telephony_new_data_stack">true</bool>
+ <java-symbol type="bool" name="config_force_enable_telephony_new_data_stack" />
+
+ <!-- Configure tcp buffer sizes per network type in the form:
+ network-type:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
+
+ The network-type must be a valid DataConfigNetworkType value. If no value is found for the
+ network-type in use, config_tcp_buffers will be used instead.
+ -->
+ <string-array name="config_network_type_tcp_buffers">
+ </string-array>
+ <java-symbol type="array" name="config_network_type_tcp_buffers" />
+
+ <!-- Configure tcp buffer sizes in the form:
+ rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
+ If this is configured as an empty string, the system default will be applied.
+ -->
+ <string name="config_tcp_buffers" translatable="false"></string>
+ <java-symbol type="string" name="config_tcp_buffers" />
+
+ <!-- What source to use to estimate link upstream and downstream bandwidth capacities.
+ Default is bandwidth_estimator.
+ Values are bandwidth_estimator, carrier_config and modem. -->
+ <string name="config_bandwidthEstimateSource">bandwidth_estimator</string>
+ <java-symbol type="string" name="config_bandwidthEstimateSource" />
+
+ <!-- Whether to adopt the predefined handover policies for IWLAN.
+ {@see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY}
+ -->
+ <bool name="config_enable_iwlan_handover_policy">true</bool>
+ <java-symbol type="bool" name="config_enable_iwlan_handover_policy" />
+
+ <!-- When a radio power off request is received, we will delay completing the request until
+ either IMS moves to the deregistered state or the timeout defined by this configuration
+ elapses. If 0, this feature is disabled and we do not delay radio power off requests.-->
+ <integer name="config_delay_for_ims_dereg_millis">0</integer>
+ <java-symbol type="integer" name="config_delay_for_ims_dereg_millis" />
+
+ <!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec
+ tunnels across service restart. If iwlan tunnels are not persisted across restart,
+ Framework will clean up dangling data connections when service restarts -->
+ <bool name="config_wlan_data_service_conn_persistence_on_restart">true</bool>
+ <java-symbol type="bool" name="config_wlan_data_service_conn_persistence_on_restart" />
+
+ <!-- Cellular data service package name to bind to by default. If none is specified in an
+ overlay, an empty string is passed in -->
+ <string name="config_wwan_data_service_package" translatable="false">com.android.phone</string>
+ <java-symbol type="string" name="config_wwan_data_service_package" />
+
+ <!-- IWLAN data service package name to bind to by default. If none is specified in an overlay,
+ an empty string is passed in -->
+ <string name="config_wlan_data_service_package" translatable="false"></string>
+ <java-symbol type="string" name="config_wlan_data_service_package" />
+
+ <!-- Cellular data service class name to bind to by default. If none is specified in an overlay,
+ an empty string is passed in -->
+ <string name="config_wwan_data_service_class" translatable="false"></string>
+ <java-symbol type="string" name="config_wwan_data_service_class" />
+
+ <!-- IWLAN data service class name to bind to by default. If none is specified in an overlay, an
+ empty string is passed in -->
+ <string name="config_wlan_data_service_class" translatable="false"></string>
+ <java-symbol type="string" name="config_wlan_data_service_class" />
+
+ <!-- Cellular network service package name to bind to by default. -->
+ <string name="config_wwan_network_service_package" translatable="false">
+ com.android.phone
+ </string>
+ <java-symbol type="string" name="config_wwan_network_service_package" />
+
+ <!-- Cellular network service class name to bind to by default.-->
+ <string name="config_wwan_network_service_class" translatable="false"></string>
+ <java-symbol type="string" name="config_wwan_network_service_class" />
+
+ <!-- IWLAN network service package name to bind to by default. If none is specified in an
+ overlay, an empty string is passed in -->
+ <string name="config_wlan_network_service_package" translatable="false"></string>
+ <java-symbol type="string" name="config_wlan_network_service_package" />
+
+ <!-- IWLAN network service class name to bind to by default. If none is specified in an overlay,
+ an empty string is passed in -->
+ <string name="config_wlan_network_service_class" translatable="false"></string>
+ <java-symbol type="string" name="config_wlan_network_service_class" />
+
+ <!-- Telephony qualified networks service package name to bind to by default. -->
+ <string name="config_qualified_networks_service_package" translatable="false"></string>
+ <java-symbol type="string" name="config_qualified_networks_service_package" />
+
+ <!-- Telephony qualified networks service class name to bind to by default. -->
+ <string name="config_qualified_networks_service_class" translatable="false"></string>
+ <java-symbol type="string" name="config_qualified_networks_service_class" />
+</resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index aaf6a41e996d..870f54989674 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -126,8 +126,8 @@
<public name="allowGameDownscaling" />
<public name="allowGameFpsOverride" />
<public name="localeConfig" />
- <public name="showBackground" />
- <public name="useTargetActivityForQuickAccess"/>
+ <public name="showBackdrop" />
+ <public name="removed_useTargetActivityForQuickAccess"/>
<public name="removed_inheritKeyStoreKeys" />
<public name="preferKeepClear" />
<public name="autoHandwritingEnabled" />
@@ -152,6 +152,7 @@
<public name="maxDrawableWidth" />
<!-- @hide -->
<public name="maxDrawableHeight" />
+ <public name="backdropColor" />
</staging-public-group>
<staging-public-group type="id" first-id="0x01de0000">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1b947e961f36..3d73a02fca4a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1694,7 +1694,7 @@
<string name="screen_lock_dialog_default_subtitle">Enter your screen lock to continue</string>
<!-- Message shown during fingerprint acquisision when the fingerprint cannot be recognized -->
- <string name="fingerprint_acquired_partial">Partial fingerprint detected</string>
+ <string name="fingerprint_acquired_partial">Press firmly on the sensor</string>
<!-- Message shown during fingerprint acquisision when the fingerprint cannot be recognized -->
<string name="fingerprint_acquired_insufficient">Couldn\'t process fingerprint. Please try again.</string>
<!-- Message shown during fingerprint acquisision when the fingerprint sensor needs cleaning -->
@@ -1718,7 +1718,7 @@
<!-- Message shown when fingerprint fails to match -->
<string name="fingerprint_error_not_match">Fingerprint not recognized</string>
<!-- Message shown when UDFPS fails to match -->
- <string name="fingerprint_udfps_error_not_match">Press firmly on the sensor</string>
+ <string name="fingerprint_udfps_error_not_match">Fingerprint not recognized</string>
<!-- Accessibility message announced when a fingerprint has been authenticated [CHAR LIMIT=NONE] -->
<string name="fingerprint_authenticated">Fingerprint authenticated</string>
@@ -4768,13 +4768,6 @@
<xliff:g id="service" example="TalkBack">%1$s</xliff:g> to have full control of your
device?</string>
- <!-- Warning that the device data will not be encrypted with password or PIN if
- enabling an accessibility service and there is a secure lock setup. [CHAR LIMIT=NONE] -->
- <string name="accessibility_enable_service_encryption_warning">If you turn on
- <xliff:g id="service" example="TalkBack">%1$s</xliff:g>, your device won’t use your screen
- lock to enhance data encryption.
- </string>
-
<!-- Warning description that explains that it's appropriate for accessibility
services to have full control to help users with accessibility needs. [CHAR LIMIT=NONE] -->
<string name="accessibility_service_warning_description">Full control is appropriate for apps
@@ -5716,8 +5709,8 @@
<!-- Title for the log access confirmation dialog. [CHAR LIMIT=NONE] -->
<string name="log_access_confirmation_title">Allow <xliff:g id="log_access_app_name" example="Example App">%s</xliff:g> to access all device logs?</string>
- <!-- Label for the allow button on the log access confirmation dialog. [CHAR LIMIT=20] -->
- <string name="log_access_confirmation_allow">Only this time</string>
+ <!-- Label for the allow button on the log access confirmation dialog. [CHAR LIMIT=40] -->
+ <string name="log_access_confirmation_allow">Allow one-time access</string>
<!-- Label for the deny button on the log access confirmation dialog. [CHAR LIMIT=20] -->
<string name="log_access_confirmation_deny">Don\u2019t allow</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8fa5dd2c756b..7069e716087d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -294,17 +294,6 @@
<java-symbol type="bool" name="config_enableBurnInProtection" />
<java-symbol type="bool" name="config_hotswapCapable" />
<java-symbol type="bool" name="config_mms_content_disposition_support" />
- <java-symbol type="string" name="config_wwan_network_service_package" />
- <java-symbol type="string" name="config_wlan_network_service_package" />
- <java-symbol type="string" name="config_wwan_network_service_class" />
- <java-symbol type="string" name="config_wlan_network_service_class" />
- <java-symbol type="bool" name="config_wlan_data_service_conn_persistence_on_restart" />
- <java-symbol type="string" name="config_wwan_data_service_package" />
- <java-symbol type="string" name="config_wlan_data_service_package" />
- <java-symbol type="string" name="config_wwan_data_service_class" />
- <java-symbol type="string" name="config_wlan_data_service_class" />
- <java-symbol type="string" name="config_qualified_networks_service_package" />
- <java-symbol type="string" name="config_qualified_networks_service_class" />
<java-symbol type="bool" name="config_networkSamplingWakesDevice" />
<java-symbol type="bool" name="config_showMenuShortcutsWhenKeyboardPresent" />
<java-symbol type="bool" name="config_sip_wifi_only" />
@@ -472,10 +461,6 @@
<java-symbol type="integer" name="config_safe_media_volume_usb_mB" />
<java-symbol type="integer" name="config_mobile_mtu" />
<java-symbol type="array" name="config_mobile_tcp_buffers" />
- <java-symbol type="array" name="config_network_type_tcp_buffers" />
- <java-symbol type="string" name="config_tcp_buffers" />
- <java-symbol type="bool" name="config_force_enable_telephony_new_data_stack" />
- <java-symbol type="bool" name="config_enable_iwlan_handover_policy" />
<java-symbol type="integer" name="config_volte_replacement_rat"/>
<java-symbol type="integer" name="config_valid_wappush_index" />
<java-symbol type="integer" name="config_overrideHasPermanentMenuKey" />
@@ -489,10 +474,8 @@
<java-symbol type="integer" name="config_num_physical_slots" />
<java-symbol type="integer" name="config_default_cellular_usage_setting" />
<java-symbol type="array" name="config_supported_cellular_usage_settings" />
- <java-symbol type="integer" name="config_delay_for_ims_dereg_millis" />
<java-symbol type="array" name="config_integrityRuleProviderPackages" />
<java-symbol type="bool" name="config_useAssistantVolume" />
- <java-symbol type="string" name="config_bandwidthEstimateSource" />
<java-symbol type="integer" name="config_smartSelectionInitializedTimeoutMillis" />
<java-symbol type="integer" name="config_smartSelectionInitializingTimeoutMillis" />
<java-symbol type="integer" name="config_preferKeepClearForFocusDelayMillis" />
@@ -1732,6 +1715,7 @@
<java-symbol type="attr" name="dialogTitleIconsDecorLayout" />
<java-symbol type="bool" name="config_allowAllRotations" />
<java-symbol type="bool" name="config_annoy_dianne" />
+ <java-symbol type="bool" name="config_startDreamImmediatelyOnDock" />
<java-symbol type="bool" name="config_carDockEnablesAccelerometer" />
<java-symbol type="bool" name="config_customUserSwitchUi" />
<java-symbol type="bool" name="config_deskDockEnablesAccelerometer" />
@@ -3487,14 +3471,12 @@
<java-symbol type="string" name="accessibility_edit_shortcut_menu_volume_title" />
<java-symbol type="string" name="accessibility_uncheck_legacy_item_warning" />
- <java-symbol type="layout" name="accessibility_enable_service_encryption_warning" />
+ <java-symbol type="layout" name="accessibility_enable_service_warning" />
<java-symbol type="id" name="accessibility_permissionDialog_icon" />
<java-symbol type="id" name="accessibility_permissionDialog_title" />
- <java-symbol type="id" name="accessibility_encryption_warning" />
<java-symbol type="id" name="accessibility_permission_enable_allow_button" />
<java-symbol type="id" name="accessibility_permission_enable_deny_button" />
<java-symbol type="string" name="accessibility_enable_service_title" />
- <java-symbol type="string" name="accessibility_enable_service_encryption_warning" />
<java-symbol type="layout" name="accessibility_shortcut_chooser_item" />
<java-symbol type="id" name="accessibility_shortcut_target_checkbox" />
@@ -3969,7 +3951,6 @@
<java-symbol type="string" name="config_misprovisionedBrandValue" />
<java-symbol type="integer" name="db_wal_truncate_size" />
- <java-symbol type="integer" name="config_wakeUpDelayDoze" />
<!-- For Bluetooth AbsoluteVolume -->
<java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index1" />
diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
index 114317abc07c..eb8e13d91390 100644
--- a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
+++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
@@ -332,21 +332,23 @@ public class VirtualDisplayTest extends AndroidTestCase {
}
private void runOnUiThread(Runnable runnable) {
- Runnable waiter = new Runnable() {
- @Override
- public void run() {
- synchronized (this) {
- notifyAll();
- }
- }
- };
- synchronized (waiter) {
- mHandler.post(runnable);
- mHandler.post(waiter);
+ final Throwable[] thrown = new Throwable[1];
+ assertTrue("Timed out", mHandler.runWithScissors(() -> {
try {
- waiter.wait(TIMEOUT);
- } catch (InterruptedException ex) {
+ runnable.run();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ thrown[0] = t;
+ }
+ }, TIMEOUT));
+ if (thrown[0] != null) {
+ if (thrown[0] instanceof RuntimeException) {
+ throw (RuntimeException) thrown[0];
+ }
+ if (thrown[0] instanceof Error) {
+ throw (Error) thrown[0];
}
+ throw new RuntimeException(thrown[0]);
}
}
diff --git a/core/tests/coretests/src/android/text/TextUtilsTest.java b/core/tests/coretests/src/android/text/TextUtilsTest.java
index a0fc34923a4d..c4bcfd4cf117 100644
--- a/core/tests/coretests/src/android/text/TextUtilsTest.java
+++ b/core/tests/coretests/src/android/text/TextUtilsTest.java
@@ -43,6 +43,7 @@ import com.google.android.collect.Lists;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -782,6 +783,81 @@ public class TextUtilsTest {
}
@Test
+ public void truncateStringForUtf8Storage() {
+ assertEquals("", TextUtils.truncateStringForUtf8Storage("abc", 0));
+
+ //================ long normal case ================
+ StringBuilder builder = new StringBuilder();
+
+ int n = 50;
+ for (int i = 0; i < 2 * n; i++) {
+ builder.append("哈");
+ }
+ String initial = builder.toString();
+ String result = TextUtils.truncateStringForUtf8Storage(initial, n);
+
+ // Result should be the beginning of initial
+ assertTrue(initial.startsWith(result));
+
+ // Result should take less than n bytes in UTF-8
+ assertTrue(result.getBytes(StandardCharsets.UTF_8).length <= n);
+
+ // result + the next codePoint should take strictly more than
+ // n bytes in UTF-8
+ assertTrue(initial.substring(0, initial.offsetByCodePoints(result.length(), 1))
+ .getBytes(StandardCharsets.UTF_8).length > n);
+
+ // =================== short normal case =====================
+ String s = "sf\u20ACgk\u00E9ls\u00E9fg";
+ result = TextUtils.truncateStringForUtf8Storage(s, 100);
+ assertEquals(s, result);
+ }
+
+ @Test
+ public void testTruncateInMiddleOfSurrogate() {
+ StringBuilder builder = new StringBuilder();
+ String beginning = "a";
+ builder.append(beginning);
+ builder.append(Character.toChars(0x1D11E));
+
+ String result = TextUtils.truncateStringForUtf8Storage(builder.toString(), 3);
+
+ // \u1D11E is a surrogate and needs 4 bytes in UTF-8. beginning == "a" uses
+ // only 1 bytes in UTF8
+ // As we allow only 3 bytes for the whole string, so just 2 for this
+ // codePoint, there is not enough place and the string will be truncated
+ // just before it
+ assertEquals(beginning, result);
+ }
+
+ @Test
+ public void testTruncateInMiddleOfChar() {
+ StringBuilder builder = new StringBuilder();
+ String beginning = "a";
+ builder.append(beginning);
+ builder.append(Character.toChars(0x20AC));
+
+ String result = TextUtils.truncateStringForUtf8Storage(builder.toString(), 3);
+
+ // Like above, \u20AC uses 3 bytes in UTF-8, with "beginning", that makes
+ // 4 bytes so it is too big and should be truncated
+ assertEquals(beginning, result);
+ }
+
+ @Test
+ public void testTruncateSubString() {
+ String test = "sdgkl;hjsl;gjhdgkljdfhglkdj";
+ String sub = test.substring(10, 20);
+ String res = TextUtils.truncateStringForUtf8Storage(sub, 255);
+ assertEquals(sub, res);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void truncateStringForUtf8StorageThrowsExceptionForNegativeSize() {
+ TextUtils.truncateStringForUtf8Storage("abc", -1);
+ }
+
+ @Test
public void length() {
assertEquals(0, TextUtils.length(null));
assertEquals(0, TextUtils.length(""));
diff --git a/core/tests/coretests/src/android/window/BackNavigationTest.java b/core/tests/coretests/src/android/window/BackNavigationTest.java
index 94a149b09d54..678eef557fed 100644
--- a/core/tests/coretests/src/android/window/BackNavigationTest.java
+++ b/core/tests/coretests/src/android/window/BackNavigationTest.java
@@ -111,12 +111,7 @@ public class BackNavigationTest {
CountDownLatch backRegisteredLatch = new CountDownLatch(1);
mScenario.onActivity(activity -> {
activity.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
- 0, new OnBackInvokedCallback() {
- @Override
- public void onBackInvoked() {
- backInvokedLatch.countDown();
- }
- }
+ 0, backInvokedLatch::countDown
);
backRegisteredLatch.countDown();
});
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 212f4ed92b8c..6aa5be5c1a1b 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -56,9 +56,9 @@ public class WindowOnBackInvokedDispatcherTest {
private IWindow mWindow;
private WindowOnBackInvokedDispatcher mDispatcher;
@Mock
- private OnBackInvokedCallback mCallback1;
+ private OnBackAnimationCallback mCallback1;
@Mock
- private OnBackInvokedCallback mCallback2;
+ private OnBackAnimationCallback mCallback2;
@Before
public void setUp() throws Exception {
diff --git a/core/tests/coretests/src/com/android/internal/widget/OWNERS b/core/tests/coretests/src/com/android/internal/widget/OWNERS
index b40fe240d80c..659a3d1a5c46 100644
--- a/core/tests/coretests/src/com/android/internal/widget/OWNERS
+++ b/core/tests/coretests/src/com/android/internal/widget/OWNERS
@@ -1,3 +1,7 @@
+include /core/java/com/android/internal/widget/OWNERS
+
+# Notifications related
+per-file CachingIconViewTest.java = file:/services/core/java/com/android/server/notification/OWNERS
# LockSettings related
per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS
per-file *Lockscreen* = file:/services/core/java/com/android/server/locksettings/OWNERS
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index a02ac6c39e93..61bb1ee2561f 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -223,37 +223,13 @@
targetSdk="29">
<new-permission name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</split-permission>
- <split-permission name="android.permission.BODY_SENSORS"
- targetSdk="33">
- <new-permission name="android.permission.BODY_SENSORS_BACKGROUND" />
- </split-permission>
<split-permission name="android.permission.READ_EXTERNAL_STORAGE"
targetSdk="29">
<new-permission name="android.permission.ACCESS_MEDIA_LOCATION" />
</split-permission>
- <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_AUDIO" />
- </split-permission>
- <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_VIDEO" />
- </split-permission>
- <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_IMAGES" />
- </split-permission>
- <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_AUDIO" />
- </split-permission>
- <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_VIDEO" />
- </split-permission>
<split-permission name="android.permission.WRITE_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_IMAGES" />
+ targetSdk="29">
+ <new-permission name="android.permission.ACCESS_MEDIA_LOCATION" />
</split-permission>
<split-permission name="android.permission.BLUETOOTH"
targetSdk="31">
@@ -279,6 +255,34 @@
targetSdk="31">
<new-permission name="android.permission.BLUETOOTH_ADVERTISE" />
</split-permission>
+ <split-permission name="android.permission.BODY_SENSORS"
+ targetSdk="33">
+ <new-permission name="android.permission.BODY_SENSORS_BACKGROUND" />
+ </split-permission>
+ <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
+ targetSdk="33">
+ <new-permission name="android.permission.READ_MEDIA_AUDIO" />
+ </split-permission>
+ <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
+ targetSdk="33">
+ <new-permission name="android.permission.READ_MEDIA_VIDEO" />
+ </split-permission>
+ <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
+ targetSdk="33">
+ <new-permission name="android.permission.READ_MEDIA_IMAGES" />
+ </split-permission>
+ <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE"
+ targetSdk="33">
+ <new-permission name="android.permission.READ_MEDIA_AUDIO" />
+ </split-permission>
+ <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE"
+ targetSdk="33">
+ <new-permission name="android.permission.READ_MEDIA_VIDEO" />
+ </split-permission>
+ <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE"
+ targetSdk="33">
+ <new-permission name="android.permission.READ_MEDIA_IMAGES" />
+ </split-permission>
<!-- This is a list of all the libraries available for application
code to link against. -->
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 472741653d9e..58a2073981bf 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -116,24 +116,6 @@ applications that come with the platform
<permission name="android.permission.PACKAGE_USAGE_STATS"/>
</privapp-permissions>
- <privapp-permissions package="com.android.permissioncontroller">
- <permission name="android.permission.CLEAR_APP_CACHE"/>
- <permission name="android.permission.MANAGE_USERS"/>
- <permission name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"/>
- <permission name="android.permission.GET_APP_OPS_STATS"/>
- <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
- <permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/>
- <permission name="android.permission.APPROVE_INCIDENT_REPORTS"/>
- <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
- <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
- <permission name="android.permission.PACKAGE_USAGE_STATS" />
- <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
- <permission name="android.permission.MODIFY_AUDIO_ROUTING" />
- <permission name="android.permission.WRITE_SECURE_SETTINGS" />
- <permission name="android.permission.READ_SAFETY_CENTER_STATUS" />
- <permission name="android.permission.SEND_SAFETY_CENTER_UPDATE" />
- </privapp-permissions>
-
<privapp-permissions package="com.android.phone">
<permission name="android.permission.ACCESS_IMS_CALL_SERVICE"/>
<permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
@@ -291,12 +273,14 @@ applications that come with the platform
<permission name="android.permission.LOCAL_MAC_ADDRESS"/>
<permission name="android.permission.MANAGE_ACCESSIBILITY"/>
<permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
+ <permission name="android.permission.ACCESS_FPS_COUNTER"/>
<permission name="android.permission.MANAGE_GAME_MODE"/>
<permission name="android.permission.MANAGE_GAME_ACTIVITY" />
<permission name="android.permission.MANAGE_LOW_POWER_STANDBY" />
<permission name="android.permission.MANAGE_ROLLBACKS"/>
<permission name="android.permission.MANAGE_USB"/>
<!-- Needed for tests only -->
+ <permission name="android.permission.MANAGE_CLOUDSEARCH" />
<permission name="android.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION" />
<permission name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/>
<permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 3a900e6e6bfa..80b144acd991 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -703,6 +703,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-1427392850": {
+ "message": "WindowState: Setting back callback %s (priority: %d) (Client IWindow: %s). (WindowState: %s)",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
"-1427184084": {
"message": "addWindow: New client %s: window=%s Callers=%s",
"level": "VERBOSE",
diff --git a/framework-jarjar-rules.txt b/framework-jarjar-rules.txt
index be21f4e87101..03b268d87d01 100644
--- a/framework-jarjar-rules.txt
+++ b/framework-jarjar-rules.txt
@@ -5,3 +5,6 @@ rule android.hidl.** android.internal.hidl.@1
# Framework-specific renames.
rule android.net.wifi.WifiAnnotations* android.internal.wifi.WifiAnnotations@1
rule com.android.server.vcn.util.** com.android.server.vcn.repackaged.util.@1
+
+# for modules-utils-build dependency
+rule com.android.modules.utils.build.** android.internal.modules.utils.build.@1
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index 6987401525b4..fdcb7be597d5 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -31,11 +31,13 @@ import android.util.Log;
import android.util.SparseIntArray;
import androidx.window.util.BaseDataProducer;
+import androidx.window.util.DataProducer;
import com.android.internal.R;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
/**
* An implementation of {@link androidx.window.util.DataProducer} that returns the device's posture
@@ -48,7 +50,6 @@ public final class DeviceStateManagerFoldingFeatureProducer extends
DeviceStateManagerFoldingFeatureProducer.class.getSimpleName();
private static final boolean DEBUG = false;
- private final Context mContext;
private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
private int mCurrentDeviceState = INVALID_DEVICE_STATE;
@@ -57,9 +58,12 @@ public final class DeviceStateManagerFoldingFeatureProducer extends
mCurrentDeviceState = state;
notifyDataChanged();
};
+ @NonNull
+ private final DataProducer<String> mRawFoldSupplier;
- public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context) {
- mContext = context;
+ public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context,
+ @NonNull DataProducer<String> rawFoldSupplier) {
+ mRawFoldSupplier = rawFoldSupplier;
String[] deviceStatePosturePairs = context.getResources()
.getStringArray(R.array.config_device_state_postures);
for (String deviceStatePosturePair : deviceStatePosturePairs) {
@@ -97,12 +101,21 @@ public final class DeviceStateManagerFoldingFeatureProducer extends
@Nullable
public Optional<List<CommonFoldingFeature>> getData() {
final int globalHingeState = globalHingeState();
- String displayFeaturesString = mContext.getResources().getString(
- R.string.config_display_features);
- if (TextUtils.isEmpty(displayFeaturesString)) {
+ Optional<String> displayFeaturesString = mRawFoldSupplier.getData();
+ if (displayFeaturesString.isEmpty() || TextUtils.isEmpty(displayFeaturesString.get())) {
return Optional.empty();
}
- return Optional.of(parseListFromString(displayFeaturesString, globalHingeState));
+ return Optional.of(parseListFromString(displayFeaturesString.get(), globalHingeState));
+ }
+
+ @Override
+ protected void onListenersChanged(Set<Runnable> callbacks) {
+ super.onListenersChanged(callbacks);
+ if (callbacks.isEmpty()) {
+ mRawFoldSupplier.removeDataChangedCallback(this::notifyDataChanged);
+ } else {
+ mRawFoldSupplier.addDataChangedCallback(this::notifyDataChanged);
+ }
}
private int globalHingeState() {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
index 0e696eb8efb7..69ad1badce60 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
@@ -16,11 +16,6 @@
package androidx.window.common;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
-import static androidx.window.common.CommonFoldingFeature.parseListFromString;
-
import android.annotation.NonNull;
import android.content.ContentResolver;
import android.content.Context;
@@ -33,75 +28,88 @@ import android.text.TextUtils;
import androidx.window.util.BaseDataProducer;
-import java.util.Collections;
-import java.util.List;
+import com.android.internal.R;
+
import java.util.Optional;
+import java.util.Set;
/**
- * Implementation of {@link androidx.window.util.DataProducer} that produces
- * {@link CommonFoldingFeature} parsed from a string stored in {@link Settings}.
+ * Implementation of {@link androidx.window.util.DataProducer} that produces a
+ * {@link String} that can be parsed to a {@link CommonFoldingFeature}.
+ * {@link RawFoldingFeatureProducer} searches for the value in two places. The first check is in
+ * settings where the {@link String} property is saved with the key
+ * {@link RawFoldingFeatureProducer#DISPLAY_FEATURES}. If this value is null or empty then the
+ * value in {@link android.content.res.Resources} is used. If both are empty then
+ * {@link RawFoldingFeatureProducer#getData()} returns an empty object.
+ * {@link RawFoldingFeatureProducer} listens to changes in the setting so that it can override
+ * the system {@link CommonFoldingFeature} data.
*/
-public final class SettingsDisplayFeatureProducer
- extends BaseDataProducer<List<CommonFoldingFeature>> {
+public final class RawFoldingFeatureProducer extends BaseDataProducer<String> {
private static final String DISPLAY_FEATURES = "display_features";
- private static final String DEVICE_POSTURE = "device_posture";
- private final Uri mDevicePostureUri =
- Settings.Global.getUriFor(DEVICE_POSTURE);
private final Uri mDisplayFeaturesUri =
Settings.Global.getUriFor(DISPLAY_FEATURES);
private final ContentResolver mResolver;
private final ContentObserver mObserver;
+ private final String mResourceFeature;
private boolean mRegisteredObservers;
- public SettingsDisplayFeatureProducer(@NonNull Context context) {
+ public RawFoldingFeatureProducer(@NonNull Context context) {
mResolver = context.getContentResolver();
mObserver = new SettingsObserver();
- }
-
- private int getPosture() {
- int posture = Settings.Global.getInt(mResolver, DEVICE_POSTURE, COMMON_STATE_UNKNOWN);
- if (posture == COMMON_STATE_HALF_OPENED || posture == COMMON_STATE_FLAT) {
- return posture;
- } else {
- return COMMON_STATE_UNKNOWN;
- }
+ mResourceFeature = context.getResources().getString(R.string.config_display_features);
}
@Override
@NonNull
- public Optional<List<CommonFoldingFeature>> getData() {
- String displayFeaturesString = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
+ public Optional<String> getData() {
+ String displayFeaturesString = getFeatureString();
if (displayFeaturesString == null) {
return Optional.empty();
}
+ return Optional.of(displayFeaturesString);
+ }
+
+ /**
+ * Returns the {@link String} representation for a {@link CommonFoldingFeature} from settings if
+ * present and falls back to the resource value if empty or {@code null}.
+ */
+ private String getFeatureString() {
+ String settingsFeature = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
+ if (TextUtils.isEmpty(settingsFeature)) {
+ return mResourceFeature;
+ }
+ return settingsFeature;
+ }
- if (TextUtils.isEmpty(displayFeaturesString)) {
- return Optional.of(Collections.emptyList());
+ @Override
+ protected void onListenersChanged(Set<Runnable> callbacks) {
+ if (callbacks.isEmpty()) {
+ unregisterObserversIfNeeded();
+ } else {
+ registerObserversIfNeeded();
}
- return Optional.of(parseListFromString(displayFeaturesString, getPosture()));
}
/**
* Registers settings observers, if needed. When settings observers are registered for this
* producer callbacks for changes in data will be triggered.
*/
- public void registerObserversIfNeeded() {
+ private void registerObserversIfNeeded() {
if (mRegisteredObservers) {
return;
}
mRegisteredObservers = true;
mResolver.registerContentObserver(mDisplayFeaturesUri, false /* notifyForDescendants */,
mObserver /* ContentObserver */);
- mResolver.registerContentObserver(mDevicePostureUri, false, mObserver);
}
/**
* Unregisters settings observers, if needed. When settings observers are unregistered for this
* producer callbacks for changes in data will not be triggered.
*/
- public void unregisterObserversIfNeeded() {
+ private void unregisterObserversIfNeeded() {
if (!mRegisteredObservers) {
return;
}
@@ -116,7 +124,7 @@ public final class SettingsDisplayFeatureProducer
@Override
public void onChange(boolean selfChange, Uri uri) {
- if (mDisplayFeaturesUri.equals(uri) || mDevicePostureUri.equals(uri)) {
+ if (mDisplayFeaturesUri.equals(uri)) {
notifyDataChanged();
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index 180c77250fd1..f4e91bae54ee 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -35,6 +35,8 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.Map;
import java.util.concurrent.Executor;
@@ -56,7 +58,8 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
final Map<IBinder, Configuration> mFragmentParentConfigs = new ArrayMap<>();
private final TaskFragmentCallback mCallback;
- private TaskFragmentAnimationController mAnimationController;
+ @VisibleForTesting
+ TaskFragmentAnimationController mAnimationController;
/**
* Callback that notifies the controller about changes to task fragments.
@@ -80,21 +83,25 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
@Override
public void unregisterOrganizer() {
- stopOverrideSplitAnimation();
- mAnimationController = null;
+ if (mAnimationController != null) {
+ mAnimationController.unregisterAllRemoteAnimations();
+ mAnimationController = null;
+ }
super.unregisterOrganizer();
}
- void startOverrideSplitAnimation() {
+ /** Overrides the animation if the transition is on the given Task. */
+ void startOverrideSplitAnimation(int taskId) {
if (mAnimationController == null) {
mAnimationController = new TaskFragmentAnimationController(this);
}
- mAnimationController.registerRemoteAnimations();
+ mAnimationController.registerRemoteAnimations(taskId);
}
- void stopOverrideSplitAnimation() {
+ /** No longer overrides the animation if the transition is on the given Task. */
+ void stopOverrideSplitAnimation(int taskId) {
if (mAnimationController != null) {
- mAnimationController.unregisterRemoteAnimations();
+ mAnimationController.unregisterRemoteAnimations(taskId);
}
}
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 bb3b534403bb..c76fa9658c67 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -37,6 +37,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.util.ArraySet;
import android.util.SparseArray;
import android.window.TaskFragmentInfo;
import android.window.WindowContainerTransaction;
@@ -75,10 +76,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private Consumer<List<SplitInfo>> mEmbeddingCallback;
private final List<SplitInfo> mLastReportedSplitStates = new ArrayList<>();
- // We currently only support split activity embedding within the one root Task.
- // TODO(b/207720388): move to TaskContainer
- private final Rect mParentBounds = new Rect();
-
public SplitController() {
mPresenter = new SplitPresenter(new MainThreadExecutor(), this);
ActivityThread activityThread = ActivityThread.currentActivityThread();
@@ -95,7 +92,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
public void setEmbeddingRules(@NonNull Set<EmbeddingRule> rules) {
mSplitRules.clear();
mSplitRules.addAll(rules);
- updateAnimationOverride();
+ for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
+ updateAnimationOverride(mTaskContainers.keyAt(i));
+ }
}
@NonNull
@@ -163,38 +162,49 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@Override
public void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo) {
- TaskFragmentContainer container = getContainer(taskFragmentInfo.getFragmentToken());
- if (container == null) {
- return;
+ final TaskFragmentContainer container = getContainer(taskFragmentInfo.getFragmentToken());
+ if (container != null) {
+ // Cleanup if the TaskFragment vanished is not requested by the organizer.
+ mPresenter.cleanupContainer(container, true /* shouldFinishDependent */);
+ updateCallbackIfNecessary();
}
-
- mPresenter.cleanupContainer(container, true /* shouldFinishDependent */);
- updateCallbackIfNecessary();
+ cleanupTaskFragment(taskFragmentInfo.getFragmentToken());
}
@Override
public void onTaskFragmentParentInfoChanged(@NonNull IBinder fragmentToken,
@NonNull Configuration parentConfig) {
- onParentBoundsMayChange(parentConfig.windowConfiguration.getBounds());
TaskFragmentContainer container = getContainer(fragmentToken);
if (container != null) {
+ onTaskBoundsMayChange(container.getTaskId(),
+ parentConfig.windowConfiguration.getBounds());
mPresenter.updateContainer(container);
updateCallbackIfNecessary();
}
}
- private void onParentBoundsMayChange(Activity activity) {
- if (activity.isFinishing()) {
+ /** Called on receiving {@link #onTaskFragmentVanished(TaskFragmentInfo)} for cleanup. */
+ private void cleanupTaskFragment(@NonNull IBinder taskFragmentToken) {
+ for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
+ final TaskContainer taskContainer = mTaskContainers.valueAt(i);
+ if (!taskContainer.mFinishedContainer.remove(taskFragmentToken)) {
+ continue;
+ }
+ if (taskContainer.isEmpty()) {
+ // Cleanup the TaskContainer if it becomes empty.
+ mPresenter.stopOverrideSplitAnimation(taskContainer.mTaskId);
+ mTaskContainers.remove(taskContainer.mTaskId);
+ }
return;
}
-
- onParentBoundsMayChange(mPresenter.getParentContainerBounds(activity));
}
- private void onParentBoundsMayChange(Rect parentBounds) {
- if (!parentBounds.isEmpty() && !mParentBounds.equals(parentBounds)) {
- mParentBounds.set(parentBounds);
- updateAnimationOverride();
+ private void onTaskBoundsMayChange(int taskId, @NonNull Rect taskBounds) {
+ final TaskContainer taskContainer = mTaskContainers.get(taskId);
+ if (taskContainer != null && !taskBounds.isEmpty()
+ && !taskContainer.mTaskBounds.equals(taskBounds)) {
+ taskContainer.mTaskBounds.set(taskBounds);
+ updateAnimationOverride(taskId);
}
}
@@ -202,9 +212,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* Updates if we should override transition animation. We only want to override if the Task
* bounds is large enough for at least one split rule.
*/
- private void updateAnimationOverride() {
- if (mParentBounds.isEmpty()) {
- // We don't know about the parent bounds yet.
+ private void updateAnimationOverride(int taskId) {
+ final TaskContainer taskContainer = mTaskContainers.get(taskId);
+ if (taskContainer == null || !taskContainer.isTaskBoundsInitialized()) {
+ // We don't know about the Task bounds yet.
return;
}
@@ -214,7 +225,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
if (!(rule instanceof SplitRule)) {
continue;
}
- if (mPresenter.shouldShowSideBySide(mParentBounds, (SplitRule) rule)) {
+ if (mPresenter.shouldShowSideBySide(taskContainer.mTaskBounds, (SplitRule) rule)) {
supportSplit = true;
break;
}
@@ -222,9 +233,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// We only want to override if it supports split.
if (supportSplit) {
- mPresenter.startOverrideSplitAnimation();
+ mPresenter.startOverrideSplitAnimation(taskId);
} else {
- mPresenter.stopOverrideSplitAnimation();
+ mPresenter.stopOverrideSplitAnimation(taskId);
}
}
@@ -243,11 +254,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
final TaskFragmentContainer currentContainer = getContainerWithActivity(
launchedActivity.getActivityToken());
- if (currentContainer == null) {
- // Initial check before any TaskFragment is created.
- onParentBoundsMayChange(launchedActivity);
- }
-
// Check if the activity is configured to always be expanded.
if (shouldExpand(launchedActivity, null, splitRules)) {
if (shouldContainerBeExpanded(currentContainer)) {
@@ -326,8 +332,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// onTaskFragmentParentInfoChanged
return;
}
- // The bounds of the container may have been changed.
- onParentBoundsMayChange(activity);
// Check if activity requires a placeholder
launchPlaceholderIfNecessary(activity);
@@ -357,9 +361,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
TaskFragmentContainer newContainer(@Nullable Activity activity, int taskId) {
final TaskFragmentContainer container = new TaskFragmentContainer(activity, taskId);
if (!mTaskContainers.contains(taskId)) {
- mTaskContainers.put(taskId, new TaskContainer());
+ mTaskContainers.put(taskId, new TaskContainer(taskId));
+ }
+ final TaskContainer taskContainer = mTaskContainers.get(taskId);
+ taskContainer.mContainers.add(container);
+ if (activity != null && !taskContainer.isTaskBoundsInitialized()) {
+ // Initial check before any TaskFragment has appeared.
+ onTaskBoundsMayChange(taskId, SplitPresenter.getTaskBoundsFromActivity(activity));
}
- mTaskContainers.get(taskId).mContainers.add(container);
return container;
}
@@ -391,11 +400,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return;
}
taskContainer.mContainers.remove(container);
- if (taskContainer.mContainers.isEmpty()) {
- mTaskContainers.remove(taskId);
- // No more TaskFragment in this Task, so no need to check split container.
- return;
- }
+ // 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
+ // TaskFragment there.
+ taskContainer.mFinishedContainer.add(container.getTaskFragmentToken());
final List<SplitContainer> containersToRemove = new ArrayList<>();
for (SplitContainer splitContainer : taskContainer.mSplitContainers) {
@@ -543,7 +552,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
boolean launchPlaceholderIfNecessary(@NonNull Activity activity) {
- final TaskFragmentContainer container = getContainerWithActivity(
+ final TaskFragmentContainer container = getContainerWithActivity(
activity.getActivityToken());
// Don't launch placeholder if the container is occluded.
if (container != null && container != getTopActiveContainer(container.getTaskId())) {
@@ -1035,7 +1044,30 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
/** Represents TaskFragments and split pairs below a Task. */
@VisibleForTesting
static class TaskContainer {
+ /** The unique task id. */
+ final int mTaskId;
+ /** Active TaskFragments in this Task. */
final List<TaskFragmentContainer> mContainers = new ArrayList<>();
+ /** Active split pairs in this Task. */
final List<SplitContainer> mSplitContainers = new ArrayList<>();
+ /**
+ * TaskFragments that the organizer has requested to be closed. They should be removed when
+ * the organizer receives {@link #onTaskFragmentVanished(TaskFragmentInfo)} event for them.
+ */
+ final Set<IBinder> mFinishedContainer = new ArraySet<>();
+ /** Available window bounds of this Task. */
+ final Rect mTaskBounds = new Rect();
+
+ TaskContainer(int taskId) {
+ mTaskId = taskId;
+ }
+
+ boolean isEmpty() {
+ return mContainers.isEmpty() && mFinishedContainer.isEmpty();
+ }
+
+ boolean isTaskBoundsInitialized() {
+ return !mTaskBounds.isEmpty();
+ }
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index e7552ff48d52..e4d9edeb4c6e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -419,7 +419,11 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
}
}
- // TODO(b/190433398): Check if the client-side available info about parent bounds is enough.
+ return getTaskBoundsFromActivity(activity);
+ }
+
+ @NonNull
+ static Rect getTaskBoundsFromActivity(@NonNull Activity activity) {
if (!activity.isInMultiWindowMode()) {
// In fullscreen mode the max bounds should correspond to the task bounds.
return activity.getResources().getConfiguration().windowConfiguration.getMaxBounds();
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java
index a801dc8193fd..f721341a3647 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java
@@ -24,11 +24,14 @@ import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
+import android.util.ArraySet;
import android.util.Log;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
import android.window.TaskFragmentOrganizer;
+import com.android.internal.annotations.VisibleForTesting;
+
/** Controls the TaskFragment remote animations. */
class TaskFragmentAnimationController {
@@ -37,8 +40,10 @@ class TaskFragmentAnimationController {
private final TaskFragmentOrganizer mOrganizer;
private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner();
- private final RemoteAnimationDefinition mDefinition;
- private boolean mIsRegister;
+ @VisibleForTesting
+ final RemoteAnimationDefinition mDefinition;
+ /** Task Ids that we have registered for remote animation. */
+ private final ArraySet<Integer> mRegisterTasks = new ArraySet<>();
TaskFragmentAnimationController(TaskFragmentOrganizer organizer) {
mOrganizer = organizer;
@@ -54,25 +59,32 @@ class TaskFragmentAnimationController {
mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter);
}
- void registerRemoteAnimations() {
+ void registerRemoteAnimations(int taskId) {
if (DEBUG) {
Log.v(TAG, "registerRemoteAnimations");
}
- if (mIsRegister) {
+ if (mRegisterTasks.contains(taskId)) {
return;
}
- mOrganizer.registerRemoteAnimations(mDefinition);
- mIsRegister = true;
+ mOrganizer.registerRemoteAnimations(taskId, mDefinition);
+ mRegisterTasks.add(taskId);
}
- void unregisterRemoteAnimations() {
+ void unregisterRemoteAnimations(int taskId) {
if (DEBUG) {
Log.v(TAG, "unregisterRemoteAnimations");
}
- if (!mIsRegister) {
+ if (!mRegisterTasks.contains(taskId)) {
return;
}
- mOrganizer.unregisterRemoteAnimations();
- mIsRegister = false;
+ mOrganizer.unregisterRemoteAnimations(taskId);
+ mRegisterTasks.remove(taskId);
+ }
+
+ void unregisterAllRemoteAnimations() {
+ final ArraySet<Integer> tasks = new ArraySet<>(mRegisterTasks);
+ for (int taskId : tasks) {
+ unregisterRemoteAnimations(taskId);
+ }
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index a4fbdbc493f5..2f7d958434a3 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -37,9 +37,8 @@ import androidx.annotation.NonNull;
import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
-import androidx.window.common.SettingsDisplayFeatureProducer;
+import androidx.window.common.RawFoldingFeatureProducer;
import androidx.window.util.DataProducer;
-import androidx.window.util.PriorityDataProducer;
import java.util.ArrayList;
import java.util.List;
@@ -62,17 +61,14 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
private final Map<Activity, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
new ArrayMap<>();
- private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
public WindowLayoutComponentImpl(Context context) {
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
- mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
- mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
- mSettingsDisplayFeatureProducer,
- new DeviceStateManagerFoldingFeatureProducer(context)
- ));
+ RawFoldingFeatureProducer foldingFeatureProducer = new RawFoldingFeatureProducer(context);
+ mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context,
+ foldingFeatureProducer);
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
}
@@ -85,7 +81,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
public void addWindowLayoutInfoListener(@NonNull Activity activity,
@NonNull Consumer<WindowLayoutInfo> consumer) {
mWindowLayoutChangeListeners.put(activity, consumer);
- updateRegistrations();
+ onDisplayFeaturesChanged();
}
/**
@@ -96,7 +92,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
public void removeWindowLayoutInfoListener(
@NonNull Consumer<WindowLayoutInfo> consumer) {
mWindowLayoutChangeListeners.values().remove(consumer);
- updateRegistrations();
+ onDisplayFeaturesChanged();
}
void updateWindowLayout(@NonNull Activity activity,
@@ -210,15 +206,6 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
return features;
}
- private void updateRegistrations() {
- if (hasListeners()) {
- mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
- } else {
- mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
- }
- onDisplayFeaturesChanged();
- }
-
private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index c7b709347060..970f0a2af632 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -34,9 +34,8 @@ import androidx.annotation.NonNull;
import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
-import androidx.window.common.SettingsDisplayFeatureProducer;
+import androidx.window.common.RawFoldingFeatureProducer;
import androidx.window.util.DataProducer;
-import androidx.window.util.PriorityDataProducer;
import java.util.ArrayList;
import java.util.Collections;
@@ -52,16 +51,13 @@ class SampleSidecarImpl extends StubSidecar {
private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
- private final SettingsDisplayFeatureProducer mSettingsFoldingFeatureProducer;
SampleSidecarImpl(Context context) {
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
- mSettingsFoldingFeatureProducer = new SettingsDisplayFeatureProducer(context);
- mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
- mSettingsFoldingFeatureProducer,
- new DeviceStateManagerFoldingFeatureProducer(context)
- ));
+ DataProducer<String> settingsFeatureProducer = new RawFoldingFeatureProducer(context);
+ mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context,
+ settingsFeatureProducer);
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
}
@@ -142,10 +138,7 @@ class SampleSidecarImpl extends StubSidecar {
@Override
protected void onListenersChanged() {
if (hasListeners()) {
- mSettingsFoldingFeatureProducer.registerObserversIfNeeded();
onDisplayFeaturesChanged();
- } else {
- mSettingsFoldingFeatureProducer.unregisterObserversIfNeeded();
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
index 0a46703451ab..930db3b701b7 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
@@ -33,13 +33,17 @@ public abstract class BaseDataProducer<T> implements DataProducer<T> {
@Override
public final void addDataChangedCallback(@NonNull Runnable callback) {
mCallbacks.add(callback);
+ onListenersChanged(mCallbacks);
}
@Override
public final void removeDataChangedCallback(@NonNull Runnable callback) {
mCallbacks.remove(callback);
+ onListenersChanged(mCallbacks);
}
+ protected void onListenersChanged(Set<Runnable> callbacks) {}
+
/**
* Called to notify all registered callbacks that the data provided by {@link #getData()} has
* changed.
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/PriorityDataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/PriorityDataProducer.java
deleted file mode 100644
index 990ae20cc934..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/PriorityDataProducer.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 androidx.window.util;
-
-import android.annotation.Nullable;
-
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Implementation of {@link DataProducer} that delegates calls to {@link #getData()} to the list of
- * provided child producers.
- * <p>
- * The value returned is based on the precedence of the supplied children where the producer with
- * index 0 has a higher precedence than producers that come later in the list. When a producer with
- * a higher precedence has a non-empty value returned from {@link #getData()}, its value will be
- * returned from an instance of this class, ignoring all other producers with lower precedence.
- *
- * @param <T> The type of data this producer returns through {@link #getData()}.
- */
-public final class PriorityDataProducer<T> extends BaseDataProducer<T> {
- private final List<DataProducer<T>> mChildProducers;
-
- public PriorityDataProducer(List<DataProducer<T>> childProducers) {
- mChildProducers = childProducers;
- for (DataProducer<T> childProducer : mChildProducers) {
- childProducer.addDataChangedCallback(this::notifyDataChanged);
- }
- }
-
- @Nullable
- @Override
- public Optional<T> getData() {
- for (DataProducer<T> childProducer : mChildProducers) {
- final Optional<T> data = childProducer.getData();
- if (data.isPresent()) {
- return data;
- }
- }
- return Optional.empty();
- }
-}
diff --git a/libs/WindowManager/Jetpack/tests/OWNERS b/libs/WindowManager/Jetpack/tests/OWNERS
index f2c3388023be..ac522b2dde10 100644
--- a/libs/WindowManager/Jetpack/tests/OWNERS
+++ b/libs/WindowManager/Jetpack/tests/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 909476
+# Bug component: 1157642
# includes OWNERS from parent directories
charlesccchen@google.com
diegovela@google.com
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
new file mode 100644
index 000000000000..26463c18b9a0
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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 androidx.window.extensions.embedding;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Test class for {@link JetpackTaskFragmentOrganizer}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:JetpackTaskFragmentOrganizerTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class JetpackTaskFragmentOrganizerTest {
+ private static final int TASK_ID = 10;
+
+ @Mock
+ private JetpackTaskFragmentOrganizer.TaskFragmentCallback mCallback;
+ private JetpackTaskFragmentOrganizer mOrganizer;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mOrganizer = new JetpackTaskFragmentOrganizer(Runnable::run, mCallback);
+ mOrganizer.registerOrganizer();
+ spyOn(mOrganizer);
+ }
+
+ @Test
+ public void testUnregisterOrganizer() {
+ mOrganizer.startOverrideSplitAnimation(TASK_ID);
+ mOrganizer.startOverrideSplitAnimation(TASK_ID + 1);
+ mOrganizer.unregisterOrganizer();
+
+ verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
+ verify(mOrganizer).unregisterRemoteAnimations(TASK_ID + 1);
+ }
+
+ @Test
+ public void testStartOverrideSplitAnimation() {
+ assertNull(mOrganizer.mAnimationController);
+
+ mOrganizer.startOverrideSplitAnimation(TASK_ID);
+
+ assertNotNull(mOrganizer.mAnimationController);
+ verify(mOrganizer).registerRemoteAnimations(TASK_ID,
+ mOrganizer.mAnimationController.mDefinition);
+ }
+
+ @Test
+ public void testStopOverrideSplitAnimation() {
+ mOrganizer.stopOverrideSplitAnimation(TASK_ID);
+
+ verify(mOrganizer, never()).unregisterRemoteAnimations(anyInt());
+
+ mOrganizer.startOverrideSplitAnimation(TASK_ID);
+ mOrganizer.stopOverrideSplitAnimation(TASK_ID);
+
+ verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
+ }
+}
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 30e89a6524c7..120c7ebfe2da 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
@@ -31,6 +31,12 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+/**
+ * Test class for {@link SplitController}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:SplitController
+ */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class SplitControllerTest {
@@ -46,7 +52,7 @@ public class SplitControllerTest {
@Test
public void testGetTopActiveContainer() {
- TaskContainer taskContainer = new TaskContainer();
+ TaskContainer taskContainer = new TaskContainer(TASK_ID);
// tf3 is finished so is not active.
TaskFragmentContainer tf3 = mock(TaskFragmentContainer.class);
doReturn(true).when(tf3).isFinished();
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java
new file mode 100644
index 000000000000..7f88f4e7ff2e
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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 androidx.window.extensions.embedding;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+
+import android.window.TaskFragmentOrganizer;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Test class for {@link TaskFragmentAnimationController}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:TaskFragmentAnimationControllerTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TaskFragmentAnimationControllerTest {
+ private static final int TASK_ID = 10;
+
+ @Mock
+ private TaskFragmentOrganizer mOrganizer;
+ private TaskFragmentAnimationController mAnimationController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mAnimationController = new TaskFragmentAnimationController(mOrganizer);
+ }
+
+ @Test
+ public void testRegisterRemoteAnimations() {
+ mAnimationController.registerRemoteAnimations(TASK_ID);
+
+ verify(mOrganizer).registerRemoteAnimations(TASK_ID, mAnimationController.mDefinition);
+
+ mAnimationController.registerRemoteAnimations(TASK_ID);
+
+ // No extra call if it has been registered.
+ verify(mOrganizer).registerRemoteAnimations(TASK_ID, mAnimationController.mDefinition);
+ }
+
+ @Test
+ public void testUnregisterRemoteAnimations() {
+ mAnimationController.unregisterRemoteAnimations(TASK_ID);
+
+ // No call if it is not registered.
+ verify(mOrganizer, never()).unregisterRemoteAnimations(anyInt());
+
+ mAnimationController.registerRemoteAnimations(TASK_ID);
+ mAnimationController.unregisterRemoteAnimations(TASK_ID);
+
+ verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
+
+ mAnimationController.unregisterRemoteAnimations(TASK_ID);
+
+ // No extra call if it has been unregistered.
+ verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
+ }
+
+ @Test
+ public void testUnregisterAllRemoteAnimations() {
+ mAnimationController.registerRemoteAnimations(TASK_ID);
+ mAnimationController.registerRemoteAnimations(TASK_ID + 1);
+ mAnimationController.unregisterAllRemoteAnimations();
+
+ verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
+ verify(mOrganizer).unregisterRemoteAnimations(TASK_ID + 1);
+ }
+}
diff --git a/libs/WindowManager/Shell/res/drawable/home_icon.xml b/libs/WindowManager/Shell/res/drawable/home_icon.xml
new file mode 100644
index 000000000000..1669d0167e4b
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/home_icon.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:gravity="center">
+ <item android:gravity="center">
+ <shape
+ android:shape="oval">
+ <stroke
+ android:color="@color/tv_pip_edu_text_home_icon"
+ android:width="1sp" />
+ <solid android:color="@android:color/transparent" />
+ <size
+ android:width="@dimen/pip_menu_edu_text_home_icon_outline"
+ android:height="@dimen/pip_menu_edu_text_home_icon_outline"/>
+ </shape>
+ </item>
+ <item
+ android:width="@dimen/pip_menu_edu_text_home_icon"
+ android:height="@dimen/pip_menu_edu_text_home_icon"
+ android:gravity="center">
+ <vector
+ android:width="24sp"
+ android:height="24sp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/tv_pip_edu_text_home_icon"
+ android:pathData="M12,3L4,9v12h5v-7h6v7h5V9z"/>
+ </vector>
+ </item>
+</layer-list>
diff --git a/libs/WindowManager/Shell/res/drawable/tv_pip_menu_background.xml b/libs/WindowManager/Shell/res/drawable/tv_pip_menu_background.xml
new file mode 100644
index 000000000000..0c627921573c
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/tv_pip_menu_background.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="@dimen/pip_menu_background_corner_radius" />
+ <solid android:color="@color/tv_pip_menu_background"/>
+ <stroke android:width="@dimen/pip_menu_border_width"
+ android:color="@color/tv_pip_menu_background"/>
+</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml b/libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml
index 9bc03112b118..846fdb3e8a58 100644
--- a/libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml
+++ b/libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml
@@ -14,9 +14,20 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <corners android:radius="@dimen/pip_menu_border_radius" />
- <stroke android:width="@dimen/pip_menu_border_width"
- android:color="@color/tv_pip_menu_focus_border" />
-</shape> \ No newline at end of file
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@integer/pip_menu_fade_animation_duration">
+ <item android:state_activated="true">
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/pip_menu_border_corner_radius" />
+ <stroke android:width="@dimen/pip_menu_border_width"
+ android:color="@color/tv_pip_menu_focus_border" />
+ </shape>
+ </item>
+ <item>
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/pip_menu_border_corner_radius" />
+ <stroke android:width="@dimen/pip_menu_border_width"
+ android:color="@color/tv_pip_menu_background"/>
+ </shape>
+ </item>
+</selector>
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
index b826d03bf765..dbd5a9b370ab 100644
--- a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
@@ -16,26 +16,41 @@
-->
<!-- Layout for TvPipMenuView -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/tv_pip_menu"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:id="@+id/tv_pip_menu"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center|top">
+
+ <View
+ android:id="@+id/tv_pip"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="@dimen/pip_menu_outer_space"
+ android:layout_marginStart="@dimen/pip_menu_outer_space"
+ android:layout_marginEnd="@dimen/pip_menu_outer_space"/>
<ScrollView
android:id="@+id/tv_pip_menu_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
+ android:layout_alignTop="@+id/tv_pip"
+ android:layout_alignStart="@+id/tv_pip"
+ android:layout_alignEnd="@+id/tv_pip"
+ android:layout_alignBottom="@+id/tv_pip"
android:scrollbars="none"
- android:layout_margin="@dimen/pip_menu_outer_space"
android:visibility="gone"/>
<HorizontalScrollView
android:id="@+id/tv_pip_menu_horizontal_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_alignTop="@+id/tv_pip"
+ android:layout_alignStart="@+id/tv_pip"
+ android:layout_alignEnd="@+id/tv_pip"
+ android:layout_alignBottom="@+id/tv_pip"
android:gravity="center_vertical"
- android:scrollbars="none"
- android:layout_margin="@dimen/pip_menu_outer_space">
+ android:scrollbars="none">
<LinearLayout
android:id="@+id/tv_pip_menu_action_buttons"
@@ -89,10 +104,44 @@
</HorizontalScrollView>
<View
+ android:id="@+id/tv_pip_border"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="@dimen/pip_menu_outer_space_frame"
+ android:layout_marginStart="@dimen/pip_menu_outer_space_frame"
+ android:layout_marginEnd="@dimen/pip_menu_outer_space_frame"
+ android:background="@drawable/tv_pip_menu_border"/>
+
+ <FrameLayout
+ android:id="@+id/tv_pip_menu_edu_text_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@+id/tv_pip"
+ android:layout_alignBottom="@+id/tv_pip_menu_frame"
+ android:layout_alignStart="@+id/tv_pip"
+ android:layout_alignEnd="@+id/tv_pip"
+ android:background="@color/tv_pip_menu_background"
+ android:clipChildren="true">
+
+ <TextView
+ android:id="@+id/tv_pip_menu_edu_text"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/pip_menu_edu_text_view_height"
+ android:layout_gravity="bottom|center"
+ android:gravity="center"
+ android:paddingBottom="@dimen/pip_menu_border_width"
+ android:text="@string/pip_edu_text"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:marqueeRepeatLimit="1"
+ android:scrollHorizontally="true"
+ android:textAppearance="@style/TvPipEduText"/>
+ </FrameLayout>
+
+ <View
android:id="@+id/tv_pip_menu_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:alpha="0"
android:layout_margin="@dimen/pip_menu_outer_space_frame"
android:background="@drawable/tv_pip_menu_border"/>
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_menu_background.xml b/libs/WindowManager/Shell/res/layout/tv_pip_menu_background.xml
new file mode 100644
index 000000000000..5af40200d240
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_menu_background.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<!-- Layout for the back surface of the PiP menu -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="@dimen/pip_menu_outer_space_frame"
+ android:background="@drawable/tv_pip_menu_background"
+ android:elevation="@dimen/pip_menu_elevation"/>
+</FrameLayout>
+
diff --git a/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml b/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml
index 558ec51752b9..776b18ecc01b 100644
--- a/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml
+++ b/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml
@@ -22,7 +22,12 @@
<dimen name="pip_menu_button_margin">4dp</dimen>
<dimen name="pip_menu_button_wrapper_margin">26dp</dimen>
<dimen name="pip_menu_border_width">4dp</dimen>
- <dimen name="pip_menu_border_radius">4dp</dimen>
+ <integer name="pip_menu_fade_animation_duration">500</integer>
+ <!-- The pip menu front border corner radius is 2dp smaller than
+ the background corner radius to hide the background from
+ showing through. -->
+ <dimen name="pip_menu_border_corner_radius">4dp</dimen>
+ <dimen name="pip_menu_background_corner_radius">6dp</dimen>
<dimen name="pip_menu_outer_space">24dp</dimen>
<!-- outer space minus border width -->
@@ -30,5 +35,14 @@
<dimen name="pip_menu_arrow_size">24dp</dimen>
<dimen name="pip_menu_arrow_elevation">5dp</dimen>
+
+ <dimen name="pip_menu_elevation">1dp</dimen>
+
+ <dimen name="pip_menu_edu_text_view_height">24dp</dimen>
+ <dimen name="pip_menu_edu_text_home_icon">9sp</dimen>
+ <dimen name="pip_menu_edu_text_home_icon_outline">14sp</dimen>
+ <integer name="pip_edu_text_show_duration_ms">10500</integer>
+ <integer name="pip_edu_text_window_exit_animation_duration_ms">1000</integer>
+ <integer name="pip_edu_text_view_exit_animation_duration_ms">300</integer>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/colors_tv.xml b/libs/WindowManager/Shell/res/values/colors_tv.xml
index 64b146ec3a83..fa90fe36b545 100644
--- a/libs/WindowManager/Shell/res/values/colors_tv.xml
+++ b/libs/WindowManager/Shell/res/values/colors_tv.xml
@@ -23,4 +23,8 @@
<color name="tv_pip_menu_icon_bg_focused">#E8EAED</color>
<color name="tv_pip_menu_icon_bg_unfocused">#990E0E0F</color>
<color name="tv_pip_menu_focus_border">#E8EAED</color>
-</resources> \ No newline at end of file
+ <color name="tv_pip_menu_background">#1E232C</color>
+
+ <color name="tv_pip_edu_text">#99D2E3FC</color>
+ <color name="tv_pip_edu_text_home_icon">#D2E3FC</color>
+</resources>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 7733201d2465..19f7c3ef4364 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -47,4 +47,13 @@
<item name="android:layout_width">96dp</item>
<item name="android:layout_height">48dp</item>
</style>
+
+ <style name="TvPipEduText">
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
+ <item name="android:textAllCaps">true</item>
+ <item name="android:textSize">10sp</item>
+ <item name="android:lineSpacingExtra">4sp</item>
+ <item name="android:lineHeight">16sp</item>
+ <item name="android:textColor">@color/tv_pip_edu_text</item>
+ </style>
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
index b729fe1e55dc..62fb840d29d1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
@@ -35,6 +35,7 @@ import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.startingsurface.StartingWindowController;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.unfold.UnfoldTransitionHandler;
import java.util.Optional;
@@ -56,6 +57,7 @@ public class ShellInitImpl {
private final Optional<PipTouchHandler> mPipTouchHandlerOptional;
private final FullscreenTaskListener mFullscreenTaskListener;
private final Optional<FullscreenUnfoldController> mFullscreenUnfoldController;
+ private final Optional<UnfoldTransitionHandler> mUnfoldTransitionHandler;
private final Optional<FreeformTaskListener> mFreeformTaskListenerOptional;
private final ShellExecutor mMainExecutor;
private final Transitions mTransitions;
@@ -77,6 +79,7 @@ public class ShellInitImpl {
Optional<PipTouchHandler> pipTouchHandlerOptional,
FullscreenTaskListener fullscreenTaskListener,
Optional<FullscreenUnfoldController> fullscreenUnfoldTransitionController,
+ Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
Optional<FreeformTaskListener> freeformTaskListenerOptional,
Optional<RecentTasksController> recentTasks,
Transitions transitions,
@@ -94,6 +97,7 @@ public class ShellInitImpl {
mFullscreenTaskListener = fullscreenTaskListener;
mPipTouchHandlerOptional = pipTouchHandlerOptional;
mFullscreenUnfoldController = fullscreenUnfoldTransitionController;
+ mUnfoldTransitionHandler = unfoldTransitionHandler;
mFreeformTaskListenerOptional = freeformTaskListenerOptional;
mRecentTasks = recentTasks;
mTransitions = transitions;
@@ -126,6 +130,7 @@ public class ShellInitImpl {
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
mTransitions.register(mShellTaskOrganizer);
+ mUnfoldTransitionHandler.ifPresent(UnfoldTransitionHandler::init);
}
// TODO(b/181599115): This should really be the pip controller, but until we can provide the
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 93ee3f5378e8..577ced53f992 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -19,9 +19,6 @@ package com.android.wm.shell.back;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
@@ -223,14 +220,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
private void initAnimation(MotionEvent event) {
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "initAnimation mMotionStarted=%b", mBackGestureStarted);
- if (mBackGestureStarted) {
+ if (mBackGestureStarted || mBackNavigationInfo != null) {
Log.e(TAG, "Animation is being initialized but is already started.");
- return;
- }
-
- if (mBackNavigationInfo != null) {
finishAnimation();
}
+
mInitTouchLocation.set(event.getX(), event.getY());
mBackGestureStarted = true;
@@ -304,8 +298,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
return;
}
int deltaX = Math.round(event.getX() - mInitTouchLocation.x);
- int deltaY = Math.round(event.getY() - mInitTouchLocation.y);
- ProtoLog.v(WM_SHELL_BACK_PREVIEW, "Runner move: %d %d", deltaX, deltaY);
float progressThreshold = PROGRESS_THRESHOLD >= 0 ? PROGRESS_THRESHOLD : mProgressThreshold;
float progress = Math.min(Math.max(Math.abs(deltaX) / progressThreshold, 0), 1);
int backType = mBackNavigationInfo.getType();
@@ -317,11 +309,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
targetCallback = mBackToLauncherCallback;
} else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
|| backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
- if (animationTarget != null) {
- mTransaction.setPosition(animationTarget.leash, deltaX, deltaY);
- mTouchEventDelta.set(deltaX, deltaY);
- mTransaction.apply();
- }
+ // TODO(208427216) Run the actual animation
} else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
}
@@ -343,19 +331,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
} else {
dispatchOnBackCancelled(targetCallback);
}
- if (backType == BackNavigationInfo.TYPE_CALLBACK) {
- finishAnimation();
- } else if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
- && !shouldDispatchToLauncher) {
+ if (backType != BackNavigationInfo.TYPE_RETURN_TO_HOME || !shouldDispatchToLauncher) {
// Launcher callback missing. Simply finish animation.
finishAnimation();
- } else if (backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY
- || backType == BackNavigationInfo.TYPE_CROSS_TASK) {
- if (mTriggerBack) {
- prepareTransition();
- } else {
- resetPositionAnimated();
- }
}
}
@@ -403,8 +381,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
}
- private static void dispatchOnBackProgressed(
- IOnBackInvokedCallback callback, BackEvent backEvent) {
+ private static void dispatchOnBackProgressed(IOnBackInvokedCallback callback,
+ BackEvent backEvent) {
if (callback == null) {
return;
}
@@ -416,48 +394,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
/**
- * Animate the top window leash to its initial position.
- */
- private void resetPositionAnimated() {
- mBackGestureStarted = false;
- // TODO(208786853) Handle overlap with a new coming gesture.
- ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Runner: Back not triggered, cancelling animation "
- + "mLastPos=%s mInitTouch=%s", mTouchEventDelta, mInitTouchLocation);
-
- // TODO(208427216) : Replace placeholder animation with an actual one.
- ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f).setDuration(200);
- animation.addUpdateListener(animation1 -> {
- if (mBackNavigationInfo == null) {
- return;
- }
- float fraction = animation1.getAnimatedFraction();
- int deltaX = Math.round(mTouchEventDelta.x - (mTouchEventDelta.x * fraction));
- int deltaY = Math.round(mTouchEventDelta.y - (mTouchEventDelta.y * fraction));
- RemoteAnimationTarget animationTarget =
- mBackNavigationInfo.getDepartingAnimationTarget();
- if (animationTarget != null) {
- mTransaction.setPosition(animationTarget.leash, deltaX, deltaY);
- mTransaction.apply();
- }
- });
-
- animation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: onAnimationEnd");
- finishAnimation();
- }
- });
- animation.start();
- }
-
- private void prepareTransition() {
- ProtoLog.d(WM_SHELL_BACK_PREVIEW, "prepareTransition()");
- mTriggerBack = false;
- mBackGestureStarted = false;
- }
-
- /**
* Sets to true when the back gesture has passed the triggering threshold, false otherwise.
*/
public void setTriggerBack(boolean triggerBack) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index a7052bc49699..3b83f1586d8c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -40,7 +40,6 @@ import android.view.WindowInsets;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
-import androidx.annotation.BinderThread;
import androidx.annotation.VisibleForTesting;
import com.android.internal.view.IInputMethodManager;
@@ -325,7 +324,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
}
@Override
- public void topFocusedWindowChanged(String packageName) {
+ public void topFocusedWindowChanged(String packageName,
+ InsetsVisibilities requestedVisibilities) {
// Do nothing
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
index 565f1481233c..b6705446674a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
@@ -23,6 +23,7 @@ import android.view.IDisplayWindowInsetsController;
import android.view.IWindowManager;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.view.InsetsVisibilities;
import androidx.annotation.BinderThread;
@@ -170,13 +171,14 @@ public class DisplayInsetsController implements DisplayController.OnDisplaysChan
}
}
- private void topFocusedWindowChanged(String packageName) {
+ private void topFocusedWindowChanged(String packageName,
+ InsetsVisibilities requestedVisibilities) {
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
if (listeners == null) {
return;
}
for (OnInsetsChangedListener listener : listeners) {
- listener.topFocusedWindowChanged(packageName);
+ listener.topFocusedWindowChanged(packageName, requestedVisibilities);
}
}
@@ -184,9 +186,10 @@ public class DisplayInsetsController implements DisplayController.OnDisplaysChan
private class DisplayWindowInsetsControllerImpl
extends IDisplayWindowInsetsController.Stub {
@Override
- public void topFocusedWindowChanged(String packageName) throws RemoteException {
+ public void topFocusedWindowChanged(String packageName,
+ InsetsVisibilities requestedVisibilities) throws RemoteException {
mMainExecutor.execute(() -> {
- PerDisplay.this.topFocusedWindowChanged(packageName);
+ PerDisplay.this.topFocusedWindowChanged(packageName, requestedVisibilities);
});
}
@@ -231,9 +234,11 @@ public class DisplayInsetsController implements DisplayController.OnDisplaysChan
/**
* Called when top focused window changes to determine whether or not to take over insets
* control. Won't be called if config_remoteInsetsControllerControlsSystemBars is false.
- * @param packageName: Passes the top package name
+ * @param packageName The name of the package that is open in the top focussed window.
+ * @param requestedVisibilities The insets visibilities requested by the focussed window.
*/
- default void topFocusedWindowChanged(String packageName) {}
+ default void topFocusedWindowChanged(String packageName,
+ InsetsVisibilities requestedVisibilities) {}
/**
* Called when the window insets configuration has changed.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 026eeb09d741..4ad08688bd51 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -92,6 +92,7 @@ import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelperController;
import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
+import com.android.wm.shell.unfold.UnfoldTransitionHandler;
import java.util.Optional;
@@ -327,6 +328,21 @@ public abstract class WMShellBaseModule {
return Optional.empty();
}
+ @WMSingleton
+ @Provides
+ static Optional<UnfoldTransitionHandler> provideUnfoldTransitionHandler(
+ Optional<ShellUnfoldProgressProvider> progressProvider,
+ TransactionPool transactionPool,
+ Transitions transitions,
+ @ShellMainThread ShellExecutor executor) {
+ if (progressProvider.isPresent()) {
+ return Optional.of(
+ new UnfoldTransitionHandler(progressProvider.get(), transactionPool, executor,
+ transitions));
+ }
+ return Optional.empty();
+ }
+
//
// Freeform (optional feature)
//
@@ -660,6 +676,7 @@ public abstract class WMShellBaseModule {
Optional<PipTouchHandler> pipTouchHandlerOptional,
FullscreenTaskListener fullscreenTaskListener,
Optional<FullscreenUnfoldController> appUnfoldTransitionController,
+ Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
Optional<FreeformTaskListener> freeformTaskListener,
Optional<RecentTasksController> recentTasksOptional,
Transitions transitions,
@@ -677,6 +694,7 @@ public abstract class WMShellBaseModule {
pipTouchHandlerOptional,
fullscreenTaskListener,
appUnfoldTransitionController,
+ unfoldTransitionHandler,
freeformTaskListener,
recentTasksOptional,
transitions,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 51e229e13284..337900088c92 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -432,6 +432,11 @@ public class PipAnimationController {
return !isOutPipDirection(mTransitionDirection);
}
+ boolean shouldApplyShadowRadius() {
+ return !isOutPipDirection(mTransitionDirection)
+ && !isRemovePipDirection(mTransitionDirection);
+ }
+
boolean inScaleTransition() {
if (mAnimationType != ANIM_TYPE_BOUNDS) return false;
final int direction = getTransitionDirection();
@@ -483,7 +488,7 @@ public class PipAnimationController {
setCurrentValue(alpha);
getSurfaceTransactionHelper().alpha(tx, leash, alpha)
.round(tx, leash, shouldApplyCornerRadius())
- .shadow(tx, leash);
+ .shadow(tx, leash, shouldApplyShadowRadius());
tx.apply();
}
@@ -497,7 +502,7 @@ public class PipAnimationController {
.resetScale(tx, leash, getDestinationBounds())
.crop(tx, leash, getDestinationBounds())
.round(tx, leash, shouldApplyCornerRadius())
- .shadow(tx, leash);
+ .shadow(tx, leash, shouldApplyShadowRadius());
tx.show(leash);
tx.apply();
}
@@ -585,7 +590,7 @@ public class PipAnimationController {
getSurfaceTransactionHelper().crop(tx, leash, base)
.scale(tx, leash, base, bounds, angle)
.round(tx, leash, base, bounds)
- .shadow(tx, leash);
+ .shadow(tx, leash, shouldApplyShadowRadius());
}
} else {
final Rect insets = computeInsets(fraction);
@@ -596,7 +601,7 @@ public class PipAnimationController {
sourceBounds.inset(insets);
getSurfaceTransactionHelper()
.round(tx, leash, sourceBounds, bounds)
- .shadow(tx, leash);
+ .shadow(tx, leash, shouldApplyShadowRadius());
}
}
if (!handlePipTransaction(leash, tx, bounds)) {
@@ -649,7 +654,7 @@ public class PipAnimationController {
if (shouldApplyCornerRadius()) {
getSurfaceTransactionHelper()
.round(tx, leash, sourceBounds, bounds)
- .shadow(tx, leash);
+ .shadow(tx, leash, shouldApplyShadowRadius());
}
tx.apply();
}
@@ -668,7 +673,7 @@ public class PipAnimationController {
getSurfaceTransactionHelper()
.alpha(tx, leash, 1f)
.round(tx, leash, shouldApplyCornerRadius())
- .shadow(tx, leash);
+ .shadow(tx, leash, shouldApplyShadowRadius());
// TODO(b/178632364): this is a work around for the black background when
// entering PiP in buttion navigation mode.
if (isInPipDirection(direction)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
index 7447fb54d636..00f62d435b68 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -206,8 +206,9 @@ public class PipSurfaceTransactionHelper {
* Operates the shadow radius on a given transaction and leash
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
- public PipSurfaceTransactionHelper shadow(SurfaceControl.Transaction tx, SurfaceControl leash) {
- tx.setShadowRadius(leash, mShadowRadius);
+ public PipSurfaceTransactionHelper shadow(SurfaceControl.Transaction tx, SurfaceControl leash,
+ boolean applyShadowRadius) {
+ tx.setShadowRadius(leash, applyShadowRadius ? mShadowRadius : 0);
return this;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/CenteredImageSpan.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/CenteredImageSpan.java
new file mode 100644
index 000000000000..6efdd57bdc48
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/CenteredImageSpan.java
@@ -0,0 +1,76 @@
+/*
+ * 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.wm.shell.pip.tv;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.style.ImageSpan;
+
+/** An ImageSpan for a Drawable that is centered vertically in the line. */
+public class CenteredImageSpan extends ImageSpan {
+
+ private Drawable mDrawable;
+
+ public CenteredImageSpan(Drawable drawable) {
+ super(drawable);
+ }
+
+ @Override
+ public int getSize(
+ Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fontMetrics) {
+ final Drawable drawable = getCachedDrawable();
+ final Rect rect = drawable.getBounds();
+
+ if (fontMetrics != null) {
+ Paint.FontMetricsInt paintFontMetrics = paint.getFontMetricsInt();
+ fontMetrics.ascent = paintFontMetrics.ascent;
+ fontMetrics.descent = paintFontMetrics.descent;
+ fontMetrics.top = paintFontMetrics.top;
+ fontMetrics.bottom = paintFontMetrics.bottom;
+ }
+
+ return rect.right;
+ }
+
+ @Override
+ public void draw(
+ Canvas canvas,
+ CharSequence text,
+ int start,
+ int end,
+ float x,
+ int top,
+ int y,
+ int bottom,
+ Paint paint) {
+ final Drawable drawable = getCachedDrawable();
+ canvas.save();
+ final int transY = (bottom - drawable.getBounds().bottom) / 2;
+ canvas.translate(x, transY);
+ drawable.draw(canvas);
+ canvas.restore();
+ }
+
+ private Drawable getCachedDrawable() {
+ if (mDrawable == null) {
+ mDrawable = getDrawable();
+ }
+ return mDrawable;
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
index 1aefd77419aa..21d5d401835d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
@@ -27,6 +27,7 @@ import static com.android.wm.shell.pip.tv.TvPipBoundsState.ORIENTATION_VERTICAL;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.os.SystemClock;
import android.util.ArraySet;
@@ -150,6 +151,10 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm {
mKeepClearAlgorithm.setScreenSize(screenSize);
mKeepClearAlgorithm.setMovementBounds(insetBounds);
mKeepClearAlgorithm.setStashOffset(mTvPipBoundsState.getStashOffset());
+ mKeepClearAlgorithm.setPipPermanentDecorInsets(
+ mTvPipBoundsState.getPipMenuPermanentDecorInsets());
+ mKeepClearAlgorithm.setPipTemporaryDecorInsets(
+ mTvPipBoundsState.getPipMenuTemporaryDecorInsets());
final Placement placement = mKeepClearAlgorithm.calculatePipPosition(
pipSize,
@@ -340,6 +345,7 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm {
final DisplayLayout displayLayout = mTvPipBoundsState.getDisplayLayout();
final float expandedRatio =
mTvPipBoundsState.getDesiredTvExpandedAspectRatio(); // width / height
+ final Insets pipDecorations = mTvPipBoundsState.getPipMenuPermanentDecorInsets();
final Size expandedSize;
if (expandedRatio == 0) {
@@ -352,7 +358,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm {
if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_HORIZONTAL) {
expandedSize = mTvPipBoundsState.getTvExpandedSize();
} else {
- int maxHeight = displayLayout.height() - (2 * mScreenEdgeInsets.y);
+ int maxHeight = displayLayout.height() - (2 * mScreenEdgeInsets.y)
+ - pipDecorations.top - pipDecorations.bottom;
float aspectRatioHeight = mFixedExpandedWidthInPx / expandedRatio;
if (maxHeight > aspectRatioHeight) {
@@ -374,7 +381,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm {
if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_VERTICAL) {
expandedSize = mTvPipBoundsState.getTvExpandedSize();
} else {
- int maxWidth = displayLayout.width() - (2 * mScreenEdgeInsets.x);
+ int maxWidth = displayLayout.width() - (2 * mScreenEdgeInsets.x)
+ - pipDecorations.left - pipDecorations.right;
float aspectRatioWidth = mFixedExpandedHeightInPx * expandedRatio;
if (maxWidth > aspectRatioWidth) {
if (DEBUG) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
index 986554853034..ea074993bae1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
@@ -24,6 +24,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.graphics.Insets;
import android.util.Size;
import android.view.Gravity;
@@ -60,7 +61,8 @@ public class TvPipBoundsState extends PipBoundsState {
private @Orientation int mTvFixedPipOrientation;
private int mTvPipGravity;
private @Nullable Size mTvExpandedSize;
-
+ private @NonNull Insets mPipMenuPermanentDecorInsets = Insets.NONE;
+ private @NonNull Insets mPipMenuTemporaryDecorInsets = Insets.NONE;
public TvPipBoundsState(@NonNull Context context) {
super(context);
@@ -159,4 +161,19 @@ public class TvPipBoundsState extends PipBoundsState {
return mIsTvExpandedPipSupported;
}
+ public void setPipMenuPermanentDecorInsets(@NonNull Insets permanentInsets) {
+ mPipMenuPermanentDecorInsets = permanentInsets;
+ }
+
+ public @NonNull Insets getPipMenuPermanentDecorInsets() {
+ return mPipMenuPermanentDecorInsets;
+ }
+
+ public void setPipMenuTemporaryDecorInsets(@NonNull Insets temporaryDecorInsets) {
+ mPipMenuTemporaryDecorInsets = temporaryDecorInsets;
+ }
+
+ public @NonNull Insets getPipMenuTemporaryDecorInsets() {
+ return mPipMenuTemporaryDecorInsets;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 46b8e6098273..0e1f5a24f4a7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -115,6 +115,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
private int mPipForceCloseDelay;
private int mResizeAnimationDuration;
+ private int mEduTextWindowExitAnimationDurationMs;
public static Pip create(
Context context,
@@ -323,11 +324,15 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
}
}
+ private void updatePinnedStackBounds() {
+ updatePinnedStackBounds(mResizeAnimationDuration);
+ }
+
/**
* Update the PiP bounds based on the state of the PiP and keep clear areas.
* Animates to the current PiP bounds, and schedules unstashing the PiP if necessary.
*/
- private void updatePinnedStackBounds() {
+ private void updatePinnedStackBounds(int animationDuration) {
if (mState == STATE_NO_PIP) {
return;
}
@@ -353,23 +358,26 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
mUnstashRunnable = null;
}
if (!disallowStashing && placement.getUnstashDestinationBounds() != null) {
- mUnstashRunnable = () -> movePinnedStackTo(placement.getUnstashDestinationBounds());
+ mUnstashRunnable = () -> {
+ movePinnedStackTo(placement.getUnstashDestinationBounds(), animationDuration);
+ };
mMainHandler.postAtTime(mUnstashRunnable, placement.getUnstashTime());
}
}
/** Animates the PiP to the given bounds. */
private void movePinnedStackTo(Rect bounds) {
+ movePinnedStackTo(bounds, mResizeAnimationDuration);
+ }
+
+ /** Animates the PiP to the given bounds with the given animation duration. */
+ private void movePinnedStackTo(Rect bounds, int animationDuration) {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: movePinnedStack() - new pip bounds: %s", TAG, bounds.toShortString());
}
mPipTaskOrganizer.scheduleAnimateResizePip(bounds,
- mResizeAnimationDuration, rect -> {
- if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: movePinnedStack() animation done", TAG);
- }
+ animationDuration, rect -> {
mTvPipMenuController.updateExpansionState();
});
}
@@ -408,6 +416,11 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
onPipDisappeared();
}
+ @Override
+ public void closeEduText() {
+ updatePinnedStackBounds(mEduTextWindowExitAnimationDurationMs);
+ }
+
private void registerSessionListenerForCurrentUser() {
mPipMediaController.registerSessionListenerForCurrentUser();
}
@@ -457,6 +470,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: onPipTransition_Started(), state=%s", TAG, stateToName(mState));
}
+ mTvPipMenuController.notifyPipAnimating(true);
}
@Override
@@ -465,6 +479,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: onPipTransition_Canceled(), state=%s", TAG, stateToName(mState));
}
+ mTvPipMenuController.notifyPipAnimating(false);
}
@Override
@@ -476,6 +491,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: onPipTransition_Finished(), state=%s", TAG, stateToName(mState));
}
+ mTvPipMenuController.notifyPipAnimating(false);
}
private void setState(@State int state) {
@@ -491,6 +507,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
final Resources res = mContext.getResources();
mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration);
mPipForceCloseDelay = res.getInteger(R.integer.config_pipForceCloseDelay);
+ mEduTextWindowExitAnimationDurationMs =
+ res.getInteger(R.integer.pip_edu_text_window_exit_animation_duration_ms);
}
private void registerTaskStackListenerCallback(TaskStackListenerImpl taskStackListener) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
index 5ac7a7200494..9ede4433a978 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.pip.tv
+import android.graphics.Insets
import android.graphics.Point
import android.graphics.Rect
import android.util.Size
@@ -94,6 +95,13 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) {
private var lastAreasOverlappingUnstashPosition: Set<Rect> = emptySet()
private var lastStashTime: Long = Long.MIN_VALUE
+ /** Spaces around the PiP that we should leave space for when placing the PiP. Permanent PiP
+ * decorations are relevant for calculating intersecting keep clear areas */
+ private var pipPermanentDecorInsets = Insets.NONE
+ /** Spaces around the PiP that we should leave space for when placing the PiP. Temporary PiP
+ * decorations are not relevant for calculating intersecting keep clear areas */
+ private var pipTemporaryDecorInsets = Insets.NONE
+
/**
* Calculates the position the PiP should be placed at, taking into consideration the
* given keep clear areas.
@@ -120,20 +128,29 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) {
): Placement {
val transformedRestrictedAreas = transformAndFilterAreas(restrictedAreas)
val transformedUnrestrictedAreas = transformAndFilterAreas(unrestrictedAreas)
- val pipAnchorBounds = getNormalPipAnchorBounds(pipSize, transformedMovementBounds)
+ val pipSizeWithAllDecors = addDecors(pipSize)
+ val pipAnchorBoundsWithAllDecors =
+ getNormalPipAnchorBounds(pipSizeWithAllDecors, transformedMovementBounds)
+
+ val pipAnchorBoundsWithPermanentDecors = removeTemporaryDecors(pipAnchorBoundsWithAllDecors)
val result = calculatePipPositionTransformed(
- pipAnchorBounds,
+ pipAnchorBoundsWithPermanentDecors,
transformedRestrictedAreas,
transformedUnrestrictedAreas
)
- val screenSpaceBounds = fromTransformedSpace(result.bounds)
+ val pipBounds = removePermanentDecors(fromTransformedSpace(result.bounds))
+ val anchorBounds = removePermanentDecors(fromTransformedSpace(result.anchorBounds))
+ val unstashedDestBounds = result.unstashDestinationBounds?.let {
+ removePermanentDecors(fromTransformedSpace(it))
+ }
+
return Placement(
- screenSpaceBounds,
- fromTransformedSpace(result.anchorBounds),
- getStashType(screenSpaceBounds, movementBounds),
- result.unstashDestinationBounds?.let { fromTransformedSpace(it) },
+ pipBounds,
+ anchorBounds,
+ getStashType(pipBounds, movementBounds),
+ unstashedDestBounds,
result.unstashTime
)
}
@@ -447,6 +464,16 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) {
transformedMovementBounds = toTransformedSpace(movementBounds)
}
+ fun setPipPermanentDecorInsets(insets: Insets) {
+ if (pipPermanentDecorInsets == insets) return
+ pipPermanentDecorInsets = insets
+ }
+
+ fun setPipTemporaryDecorInsets(insets: Insets) {
+ if (pipTemporaryDecorInsets == insets) return
+ pipTemporaryDecorInsets = insets
+ }
+
/**
* @param open Whether this event marks the opening of an occupied segment
* @param pos The coordinate of this event
@@ -735,6 +762,35 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) {
return horizontal && vertical
}
+ /**
+ * Adds space around [size] to leave space for decorations that will be drawn around the pip
+ */
+ private fun addDecors(size: Size): Size {
+ val bounds = Rect(0, 0, size.width, size.height)
+ bounds.inset(pipPermanentDecorInsets)
+ bounds.inset(pipTemporaryDecorInsets)
+
+ return Size(bounds.width(), bounds.height())
+ }
+
+ /**
+ * Removes the space that was reserved for permanent decorations around the pip
+ */
+ private fun removePermanentDecors(bounds: Rect): Rect {
+ val pipDecorReverseInsets = Insets.subtract(Insets.NONE, pipPermanentDecorInsets)
+ bounds.inset(pipDecorReverseInsets)
+ return bounds
+ }
+
+ /**
+ * Removes the space that was reserved for temporary decorations around the pip
+ */
+ private fun removeTemporaryDecors(bounds: Rect): Rect {
+ val pipDecorReverseInsets = Insets.subtract(Insets.NONE, pipTemporaryDecorInsets)
+ bounds.inset(pipDecorReverseInsets)
+ return bounds
+ }
+
private fun Rect.offsetCopy(dx: Int, dy: Int) = Rect(this).apply { offset(dx, dy) }
private fun Rect.intersectsY(other: Rect) = bottom >= other.top && top <= other.bottom
private fun Rect.intersectsX(other: Rect) = right >= other.left && left <= other.right
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index 35c34ac8315f..7b8dcf70cff0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -25,13 +25,17 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ParceledListSlice;
+import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.RemoteException;
+import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SyncRtSurfaceTransactionApplier;
+import android.view.View;
+import android.view.ViewRootImpl;
import android.view.WindowManagerGlobal;
import androidx.annotation.Nullable;
@@ -53,15 +57,20 @@ import java.util.Objects;
public class TvPipMenuController implements PipMenuController, TvPipMenuView.Listener {
private static final String TAG = "TvPipMenuController";
private static final boolean DEBUG = TvPipController.DEBUG;
+ private static final String BACKGROUND_WINDOW_TITLE = "PipBackgroundView";
private final Context mContext;
private final SystemWindows mSystemWindows;
private final TvPipBoundsState mTvPipBoundsState;
private final Handler mMainHandler;
+ private final int mPipMenuBorderWidth;
+ private final int mPipEduTextShowDurationMs;
+ private final int mPipEduTextHeight;
private Delegate mDelegate;
private SurfaceControl mLeash;
private TvPipMenuView mPipMenuView;
+ private View mPipBackgroundView;
// User can actively move the PiP via the DPAD.
private boolean mInMoveMode;
@@ -74,6 +83,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
private RemoteAction mCloseAction;
private SyncRtSurfaceTransactionApplier mApplier;
+ private SyncRtSurfaceTransactionApplier mBackgroundApplier;
RectF mTmpSourceRectF = new RectF();
RectF mTmpDestinationRectF = new RectF();
Matrix mMoveTransform = new Matrix();
@@ -91,6 +101,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
if (DEBUG) e.printStackTrace();
}
};
+ private final Runnable mCloseEduTextRunnable = this::closeEduText;
public TvPipMenuController(Context context, TvPipBoundsState tvPipBoundsState,
SystemWindows systemWindows, PipMediaController pipMediaController,
@@ -113,6 +124,13 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
mainHandler, Context.RECEIVER_EXPORTED);
pipMediaController.addActionListener(this::onMediaActionsChanged);
+
+ mPipEduTextShowDurationMs = context.getResources()
+ .getInteger(R.integer.pip_edu_text_show_duration_ms);
+ mPipEduTextHeight = context.getResources()
+ .getDimensionPixelSize(R.dimen.pip_menu_edu_text_view_height);
+ mPipMenuBorderWidth = context.getResources()
+ .getDimensionPixelSize(R.dimen.pip_menu_border_width);
}
void setDelegate(Delegate delegate) {
@@ -138,24 +156,63 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
}
mLeash = leash;
- attachPipMenuView();
+ attachPipMenu();
}
- private void attachPipMenuView() {
+ private void attachPipMenu() {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: attachPipMenuView()", TAG);
+ "%s: attachPipMenu()", TAG);
}
if (mPipMenuView != null) {
- detachPipMenuView();
+ detachPipMenu();
}
+ attachPipBackgroundView();
+ attachPipMenuView();
+
+ mTvPipBoundsState.setPipMenuPermanentDecorInsets(Insets.of(-mPipMenuBorderWidth,
+ -mPipMenuBorderWidth, -mPipMenuBorderWidth, -mPipMenuBorderWidth));
+ mTvPipBoundsState.setPipMenuTemporaryDecorInsets(Insets.of(0, 0, 0, -mPipEduTextHeight));
+ mMainHandler.postDelayed(mCloseEduTextRunnable, mPipEduTextShowDurationMs);
+ }
+
+ private void attachPipMenuView() {
mPipMenuView = new TvPipMenuView(mContext);
mPipMenuView.setListener(this);
- mSystemWindows.addView(mPipMenuView,
- getPipMenuLayoutParams(MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */),
- 0, SHELL_ROOT_LAYER_PIP);
+ setUpViewSurfaceZOrder(mPipMenuView, 1);
+ addPipMenuViewToSystemWindows(mPipMenuView, MENU_WINDOW_TITLE);
+ }
+
+ private void attachPipBackgroundView() {
+ mPipBackgroundView = LayoutInflater.from(mContext)
+ .inflate(R.layout.tv_pip_menu_background, null);
+ setUpViewSurfaceZOrder(mPipBackgroundView, -1);
+ addPipMenuViewToSystemWindows(mPipBackgroundView, BACKGROUND_WINDOW_TITLE);
+ }
+
+ private void setUpViewSurfaceZOrder(View v, int zOrderRelativeToPip) {
+ v.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ v.getViewRootImpl().addSurfaceChangedCallback(
+ new PipMenuSurfaceChangedCallback(v, zOrderRelativeToPip));
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ }
+ });
+ }
+
+ private void addPipMenuViewToSystemWindows(View v, String title) {
+ mSystemWindows.addView(v, getPipMenuLayoutParams(title, 0 /* width */, 0 /* height */),
+ 0 /* displayId */, SHELL_ROOT_LAYER_PIP);
+ }
+
+ void notifyPipAnimating(boolean animating) {
+ mPipMenuView.setEduTextActive(!animating);
}
void showMovementMenuOnly() {
@@ -171,8 +228,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
@Override
public void showMenu() {
if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: showMenu()", TAG);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMenu()", TAG);
}
mInMoveMode = false;
mCloseAfterExitMoveMenu = false;
@@ -183,27 +239,31 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
if (mPipMenuView == null) {
return;
}
- Rect menuBounds = getMenuBounds(mTvPipBoundsState.getBounds());
- mSystemWindows.updateViewLayout(mPipMenuView, getPipMenuLayoutParams(
- MENU_WINDOW_TITLE, menuBounds.width(), menuBounds.height()));
+ maybeCloseEduText();
maybeUpdateMenuViewActions();
updateExpansionState();
- SurfaceControl menuSurfaceControl = getSurfaceControl();
- if (menuSurfaceControl != null) {
- SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- t.setRelativeLayer(mPipMenuView.getWindowSurfaceControl(), mLeash, 1);
- t.setPosition(menuSurfaceControl, menuBounds.left, menuBounds.top);
- t.apply();
- }
grantPipMenuFocus(true);
if (mInMoveMode) {
mPipMenuView.showMoveMenu(mDelegate.getPipGravity());
} else {
- mPipMenuView.showButtonMenu();
+ mPipMenuView.showButtonsMenu();
+ }
+ }
+
+ private void maybeCloseEduText() {
+ if (mMainHandler.hasCallbacks(mCloseEduTextRunnable)) {
+ mMainHandler.removeCallbacks(mCloseEduTextRunnable);
+ mCloseEduTextRunnable.run();
}
}
+ private void closeEduText() {
+ mTvPipBoundsState.setPipMenuTemporaryDecorInsets(Insets.NONE);
+ mPipMenuView.hideEduText();
+ mDelegate.closeEduText();
+ }
+
void updateGravity(int gravity) {
mPipMenuView.showMovementHints(gravity);
}
@@ -214,12 +274,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
mPipMenuView.setIsExpanded(mTvPipBoundsState.isTvPipExpanded());
}
- private Rect getMenuBounds(Rect pipBounds) {
- int extraSpaceInPx = mContext.getResources()
- .getDimensionPixelSize(R.dimen.pip_menu_outer_space);
- Rect menuBounds = new Rect(pipBounds);
- menuBounds.inset(-extraSpaceInPx, -extraSpaceInPx);
- return menuBounds;
+ private Rect calculateMenuSurfaceBounds(Rect pipBounds) {
+ return mPipMenuView.getPipMenuContainerBounds(pipBounds);
}
void closeMenu() {
@@ -227,11 +283,12 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: closeMenu()", TAG);
}
+
if (mPipMenuView == null) {
return;
}
- mPipMenuView.hideAll();
+ mPipMenuView.hideAllUserControls();
grantPipMenuFocus(false);
mDelegate.onMenuClosed();
}
@@ -266,7 +323,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
}
if (mInMoveMode) {
mInMoveMode = false;
- mPipMenuView.showButtonMenu();
+ mPipMenuView.showButtonsMenu();
return true;
}
return false;
@@ -287,7 +344,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
@Override
public void detach() {
closeMenu();
- detachPipMenuView();
+ mMainHandler.removeCallbacks(mCloseEduTextRunnable);
+ detachPipMenu();
mLeash = null;
}
@@ -346,20 +404,15 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
@Override
public boolean isMenuVisible() {
- boolean isVisible = mPipMenuView != null && mPipMenuView.isVisible();
- if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: isMenuVisible: %b", TAG, isVisible);
- }
- return isVisible;
+ return true;
}
/**
* Does an immediate window crop of the PiP menu.
*/
@Override
- public void resizePipMenu(@android.annotation.Nullable SurfaceControl pipLeash,
- @android.annotation.Nullable SurfaceControl.Transaction t,
+ public void resizePipMenu(@Nullable SurfaceControl pipLeash,
+ @Nullable SurfaceControl.Transaction t,
Rect destinationBounds) {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
@@ -373,24 +426,36 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
return;
}
- SurfaceControl surfaceControl = getSurfaceControl();
- SyncRtSurfaceTransactionApplier.SurfaceParams
- params = new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(surfaceControl)
- .withWindowCrop(getMenuBounds(destinationBounds))
+ final Rect menuBounds = calculateMenuSurfaceBounds(destinationBounds);
+
+ final SurfaceControl frontSurface = getSurfaceControl(mPipMenuView);
+ final SyncRtSurfaceTransactionApplier.SurfaceParams frontParams =
+ new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(frontSurface)
+ .withWindowCrop(menuBounds)
+ .build();
+
+ final SurfaceControl backSurface = getSurfaceControl(mPipBackgroundView);
+ final SyncRtSurfaceTransactionApplier.SurfaceParams backParams =
+ new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(backSurface)
+ .withWindowCrop(menuBounds)
.build();
+
+ // TODO(b/226580399): switch to using SurfaceSyncer (see b/200284684) to synchronize the
+ // animations of the pip surface with the content of the front and back menu surfaces
+ mBackgroundApplier.scheduleApply(backParams);
if (pipLeash != null && t != null) {
- SyncRtSurfaceTransactionApplier.SurfaceParams
+ final SyncRtSurfaceTransactionApplier.SurfaceParams
pipParams = new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(pipLeash)
.withMergeTransaction(t)
.build();
- mApplier.scheduleApply(params, pipParams);
+ mApplier.scheduleApply(frontParams, pipParams);
} else {
- mApplier.scheduleApply(params);
+ mApplier.scheduleApply(frontParams);
}
}
- private SurfaceControl getSurfaceControl() {
- return mSystemWindows.getViewSurface(mPipMenuView);
+ private SurfaceControl getSurfaceControl(View v) {
+ return mSystemWindows.getViewSurface(v);
}
@Override
@@ -412,44 +477,52 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
return;
}
- Rect menuDestBounds = getMenuBounds(pipDestBounds);
- Rect mTmpSourceBounds = new Rect();
+ final Rect menuDestBounds = calculateMenuSurfaceBounds(pipDestBounds);
+ final Rect tmpSourceBounds = new Rect();
// If there is no pip leash supplied, that means the PiP leash is already finalized
// resizing and the PiP menu is also resized. We then want to do a scale from the current
// new menu bounds.
if (pipLeash != null && transaction != null) {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: mTmpSourceBounds based on mPipMenuView.getBoundsOnScreen()", TAG);
+ "%s: tmpSourceBounds based on mPipMenuView.getBoundsOnScreen()", TAG);
}
- mPipMenuView.getBoundsOnScreen(mTmpSourceBounds);
+ mPipMenuView.getBoundsOnScreen(tmpSourceBounds);
} else {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: mTmpSourceBounds based on menu width and height", TAG);
+ "%s: tmpSourceBounds based on menu width and height", TAG);
}
- mTmpSourceBounds.set(0, 0, menuDestBounds.width(), menuDestBounds.height());
+ tmpSourceBounds.set(0, 0, menuDestBounds.width(), menuDestBounds.height());
}
- mTmpSourceRectF.set(mTmpSourceBounds);
+ mTmpSourceRectF.set(tmpSourceBounds);
mTmpDestinationRectF.set(menuDestBounds);
- mMoveTransform.setRectToRect(mTmpSourceRectF, mTmpDestinationRectF, Matrix.ScaleToFit.FILL);
+ mMoveTransform.setTranslate(mTmpDestinationRectF.left, mTmpDestinationRectF.top);
+
+ final SurfaceControl frontSurface = getSurfaceControl(mPipMenuView);
+ final SyncRtSurfaceTransactionApplier.SurfaceParams frontParams =
+ new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(frontSurface)
+ .withMatrix(mMoveTransform)
+ .build();
- SurfaceControl surfaceControl = getSurfaceControl();
- SyncRtSurfaceTransactionApplier.SurfaceParams params =
- new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
- surfaceControl)
+ final SurfaceControl backSurface = getSurfaceControl(mPipBackgroundView);
+ final SyncRtSurfaceTransactionApplier.SurfaceParams backParams =
+ new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(backSurface)
.withMatrix(mMoveTransform)
.build();
+ // TODO(b/226580399): switch to using SurfaceSyncer (see b/200284684) to synchronize the
+ // animations of the pip surface with the content of the front and back menu surfaces
+ mBackgroundApplier.scheduleApply(backParams);
if (pipLeash != null && transaction != null) {
- SyncRtSurfaceTransactionApplier.SurfaceParams
- pipParams = new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(pipLeash)
+ final SyncRtSurfaceTransactionApplier.SurfaceParams pipParams =
+ new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(pipLeash)
.withMergeTransaction(transaction)
.build();
- mApplier.scheduleApply(params, pipParams);
+ mApplier.scheduleApply(frontParams, pipParams);
} else {
- mApplier.scheduleApply(params);
+ mApplier.scheduleApply(frontParams);
}
if (mPipMenuView.getViewRootImpl() != null) {
@@ -470,29 +543,40 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
if (mApplier == null) {
mApplier = new SyncRtSurfaceTransactionApplier(mPipMenuView);
}
+ if (mBackgroundApplier == null) {
+ mBackgroundApplier = new SyncRtSurfaceTransactionApplier(mPipBackgroundView);
+ }
return true;
}
- private void detachPipMenuView() {
- if (mPipMenuView == null) {
- return;
+ private void detachPipMenu() {
+ if (mPipMenuView != null) {
+ mApplier = null;
+ mSystemWindows.removeView(mPipMenuView);
+ mPipMenuView = null;
}
- mApplier = null;
- mSystemWindows.removeView(mPipMenuView);
- mPipMenuView = null;
+ if (mPipBackgroundView != null) {
+ mBackgroundApplier = null;
+ mSystemWindows.removeView(mPipBackgroundView);
+ mPipBackgroundView = null;
+ }
}
@Override
public void updateMenuBounds(Rect destinationBounds) {
- Rect menuBounds = getMenuBounds(destinationBounds);
+ final Rect menuBounds = calculateMenuSurfaceBounds(destinationBounds);
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: updateMenuBounds: %s", TAG, menuBounds.toShortString());
}
+ mSystemWindows.updateViewLayout(mPipBackgroundView,
+ getPipMenuLayoutParams(BACKGROUND_WINDOW_TITLE, menuBounds.width(),
+ menuBounds.height()));
mSystemWindows.updateViewLayout(mPipMenuView,
getPipMenuLayoutParams(MENU_WINDOW_TITLE, menuBounds.width(),
menuBounds.height()));
+
if (mPipMenuView != null) {
mPipMenuView.updateLayout(destinationBounds);
}
@@ -538,6 +622,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
void onMenuClosed();
+ void closeEduText();
+
void closePip();
}
@@ -555,4 +641,30 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
"%s: Unable to update focus, %s", TAG, e);
}
}
+
+ private class PipMenuSurfaceChangedCallback implements ViewRootImpl.SurfaceChangedCallback {
+ private final View mView;
+ private final int mZOrder;
+
+ PipMenuSurfaceChangedCallback(View v, int zOrder) {
+ mView = v;
+ mZOrder = zOrder;
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceControl.Transaction t) {
+ final SurfaceControl sc = getSurfaceControl(mView);
+ if (sc != null) {
+ t.setRelativeLayer(sc, mLeash, mZOrder);
+ }
+ }
+
+ @Override
+ public void surfaceReplaced(SurfaceControl.Transaction t) {
+ }
+
+ @Override
+ public void surfaceDestroyed() {
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index 9529d04fe185..5b0db8c86529 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -25,11 +25,17 @@ import static android.view.KeyEvent.KEYCODE_DPAD_RIGHT;
import static android.view.KeyEvent.KEYCODE_DPAD_UP;
import static android.view.KeyEvent.KEYCODE_ENTER;
+import android.animation.ValueAnimator;
import android.app.PendingIntent;
import android.app.RemoteAction;
import android.content.Context;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.text.Annotation;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannedString;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.KeyEvent;
@@ -40,6 +46,7 @@ import android.view.ViewRootImpl;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -49,6 +56,7 @@ import com.android.wm.shell.R;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -67,6 +75,15 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
private final LinearLayout mActionButtonsContainer;
private final View mMenuFrameView;
private final List<TvPipMenuActionButton> mAdditionalButtons = new ArrayList<>();
+ private final View mPipFrameView;
+ private final View mPipView;
+ private final TextView mEduTextView;
+ private final View mEduTextContainerView;
+ private final int mPipMenuOuterSpace;
+ private final int mPipMenuBorderWidth;
+ private final int mEduTextFadeExitAnimationDurationMs;
+ private final int mEduTextSlideExitAnimationDurationMs;
+ private int mEduTextHeight;
private final ImageView mArrowUp;
private final ImageView mArrowRight;
@@ -76,11 +93,13 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
private final ViewGroup mScrollView;
private final ViewGroup mHorizontalScrollView;
- private Rect mCurrentBounds;
+ private Rect mCurrentPipBounds;
private final TvPipMenuActionButton mExpandButton;
private final TvPipMenuActionButton mCloseButton;
+ private final int mPipMenuFadeAnimationDuration;
+
public TvPipMenuView(@NonNull Context context) {
this(context, null);
}
@@ -116,21 +135,86 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
mHorizontalScrollView = findViewById(R.id.tv_pip_menu_horizontal_scroll);
mMenuFrameView = findViewById(R.id.tv_pip_menu_frame);
+ mPipFrameView = findViewById(R.id.tv_pip_border);
+ mPipView = findViewById(R.id.tv_pip);
mArrowUp = findViewById(R.id.tv_pip_menu_arrow_up);
mArrowRight = findViewById(R.id.tv_pip_menu_arrow_right);
mArrowDown = findViewById(R.id.tv_pip_menu_arrow_down);
mArrowLeft = findViewById(R.id.tv_pip_menu_arrow_left);
+
+ mEduTextView = findViewById(R.id.tv_pip_menu_edu_text);
+ mEduTextContainerView = findViewById(R.id.tv_pip_menu_edu_text_container);
+
+ mPipMenuFadeAnimationDuration = context.getResources()
+ .getInteger(R.integer.pip_menu_fade_animation_duration);
+ mPipMenuOuterSpace = context.getResources()
+ .getDimensionPixelSize(R.dimen.pip_menu_outer_space);
+ mPipMenuBorderWidth = context.getResources()
+ .getDimensionPixelSize(R.dimen.pip_menu_border_width);
+ mEduTextHeight = context.getResources()
+ .getDimensionPixelSize(R.dimen.pip_menu_edu_text_view_height);
+ mEduTextFadeExitAnimationDurationMs = context.getResources()
+ .getInteger(R.integer.pip_edu_text_view_exit_animation_duration_ms);
+ mEduTextSlideExitAnimationDurationMs = context.getResources()
+ .getInteger(R.integer.pip_edu_text_window_exit_animation_duration_ms);
+
+ initEduText();
+ }
+
+ void initEduText() {
+ final SpannedString eduText = (SpannedString) getResources().getText(R.string.pip_edu_text);
+ final SpannableString spannableString = new SpannableString(eduText);
+ Arrays.stream(eduText.getSpans(0, eduText.length(), Annotation.class)).findFirst()
+ .ifPresent(annotation -> {
+ final Drawable icon =
+ getResources().getDrawable(R.drawable.home_icon, mContext.getTheme());
+ if (icon != null) {
+ icon.mutate();
+ icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
+ spannableString.setSpan(new CenteredImageSpan(icon),
+ eduText.getSpanStart(annotation),
+ eduText.getSpanEnd(annotation),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ });
+
+ mEduTextView.setText(spannableString);
}
- void updateLayout(Rect updatedBounds) {
+ void setEduTextActive(boolean active) {
+ mEduTextView.setSelected(active);
+ }
+
+ void hideEduText() {
+ final ValueAnimator heightAnimation = ValueAnimator.ofInt(mEduTextHeight, 0);
+ heightAnimation.setDuration(mEduTextSlideExitAnimationDurationMs);
+ heightAnimation.setInterpolator(TvPipInterpolators.BROWSE);
+ heightAnimation.addUpdateListener(animator -> {
+ mEduTextHeight = (int) animator.getAnimatedValue();
+ });
+ mEduTextView.animate()
+ .alpha(0f)
+ .setInterpolator(TvPipInterpolators.EXIT)
+ .setDuration(mEduTextFadeExitAnimationDurationMs)
+ .withEndAction(() -> {
+ mEduTextContainerView.setVisibility(GONE);
+ }).start();
+ heightAnimation.start();
+ }
+
+ void updateLayout(Rect updatedPipBounds) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: update menu layout: %s", TAG, updatedBounds.toShortString());
+ "%s: update menu layout: %s", TAG, updatedPipBounds.toShortString());
+
boolean previouslyVertical =
- mCurrentBounds != null && mCurrentBounds.height() > mCurrentBounds.width();
- boolean vertical = updatedBounds.height() > updatedBounds.width();
+ mCurrentPipBounds != null && mCurrentPipBounds.height() > mCurrentPipBounds.width();
+ boolean vertical = updatedPipBounds.height() > updatedPipBounds.width();
+
+ mCurrentPipBounds = updatedPipBounds;
+
+ updatePipFrameBounds();
- mCurrentBounds = updatedBounds;
if (previouslyVertical == vertical) {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
@@ -158,6 +242,38 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
mHorizontalScrollView.setVisibility(vertical ? GONE : VISIBLE);
}
+ Rect getPipMenuContainerBounds(Rect pipBounds) {
+ final Rect menuUiBounds = new Rect(pipBounds);
+ menuUiBounds.inset(-mPipMenuOuterSpace, -mPipMenuOuterSpace);
+ menuUiBounds.bottom += mEduTextHeight;
+ return menuUiBounds;
+ }
+
+ /**
+ * Update mPipFrameView's bounds according to the new pip window bounds. We can't
+ * make mPipFrameView match_parent, because the pip menu might contain other content around
+ * the pip window (e.g. edu text).
+ * TvPipMenuView needs to account for this so that it can draw a white border around the whole
+ * pip menu when it gains focus.
+ */
+ private void updatePipFrameBounds() {
+ final ViewGroup.LayoutParams pipFrameParams = mPipFrameView.getLayoutParams();
+ if (pipFrameParams != null) {
+ pipFrameParams.width = mCurrentPipBounds.width() + 2 * mPipMenuBorderWidth;
+ pipFrameParams.height = mCurrentPipBounds.height() + 2 * mPipMenuBorderWidth;
+ mPipFrameView.setLayoutParams(pipFrameParams);
+ }
+
+ final ViewGroup.LayoutParams pipViewParams = mPipView.getLayoutParams();
+ if (pipViewParams != null) {
+ pipViewParams.width = mCurrentPipBounds.width();
+ pipViewParams.height = mCurrentPipBounds.height();
+ mPipView.setLayoutParams(pipViewParams);
+ }
+
+
+ }
+
void setListener(@Nullable Listener listener) {
mListener = listener;
}
@@ -184,30 +300,32 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMoveMenu()", TAG);
}
- showMenuButtons(false);
+ showButtonsMenu(false);
showMovementHints(gravity);
- showMenuFrame(true);
+ setFrameHighlighted(true);
}
- void showButtonMenu() {
+ void showButtonsMenu() {
if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showButtonMenu()", TAG);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: showButtonsMenu()", TAG);
}
- showMenuButtons(true);
+ showButtonsMenu(true);
hideMovementHints();
- showMenuFrame(true);
+ setFrameHighlighted(true);
}
/**
* Hides all menu views, including the menu frame.
*/
- void hideAll() {
+ void hideAllUserControls() {
if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: hideAll()", TAG);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: hideAllUserControls()", TAG);
}
- showMenuButtons(false);
+ showButtonsMenu(false);
hideMovementHints();
- showMenuFrame(false);
+ setFrameHighlighted(false);
}
private void animateAlphaTo(float alpha, View view) {
@@ -217,7 +335,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
view.animate()
.alpha(alpha)
.setInterpolator(alpha == 0f ? TvPipInterpolators.EXIT : TvPipInterpolators.ENTER)
- .setDuration(500)
+ .setDuration(mPipMenuFadeAnimationDuration)
.withStartAction(() -> {
if (alpha != 0) {
view.setVisibility(VISIBLE);
@@ -230,15 +348,6 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
});
}
- boolean isVisible() {
- return mMenuFrameView.getAlpha() != 0f
- || mActionButtonsContainer.getAlpha() != 0f
- || mArrowUp.getAlpha() != 0f
- || mArrowRight.getAlpha() != 0f
- || mArrowDown.getAlpha() != 0f
- || mArrowLeft.getAlpha() != 0f;
- }
-
void setAdditionalActions(List<RemoteAction> actions, RemoteAction closeAction,
Handler mainHandler) {
if (DEBUG) {
@@ -423,18 +532,18 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
}
/**
- * Show or hide the pip user actions.
+ * Show or hide the pip buttons menu.
*/
- public void showMenuButtons(boolean show) {
+ public void showButtonsMenu(boolean show) {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: showMenuButtons: %b", TAG, show);
+ "%s: showUserActions: %b", TAG, show);
}
animateAlphaTo(show ? 1 : 0, mActionButtonsContainer);
}
- private void showMenuFrame(boolean show) {
- animateAlphaTo(show ? 1 : 0, mMenuFrameView);
+ private void setFrameHighlighted(boolean highlighted) {
+ mMenuFrameView.setActivated(highlighted);
}
interface Listener {
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 3593eddf4b3b..e150cf9cd112 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
@@ -171,6 +171,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private boolean mShouldUpdateRecents;
private boolean mExitSplitScreenOnHide;
private boolean mIsDividerRemoteAnimating;
+ private boolean mResizingSplits;
/** The target stage to dismiss to when unlock after folded. */
@StageType
@@ -1093,10 +1094,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Override
public void onSnappedToDismiss(boolean bottomOrRight) {
+ setResizingSplits(false /* resizing */);
+
final boolean mainStageToTop =
bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
: mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
-
if (!ENABLE_SHELL_TRANSITIONS) {
exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, EXIT_REASON_DRAG_DIVIDER);
return;
@@ -1125,6 +1127,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Override
public void onLayoutSizeChanging(SplitLayout layout) {
mSyncQueue.runInSync(t -> {
+ setResizingSplits(true /* resizing */);
updateSurfaceBounds(layout, t);
mMainStage.onResizing(getMainStageBounds(), t);
mSideStage.onResizing(getSideStageBounds(), t);
@@ -1138,6 +1141,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
updateUnfoldBounds();
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> {
+ setResizingSplits(false /* resizing */);
updateSurfaceBounds(layout, t);
mMainStage.onResized(t);
mSideStage.onResized(t);
@@ -1179,6 +1183,16 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer);
}
+ void setResizingSplits(boolean resizing) {
+ if (resizing == mResizingSplits) return;
+ try {
+ ActivityTaskManager.getService().setSplitScreenResizing(resizing);
+ mResizingSplits = resizing;
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error calling setSplitScreenResizing", e);
+ }
+ }
+
@Override
public int getSplitItemPosition(WindowContainerToken token) {
if (token == null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index fd6e59ee6a81..cde4247c575f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -20,8 +20,10 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.graphics.Color.WHITE;
import static android.graphics.Color.alpha;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.ViewRootImpl.LOCAL_LAYOUT;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
+import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
import static android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
@@ -51,6 +53,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityThread;
+import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -77,6 +80,7 @@ import android.view.SurfaceSession;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
+import android.view.WindowLayout;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.window.ClientWindowFrames;
@@ -208,6 +212,8 @@ public class TaskSnapshotWindow {
final IWindowSession session = WindowManagerGlobal.getWindowSession();
final SurfaceControl surfaceControl = new SurfaceControl();
final ClientWindowFrames tmpFrames = new ClientWindowFrames();
+ final WindowLayout windowLayout = new WindowLayout();
+ final Rect displayCutoutSafe = new Rect();
final InsetsSourceControl[] tmpControls = new InsetsSourceControl[0];
final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration();
@@ -244,9 +250,25 @@ public class TaskSnapshotWindow {
window.setOuter(snapshotSurface);
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "TaskSnapshot#relayout");
- session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0,
- tmpFrames, tmpMergedConfiguration, surfaceControl, tmpInsetsState,
- tmpControls, new Bundle());
+ if (LOCAL_LAYOUT) {
+ if (!surfaceControl.isValid()) {
+ session.updateVisibility(window, layoutParams, View.VISIBLE,
+ tmpMergedConfiguration, surfaceControl, tmpInsetsState, tmpControls);
+ }
+ tmpInsetsState.getDisplayCutoutSafe(displayCutoutSafe);
+ final WindowConfiguration winConfig =
+ tmpMergedConfiguration.getMergedConfiguration().windowConfiguration;
+ windowLayout.computeFrames(layoutParams, tmpInsetsState, displayCutoutSafe,
+ winConfig.getBounds(), winConfig.getWindowingMode(), UNSPECIFIED_LENGTH,
+ UNSPECIFIED_LENGTH, info.requestedVisibilities,
+ null /* attachedWindowFrame */, 1f /* compatScale */, tmpFrames);
+ session.updateLayout(window, layoutParams, 0 /* flags */, tmpFrames,
+ UNSPECIFIED_LENGTH, UNSPECIFIED_LENGTH);
+ } else {
+ session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0,
+ tmpFrames, tmpMergedConfiguration, surfaceControl, tmpInsetsState,
+ tmpControls, new Bundle());
+ }
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} catch (RemoteException e) {
snapshotSurface.clearWindowSynced();
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 542ddeea769c..3ea57b0520b7 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
@@ -437,15 +437,15 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
cornerRadius = 0;
}
- if (a.getShowBackground()) {
+ if (a.getShowBackdrop()) {
if (info.getAnimationOptions().getBackgroundColor() != 0) {
// If available use the background color provided through AnimationOptions
backgroundColorForTransition =
info.getAnimationOptions().getBackgroundColor();
- } else if (a.getBackgroundColor() != 0) {
+ } else if (a.getBackdropColor() != 0) {
// Otherwise fallback on the background color provided through the animation
// definition.
- backgroundColorForTransition = a.getBackgroundColor();
+ backgroundColorForTransition = a.getBackdropColor();
} else if (change.getBackgroundColor() != 0) {
// Otherwise default to the window's background color if provided through
// the theme as the background color for the animation - the top most window
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
new file mode 100644
index 000000000000..639603941c18
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -0,0 +1,130 @@
+/*
+ * 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.wm.shell.unfold;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_CHANGE;
+
+import android.os.IBinder;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerTransaction;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.transition.Transitions.TransitionFinishCallback;
+import com.android.wm.shell.transition.Transitions.TransitionHandler;
+import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListener {
+
+ private final ShellUnfoldProgressProvider mUnfoldProgressProvider;
+ private final Transitions mTransitions;
+ private final Executor mExecutor;
+ private final TransactionPool mTransactionPool;
+
+ @Nullable
+ private TransitionFinishCallback mFinishCallback;
+ @Nullable
+ private IBinder mTransition;
+
+ private final List<TransitionInfo.Change> mAnimatedFullscreenTasks = new ArrayList<>();
+
+ public UnfoldTransitionHandler(ShellUnfoldProgressProvider unfoldProgressProvider,
+ TransactionPool transactionPool, Executor executor, Transitions transitions) {
+ mUnfoldProgressProvider = unfoldProgressProvider;
+ mTransactionPool = transactionPool;
+ mExecutor = executor;
+ mTransitions = transitions;
+ }
+
+ public void init() {
+ mTransitions.addHandler(this);
+ mUnfoldProgressProvider.addListener(mExecutor, this);
+ }
+
+ @Override
+ public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull TransitionFinishCallback finishCallback) {
+
+ if (transition != mTransition) return false;
+
+ startTransaction.apply();
+
+ mAnimatedFullscreenTasks.clear();
+ info.getChanges().forEach(change -> {
+ final boolean allowedToAnimate = change.getTaskInfo() != null
+ && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ && change.getTaskInfo().getActivityType() != ACTIVITY_TYPE_HOME
+ && change.getMode() == TRANSIT_CHANGE;
+
+ if (allowedToAnimate) {
+ mAnimatedFullscreenTasks.add(change);
+ }
+ });
+
+ mFinishCallback = finishCallback;
+ mTransition = null;
+ return true;
+ }
+
+ @Override
+ public void onStateChangeProgress(float progress) {
+ mAnimatedFullscreenTasks.forEach(change -> {
+ final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
+
+ // TODO: this is a placeholder animation, replace with a spec version in the next CLs
+ final float testScale = 0.8f + 0.2f * progress;
+ transaction.setScale(change.getLeash(), testScale, testScale);
+
+ transaction.apply();
+ mTransactionPool.release(transaction);
+ });
+ }
+
+ @Override
+ public void onStateChangeFinished() {
+ if (mFinishCallback != null) {
+ mFinishCallback.onTransitionFinished(null, null);
+ mFinishCallback = null;
+ mAnimatedFullscreenTasks.clear();
+ }
+ }
+
+ @Nullable
+ @Override
+ public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
+ @NonNull TransitionRequestInfo request) {
+ if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null
+ && request.getDisplayChange().isPhysicalDisplayChanged()) {
+ mTransition = transition;
+ return new WindowContainerTransaction();
+ }
+ return null;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index a244d14b0e14..f4efc374ecc2 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 909476
+# Bug component: 1157642
# includes OWNERS from parent directories
natanieljr@google.com
pablogamito@google.com
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 3fe6f02eccf7..9a8c8942d2c9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.flicker.pip
+import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
@@ -84,7 +85,7 @@ class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransit
override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
/** {@inheritDoc} */
- @FlakyTest(bugId = 197726610)
+ @Presubmit
@Test
override fun pipLayerExpands() = super.pipLayerExpands()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index 5fc80db6c617..9f3fcea241e4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -111,7 +111,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
/**
* Checks that the visible region of [pipApp] always expands during the animation
*/
- @Presubmit
+ @FlakyTest(bugId = 228012337)
@Test
fun pipLayerExpands() {
val layerName = pipApp.component.toLayerName()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index 6af01e24f58c..c1ee1a7cbb35 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -33,7 +33,6 @@ import com.android.server.wm.flicker.navBarLayerRotatesAndScales
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.wm.shell.flicker.helpers.FixedAppHelper
import org.junit.Assume
-import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -69,11 +68,6 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
private val screenBoundsStart = WindowUtils.getDisplayBounds(testSpec.startRotation)
private val screenBoundsEnd = WindowUtils.getDisplayBounds(testSpec.endRotation)
- @Before
- open fun before() {
- Assume.assumeFalse(isShellTransitionsEnabled)
- }
-
override val transition: FlickerBuilder.() -> Unit
get() = buildTransition(eachRun = false) {
setup {
@@ -135,15 +129,30 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
/**
* Checks that [pipApp] layer is within [screenBoundsStart] at the start of the transition
*/
- @Presubmit
- @Test
- open fun pipLayerRotates_StartingBounds() {
+ private fun pipLayerRotates_StartingBounds_internal() {
testSpec.assertLayersStart {
visibleRegion(pipApp.component).coversAtMost(screenBoundsStart)
}
}
/**
+ * Checks that [pipApp] layer is within [screenBoundsStart] at the start of the transition
+ */
+ @Presubmit
+ @Test
+ fun pipLayerRotates_StartingBounds() {
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ pipLayerRotates_StartingBounds_internal()
+ }
+
+ @FlakyTest(bugId = 228024285)
+ @Test
+ fun pipLayerRotates_StartingBounds_ShellTransit() {
+ Assume.assumeTrue(isShellTransitionsEnabled)
+ pipLayerRotates_StartingBounds_internal()
+ }
+
+ /**
* Checks that [pipApp] layer is within [screenBoundsEnd] at the end of the transition
*/
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
index 81403d08ff20..e40f2bc1ed5a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
@@ -47,7 +47,6 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
-@FlakyTest(bugId = 218604389)
open class SetRequestedOrientationWhilePinnedTest(
testSpec: FlickerTestParameter
) : PipTransition(testSpec) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 7c1fae3a849b..a905dcaebc6b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -16,10 +16,16 @@
package com.android.wm.shell.back;
+import static android.window.BackNavigationInfo.KEY_TRIGGER_BACK;
+
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.app.IActivityTaskManager;
@@ -101,6 +107,14 @@ public class BackAnimationControllerTest {
}
}
+ private void createNavigationInfo(BackNavigationInfo.Builder builder) {
+ try {
+ doReturn(builder.build()).when(mActivityTaskManager).startBackNavigation();
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ }
+
RemoteAnimationTarget createAnimationTarget() {
SurfaceControl topWindowLeash = new SurfaceControl();
return new RemoteAnimationTarget(-1, RemoteAnimationTarget.MODE_CLOSING, topWindowLeash,
@@ -109,6 +123,18 @@ public class BackAnimationControllerTest {
true, null, null, null, false, -1);
}
+ private void triggerBackGesture() {
+ MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
+ mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
+
+ event = MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0);
+ mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
+
+ mController.setTriggerBack(true);
+ event = MotionEvent.obtain(10, 0, MotionEvent.ACTION_UP, 100, 100, 0);
+ mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
+ }
+
@Test
@Ignore("b/207481538")
public void crossActivity_screenshotAttachedAndVisible() {
@@ -140,11 +166,32 @@ public class BackAnimationControllerTest {
MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
MotionEvent.ACTION_MOVE,
BackEvent.EDGE_LEFT);
- verify(mTransaction).setPosition(animationTarget.leash, 100, 100);
+ // b/207481538, we check that the surface is not moved for now, we can re-enable this once
+ // we implement the animation
+ verify(mTransaction, never()).setScale(eq(screenshotSurface), anyInt(), anyInt());
+ verify(mTransaction, never()).setPosition(animationTarget.leash, 100, 100);
verify(mTransaction, atLeastOnce()).apply();
}
@Test
+ public void verifyAnimationFinishes() {
+ RemoteAnimationTarget animationTarget = createAnimationTarget();
+ boolean[] backNavigationDone = new boolean[]{false};
+ boolean[] triggerBack = new boolean[]{false};
+ createNavigationInfo(new BackNavigationInfo.Builder()
+ .setDepartingAnimationTarget(animationTarget)
+ .setType(BackNavigationInfo.TYPE_CROSS_ACTIVITY)
+ .setOnBackNavigationDone(
+ new RemoteCallback(result -> {
+ backNavigationDone[0] = true;
+ triggerBack[0] = result.getBoolean(KEY_TRIGGER_BACK);
+ })));
+ triggerBackGesture();
+ assertTrue("Navigation Done callback not called", backNavigationDone[0]);
+ assertTrue("TriggerBack should have been true", triggerBack[0]);
+ }
+
+ @Test
public void backToHome_dispatchesEvents() throws RemoteException {
mController.setBackToLauncherCallback(mIOnBackInvokedCallback);
RemoteAnimationTarget animationTarget = createAnimationTarget();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java
index b66c2b4aee9b..3bf06cc0ede3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java
@@ -19,11 +19,8 @@ package com.android.wm.shell.common;
import static android.view.Display.DEFAULT_DISPLAY;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.notNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -33,6 +30,7 @@ import android.view.IDisplayWindowInsetsController;
import android.view.IWindowManager;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.view.InsetsVisibilities;
import androidx.test.filters.SmallTest;
@@ -42,7 +40,6 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.List;
@@ -99,7 +96,8 @@ public class DisplayInsetsControllerTest {
mController.addInsetsChangedListener(DEFAULT_DISPLAY, defaultListener);
mController.addInsetsChangedListener(SECOND_DISPLAY, secondListener);
- mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).topFocusedWindowChanged(null);
+ mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).topFocusedWindowChanged(null,
+ new InsetsVisibilities());
mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).insetsChanged(null);
mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).insetsControlChanged(null, null);
mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).showInsets(0, false);
@@ -118,7 +116,8 @@ public class DisplayInsetsControllerTest {
assertTrue(secondListener.showInsetsCount == 0);
assertTrue(secondListener.hideInsetsCount == 0);
- mInsetsControllersByDisplayId.get(SECOND_DISPLAY).topFocusedWindowChanged(null);
+ mInsetsControllersByDisplayId.get(SECOND_DISPLAY).topFocusedWindowChanged(null,
+ new InsetsVisibilities());
mInsetsControllersByDisplayId.get(SECOND_DISPLAY).insetsChanged(null);
mInsetsControllersByDisplayId.get(SECOND_DISPLAY).insetsControlChanged(null, null);
mInsetsControllersByDisplayId.get(SECOND_DISPLAY).showInsets(0, false);
@@ -165,7 +164,8 @@ public class DisplayInsetsControllerTest {
int hideInsetsCount = 0;
@Override
- public void topFocusedWindowChanged(String packageName) {
+ public void topFocusedWindowChanged(String packageName,
+ InsetsVisibilities requestedVisibilities) {
topFocusedWindowChangedCount++;
}
diff --git a/location/java/android/location/LocationDeviceConfig.java b/location/java/android/location/LocationDeviceConfig.java
index c55eed9211f7..7d22681fc93e 100644
--- a/location/java/android/location/LocationDeviceConfig.java
+++ b/location/java/android/location/LocationDeviceConfig.java
@@ -24,6 +24,30 @@ package android.location;
public final class LocationDeviceConfig {
/**
+ * Package/tag combinations that are allowlisted for ignoring location settings (may retrieve
+ * location even when user location settings are off), for advanced driver-assistance systems
+ * only.
+ *
+ * <p>Package/tag combinations are separated by commas (","), and with in each combination is a
+ * package name followed by 0 or more attribution tags, separated by semicolons (";"). If a
+ * package is followed by 0 attribution tags, this is interpreted the same as the wildcard
+ * value. There are two special interpreted values for attribution tags, the wildcard value
+ * ("*") which represents all attribution tags, and the null value ("null"), which is converted
+ * to the null string (since attribution tags may be null). This format implies that attribution
+ * tags which should be on this list may not contain semicolons.
+ *
+ * <p>Examples of valid entries:
+ *
+ * <ul>
+ * <li>android
+ * <li>android;*
+ * <li>android;*,com.example.app;null;my_attr
+ * <li>android;*,com.example.app;null;my_attr,com.example.otherapp;my_attr
+ * </ul>
+ */
+ public static final String ADAS_SETTINGS_ALLOWLIST = "adas_settings_allowlist";
+
+ /**
* Package/tag combinations that are allowedlisted for ignoring location settings (may retrieve
* location even when user location settings are off, and may ignore throttling, etc), for
* emergency purposes only.
@@ -39,10 +63,10 @@ public final class LocationDeviceConfig {
* <p>Examples of valid entries:
*
* <ul>
- * <li>android</li>
- * <li>android;*</li>
- * <li>android;*,com.example.app;null;my_attr</li>
- * <li>android;*,com.example.app;null;my_attr,com.example.otherapp;my_attr</li>
+ * <li>android
+ * <li>android;*
+ * <li>android;*,com.example.app;null;my_attr
+ * <li>android;*,com.example.app;null;my_attr,com.example.otherapp;my_attr
* </ul>
*/
public static final String IGNORE_SETTINGS_ALLOWLIST = "ignore_settings_allowlist";
diff --git a/media/Android.bp b/media/Android.bp
index 2f9c5203b462..36da253cf60f 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -36,7 +36,7 @@ aidl_interface {
],
imports: [
"android.media.audio.common.types",
- "android.media.soundtrigger.types",
+ "android.media.soundtrigger.types-V1",
"media_permission-aidl",
],
}
@@ -166,4 +166,11 @@ aidl_interface {
imports: [
"android.media.audio.common.types",
],
+ versions_with_info: [
+ {
+ version: "1",
+ imports: ["android.media.audio.common.types-V1"],
+ },
+ ],
+
}
diff --git a/media/aidl_api/android.media.audio.common.types/1/.hash b/media/aidl_api/android.media.audio.common.types/1/.hash
new file mode 100644
index 000000000000..328aab4b355c
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/.hash
@@ -0,0 +1 @@
+985ad49c876a50c60c726dc87f60cb598fd087ad
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioChannelLayout.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioChannelLayout.aidl
new file mode 100644
index 000000000000..6845ac1f6e1f
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioChannelLayout.aidl
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+union AudioChannelLayout {
+ int none = 0;
+ int invalid = 0;
+ int indexMask;
+ int layoutMask;
+ int voiceMask;
+ const int INDEX_MASK_1 = 1;
+ const int INDEX_MASK_2 = 3;
+ const int INDEX_MASK_3 = 7;
+ const int INDEX_MASK_4 = 15;
+ const int INDEX_MASK_5 = 31;
+ const int INDEX_MASK_6 = 63;
+ const int INDEX_MASK_7 = 127;
+ const int INDEX_MASK_8 = 255;
+ const int INDEX_MASK_9 = 511;
+ const int INDEX_MASK_10 = 1023;
+ const int INDEX_MASK_11 = 2047;
+ const int INDEX_MASK_12 = 4095;
+ const int INDEX_MASK_13 = 8191;
+ const int INDEX_MASK_14 = 16383;
+ const int INDEX_MASK_15 = 32767;
+ const int INDEX_MASK_16 = 65535;
+ const int INDEX_MASK_17 = 131071;
+ const int INDEX_MASK_18 = 262143;
+ const int INDEX_MASK_19 = 524287;
+ const int INDEX_MASK_20 = 1048575;
+ const int INDEX_MASK_21 = 2097151;
+ const int INDEX_MASK_22 = 4194303;
+ const int INDEX_MASK_23 = 8388607;
+ const int INDEX_MASK_24 = 16777215;
+ const int LAYOUT_MONO = 1;
+ const int LAYOUT_STEREO = 3;
+ const int LAYOUT_2POINT1 = 11;
+ const int LAYOUT_TRI = 7;
+ const int LAYOUT_TRI_BACK = 259;
+ const int LAYOUT_3POINT1 = 15;
+ const int LAYOUT_2POINT0POINT2 = 786435;
+ const int LAYOUT_2POINT1POINT2 = 786443;
+ const int LAYOUT_3POINT0POINT2 = 786439;
+ const int LAYOUT_3POINT1POINT2 = 786447;
+ const int LAYOUT_QUAD = 51;
+ const int LAYOUT_QUAD_SIDE = 1539;
+ const int LAYOUT_SURROUND = 263;
+ const int LAYOUT_PENTA = 55;
+ const int LAYOUT_5POINT1 = 63;
+ const int LAYOUT_5POINT1_SIDE = 1551;
+ const int LAYOUT_5POINT1POINT2 = 786495;
+ const int LAYOUT_5POINT1POINT4 = 184383;
+ const int LAYOUT_6POINT1 = 319;
+ const int LAYOUT_7POINT1 = 1599;
+ const int LAYOUT_7POINT1POINT2 = 788031;
+ const int LAYOUT_7POINT1POINT4 = 185919;
+ const int LAYOUT_9POINT1POINT4 = 50517567;
+ const int LAYOUT_9POINT1POINT6 = 51303999;
+ const int LAYOUT_13POINT_360RA = 7534087;
+ const int LAYOUT_22POINT2 = 16777215;
+ const int LAYOUT_MONO_HAPTIC_A = 1073741825;
+ const int LAYOUT_STEREO_HAPTIC_A = 1073741827;
+ const int LAYOUT_HAPTIC_AB = 1610612736;
+ const int LAYOUT_MONO_HAPTIC_AB = 1610612737;
+ const int LAYOUT_STEREO_HAPTIC_AB = 1610612739;
+ const int LAYOUT_FRONT_BACK = 260;
+ const int INTERLEAVE_LEFT = 0;
+ const int INTERLEAVE_RIGHT = 1;
+ const int CHANNEL_FRONT_LEFT = 1;
+ const int CHANNEL_FRONT_RIGHT = 2;
+ const int CHANNEL_FRONT_CENTER = 4;
+ const int CHANNEL_LOW_FREQUENCY = 8;
+ const int CHANNEL_BACK_LEFT = 16;
+ const int CHANNEL_BACK_RIGHT = 32;
+ const int CHANNEL_FRONT_LEFT_OF_CENTER = 64;
+ const int CHANNEL_FRONT_RIGHT_OF_CENTER = 128;
+ const int CHANNEL_BACK_CENTER = 256;
+ const int CHANNEL_SIDE_LEFT = 512;
+ const int CHANNEL_SIDE_RIGHT = 1024;
+ const int CHANNEL_TOP_CENTER = 2048;
+ const int CHANNEL_TOP_FRONT_LEFT = 4096;
+ const int CHANNEL_TOP_FRONT_CENTER = 8192;
+ const int CHANNEL_TOP_FRONT_RIGHT = 16384;
+ const int CHANNEL_TOP_BACK_LEFT = 32768;
+ const int CHANNEL_TOP_BACK_CENTER = 65536;
+ const int CHANNEL_TOP_BACK_RIGHT = 131072;
+ const int CHANNEL_TOP_SIDE_LEFT = 262144;
+ const int CHANNEL_TOP_SIDE_RIGHT = 524288;
+ const int CHANNEL_BOTTOM_FRONT_LEFT = 1048576;
+ const int CHANNEL_BOTTOM_FRONT_CENTER = 2097152;
+ const int CHANNEL_BOTTOM_FRONT_RIGHT = 4194304;
+ const int CHANNEL_LOW_FREQUENCY_2 = 8388608;
+ const int CHANNEL_FRONT_WIDE_LEFT = 16777216;
+ const int CHANNEL_FRONT_WIDE_RIGHT = 33554432;
+ const int CHANNEL_HAPTIC_B = 536870912;
+ const int CHANNEL_HAPTIC_A = 1073741824;
+ const int VOICE_UPLINK_MONO = 16384;
+ const int VOICE_DNLINK_MONO = 32768;
+ const int VOICE_CALL_MONO = 49152;
+ const int CHANNEL_VOICE_UPLINK = 16384;
+ const int CHANNEL_VOICE_DNLINK = 32768;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioConfig.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioConfig.aidl
new file mode 100644
index 000000000000..6b8686ce2c96
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioConfig {
+ android.media.audio.common.AudioConfigBase base;
+ android.media.audio.common.AudioOffloadInfo offloadInfo;
+ long frameCount;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioConfigBase.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioConfigBase.aidl
new file mode 100644
index 000000000000..f3e716b1d3b4
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioConfigBase.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioConfigBase {
+ int sampleRate;
+ android.media.audio.common.AudioChannelLayout channelMask;
+ android.media.audio.common.AudioFormatDescription format;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioContentType.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioContentType.aidl
new file mode 100644
index 000000000000..f9ac61426fa3
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioContentType.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioContentType {
+ UNKNOWN = 0,
+ SPEECH = 1,
+ MUSIC = 2,
+ MOVIE = 3,
+ SONIFICATION = 4,
+ ULTRASOUND = 1997,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDevice.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDevice.aidl
new file mode 100644
index 000000000000..fb5cb62281e2
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDevice.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioDevice {
+ android.media.audio.common.AudioDeviceDescription type;
+ android.media.audio.common.AudioDeviceAddress address;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceAddress.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceAddress.aidl
new file mode 100644
index 000000000000..905d3aa5fb0d
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceAddress.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+union AudioDeviceAddress {
+ @utf8InCpp String id;
+ byte[] mac;
+ byte[] ipv4;
+ int[] ipv6;
+ int[] alsa;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceDescription.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceDescription.aidl
new file mode 100644
index 000000000000..1c66a8f98b1e
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceDescription.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioDeviceDescription {
+ android.media.audio.common.AudioDeviceType type = android.media.audio.common.AudioDeviceType.NONE;
+ @utf8InCpp String connection;
+ const @utf8InCpp String CONNECTION_ANALOG = "analog";
+ const @utf8InCpp String CONNECTION_BT_A2DP = "bt-a2dp";
+ const @utf8InCpp String CONNECTION_BT_LE = "bt-le";
+ const @utf8InCpp String CONNECTION_BT_SCO = "bt-sco";
+ const @utf8InCpp String CONNECTION_BUS = "bus";
+ const @utf8InCpp String CONNECTION_HDMI = "hdmi";
+ const @utf8InCpp String CONNECTION_HDMI_ARC = "hdmi-arc";
+ const @utf8InCpp String CONNECTION_HDMI_EARC = "hdmi-earc";
+ const @utf8InCpp String CONNECTION_IP_V4 = "ip-v4";
+ const @utf8InCpp String CONNECTION_SPDIF = "spdif";
+ const @utf8InCpp String CONNECTION_WIRELESS = "wireless";
+ const @utf8InCpp String CONNECTION_USB = "usb";
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceType.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceType.aidl
new file mode 100644
index 000000000000..6a7b6864b801
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioDeviceType.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioDeviceType {
+ NONE = 0,
+ IN_DEFAULT = 1,
+ IN_ACCESSORY = 2,
+ IN_AFE_PROXY = 3,
+ IN_DEVICE = 4,
+ IN_ECHO_REFERENCE = 5,
+ IN_FM_TUNER = 6,
+ IN_HEADSET = 7,
+ IN_LOOPBACK = 8,
+ IN_MICROPHONE = 9,
+ IN_MICROPHONE_BACK = 10,
+ IN_SUBMIX = 11,
+ IN_TELEPHONY_RX = 12,
+ IN_TV_TUNER = 13,
+ IN_DOCK = 14,
+ OUT_DEFAULT = 129,
+ OUT_ACCESSORY = 130,
+ OUT_AFE_PROXY = 131,
+ OUT_CARKIT = 132,
+ OUT_DEVICE = 133,
+ OUT_ECHO_CANCELLER = 134,
+ OUT_FM = 135,
+ OUT_HEADPHONE = 136,
+ OUT_HEADSET = 137,
+ OUT_HEARING_AID = 138,
+ OUT_LINE_AUX = 139,
+ OUT_SPEAKER = 140,
+ OUT_SPEAKER_EARPIECE = 141,
+ OUT_SPEAKER_SAFE = 142,
+ OUT_SUBMIX = 143,
+ OUT_TELEPHONY_TX = 144,
+ OUT_DOCK = 145,
+ OUT_BROADCAST = 146,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationMetadataType.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationMetadataType.aidl
new file mode 100644
index 000000000000..0ee0dbb0d8c3
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationMetadataType.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioEncapsulationMetadataType {
+ NONE = 0,
+ FRAMEWORK_TUNER = 1,
+ DVB_AD_DESCRIPTOR = 2,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationMode.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationMode.aidl
new file mode 100644
index 000000000000..0cf2f31217aa
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum AudioEncapsulationMode {
+ INVALID = -1,
+ NONE = 0,
+ ELEMENTARY_STREAM = 1,
+ HANDLE = 2,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationType.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationType.aidl
new file mode 100644
index 000000000000..8a31fc4eb61c
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioEncapsulationType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioEncapsulationType {
+ NONE = 0,
+ IEC61937 = 1,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioFormatDescription.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioFormatDescription.aidl
new file mode 100644
index 000000000000..58c75ebc1ae2
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioFormatDescription.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioFormatDescription {
+ android.media.audio.common.AudioFormatType type = android.media.audio.common.AudioFormatType.DEFAULT;
+ android.media.audio.common.PcmType pcm = android.media.audio.common.PcmType.DEFAULT;
+ @utf8InCpp String encoding;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioFormatType.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioFormatType.aidl
new file mode 100644
index 000000000000..7f55abeeaf0c
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioFormatType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum AudioFormatType {
+ DEFAULT = 0,
+ NON_PCM = 0,
+ PCM = 1,
+ SYS_RESERVED_INVALID = -1,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGain.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGain.aidl
new file mode 100644
index 000000000000..adc5b672eec9
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGain.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioGain {
+ int mode;
+ android.media.audio.common.AudioChannelLayout channelMask;
+ int minValue;
+ int maxValue;
+ int defaultValue;
+ int stepValue;
+ int minRampMs;
+ int maxRampMs;
+ boolean useForVolume;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGainConfig.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGainConfig.aidl
new file mode 100644
index 000000000000..01877c78ede4
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGainConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioGainConfig {
+ int index;
+ int mode;
+ android.media.audio.common.AudioChannelLayout channelMask;
+ int[] values;
+ int rampDurationMs;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGainMode.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGainMode.aidl
new file mode 100644
index 000000000000..fddc20c308d2
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioGainMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum AudioGainMode {
+ JOINT = 0,
+ CHANNELS = 1,
+ RAMP = 2,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioInputFlags.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioInputFlags.aidl
new file mode 100644
index 000000000000..37aa64ae4cee
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioInputFlags.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioInputFlags {
+ FAST = 0,
+ HW_HOTWORD = 1,
+ RAW = 2,
+ SYNC = 3,
+ MMAP_NOIRQ = 4,
+ VOIP_TX = 5,
+ HW_AV_SYNC = 6,
+ DIRECT = 7,
+ ULTRASOUND = 8,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioIoFlags.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioIoFlags.aidl
new file mode 100644
index 000000000000..4a4672506edb
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioIoFlags.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+union AudioIoFlags {
+ int input;
+ int output;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicy.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicy.aidl
new file mode 100644
index 000000000000..98bf0e5849e3
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicy.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioMMapPolicy {
+ UNSPECIFIED = 0,
+ NEVER = 1,
+ AUTO = 2,
+ ALWAYS = 3,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicyInfo.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicyInfo.aidl
new file mode 100644
index 000000000000..7c4f75e9098a
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicyInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioMMapPolicyInfo {
+ android.media.audio.common.AudioDevice device;
+ android.media.audio.common.AudioMMapPolicy mmapPolicy = android.media.audio.common.AudioMMapPolicy.UNSPECIFIED;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicyType.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicyType.aidl
new file mode 100644
index 000000000000..efe8826bba44
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMMapPolicyType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioMMapPolicyType {
+ DEFAULT = 1,
+ EXCLUSIVE = 2,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMode.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMode.aidl
new file mode 100644
index 000000000000..8256c1c81b77
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioMode.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioMode {
+ SYS_RESERVED_INVALID = -2,
+ SYS_RESERVED_CURRENT = -1,
+ NORMAL = 0,
+ RINGTONE = 1,
+ IN_CALL = 2,
+ IN_COMMUNICATION = 3,
+ CALL_SCREEN = 4,
+ SYS_RESERVED_CALL_REDIRECT = 5,
+ SYS_RESERVED_COMMUNICATION_REDIRECT = 6,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioOffloadInfo.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioOffloadInfo.aidl
new file mode 100644
index 000000000000..40bd53b2eb31
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioOffloadInfo.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioOffloadInfo {
+ android.media.audio.common.AudioConfigBase base;
+ android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID;
+ int bitRatePerSecond;
+ long durationUs;
+ boolean hasVideo;
+ boolean isStreaming;
+ int bitWidth = 16;
+ int offloadBufferSize;
+ android.media.audio.common.AudioUsage usage = android.media.audio.common.AudioUsage.INVALID;
+ android.media.audio.common.AudioEncapsulationMode encapsulationMode = android.media.audio.common.AudioEncapsulationMode.INVALID;
+ int contentId;
+ int syncId;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioOutputFlags.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioOutputFlags.aidl
new file mode 100644
index 000000000000..4a512a8049a2
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioOutputFlags.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioOutputFlags {
+ DIRECT = 0,
+ PRIMARY = 1,
+ FAST = 2,
+ DEEP_BUFFER = 3,
+ COMPRESS_OFFLOAD = 4,
+ NON_BLOCKING = 5,
+ HW_AV_SYNC = 6,
+ TTS = 7,
+ RAW = 8,
+ SYNC = 9,
+ IEC958_NONAUDIO = 10,
+ DIRECT_PCM = 11,
+ MMAP_NOIRQ = 12,
+ VOIP_RX = 13,
+ INCALL_MUSIC = 14,
+ GAPLESS_OFFLOAD = 15,
+ SPATIALIZER = 16,
+ ULTRASOUND = 17,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPort.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPort.aidl
new file mode 100644
index 000000000000..970bbc06890f
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPort.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioPort {
+ int id;
+ @utf8InCpp String name;
+ android.media.audio.common.AudioProfile[] profiles;
+ android.media.audio.common.AudioIoFlags flags;
+ android.media.audio.common.ExtraAudioDescriptor[] extraAudioDescriptors;
+ android.media.audio.common.AudioGain[] gains;
+ android.media.audio.common.AudioPortExt ext;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortConfig.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortConfig.aidl
new file mode 100644
index 000000000000..18e6406117dc
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortConfig.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioPortConfig {
+ int id;
+ int portId;
+ @nullable android.media.audio.common.Int sampleRate;
+ @nullable android.media.audio.common.AudioChannelLayout channelMask;
+ @nullable android.media.audio.common.AudioFormatDescription format;
+ @nullable android.media.audio.common.AudioGainConfig gain;
+ @nullable android.media.audio.common.AudioIoFlags flags;
+ android.media.audio.common.AudioPortExt ext;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortDeviceExt.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortDeviceExt.aidl
new file mode 100644
index 000000000000..37d7041731bf
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortDeviceExt.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioPortDeviceExt {
+ android.media.audio.common.AudioDevice device;
+ int flags;
+ android.media.audio.common.AudioFormatDescription[] encodedFormats;
+ const int FLAG_INDEX_DEFAULT_DEVICE = 0;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortExt.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortExt.aidl
new file mode 100644
index 000000000000..af9d9c4d5671
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortExt.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+union AudioPortExt {
+ boolean unspecified;
+ android.media.audio.common.AudioPortDeviceExt device;
+ android.media.audio.common.AudioPortMixExt mix;
+ int session;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortMixExt.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortMixExt.aidl
new file mode 100644
index 000000000000..5b74c0d9f7e4
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortMixExt.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioPortMixExt {
+ int handle;
+ android.media.audio.common.AudioPortMixExtUseCase usecase;
+ int maxOpenStreamCount;
+ int maxActiveStreamCount;
+ int recommendedMuteDurationMs;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortMixExtUseCase.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortMixExtUseCase.aidl
new file mode 100644
index 000000000000..e9acb40a1ab1
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioPortMixExtUseCase.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+union AudioPortMixExtUseCase {
+ boolean unspecified;
+ android.media.audio.common.AudioStreamType stream;
+ android.media.audio.common.AudioSource source;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioProfile.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioProfile.aidl
new file mode 100644
index 000000000000..134cdd98c418
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioProfile.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioProfile {
+ @utf8InCpp String name;
+ android.media.audio.common.AudioFormatDescription format;
+ android.media.audio.common.AudioChannelLayout[] channelMasks;
+ int[] sampleRates;
+ android.media.audio.common.AudioEncapsulationType encapsulationType = android.media.audio.common.AudioEncapsulationType.NONE;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioSource.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioSource.aidl
new file mode 100644
index 000000000000..acf822e5e0a5
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioSource.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioSource {
+ SYS_RESERVED_INVALID = -1,
+ DEFAULT = 0,
+ MIC = 1,
+ VOICE_UPLINK = 2,
+ VOICE_DOWNLINK = 3,
+ VOICE_CALL = 4,
+ CAMCORDER = 5,
+ VOICE_RECOGNITION = 6,
+ VOICE_COMMUNICATION = 7,
+ REMOTE_SUBMIX = 8,
+ UNPROCESSED = 9,
+ VOICE_PERFORMANCE = 10,
+ ECHO_REFERENCE = 1997,
+ FM_TUNER = 1998,
+ HOTWORD = 1999,
+ ULTRASOUND = 2000,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioStandard.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioStandard.aidl
new file mode 100644
index 000000000000..6c4490f0a449
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioStandard.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioStandard {
+ NONE = 0,
+ EDID = 1,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioStreamType.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioStreamType.aidl
new file mode 100644
index 000000000000..bcfd374cb204
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioStreamType.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioStreamType {
+ INVALID = -2,
+ SYS_RESERVED_DEFAULT = -1,
+ VOICE_CALL = 0,
+ SYSTEM = 1,
+ RING = 2,
+ MUSIC = 3,
+ ALARM = 4,
+ NOTIFICATION = 5,
+ BLUETOOTH_SCO = 6,
+ ENFORCED_AUDIBLE = 7,
+ DTMF = 8,
+ TTS = 9,
+ ACCESSIBILITY = 10,
+ ASSISTANT = 11,
+ SYS_RESERVED_REROUTING = 12,
+ SYS_RESERVED_PATCH = 13,
+ CALL_ASSISTANT = 14,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioUsage.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioUsage.aidl
new file mode 100644
index 000000000000..4c7245543cfd
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioUsage.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioUsage {
+ INVALID = -1,
+ UNKNOWN = 0,
+ MEDIA = 1,
+ VOICE_COMMUNICATION = 2,
+ VOICE_COMMUNICATION_SIGNALLING = 3,
+ ALARM = 4,
+ NOTIFICATION = 5,
+ NOTIFICATION_TELEPHONY_RINGTONE = 6,
+ SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST = 7,
+ SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT = 8,
+ SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED = 9,
+ NOTIFICATION_EVENT = 10,
+ ASSISTANCE_ACCESSIBILITY = 11,
+ ASSISTANCE_NAVIGATION_GUIDANCE = 12,
+ ASSISTANCE_SONIFICATION = 13,
+ GAME = 14,
+ VIRTUAL_SOURCE = 15,
+ ASSISTANT = 16,
+ CALL_ASSISTANT = 17,
+ EMERGENCY = 1000,
+ SAFETY = 1001,
+ VEHICLE_STATUS = 1002,
+ ANNOUNCEMENT = 1003,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioUuid.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioUuid.aidl
new file mode 100644
index 000000000000..af307dadf3a3
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/AudioUuid.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioUuid {
+ int timeLow;
+ int timeMid;
+ int timeHiAndVersion;
+ int clockSeq;
+ byte[] node;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/ExtraAudioDescriptor.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/ExtraAudioDescriptor.aidl
new file mode 100644
index 000000000000..2ae2405f544e
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/ExtraAudioDescriptor.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ExtraAudioDescriptor {
+ android.media.audio.common.AudioStandard standard = android.media.audio.common.AudioStandard.NONE;
+ byte[] audioDescriptor;
+ android.media.audio.common.AudioEncapsulationType encapsulationType = android.media.audio.common.AudioEncapsulationType.NONE;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/Int.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/Int.aidl
new file mode 100644
index 000000000000..b0d3c4922531
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/Int.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Int {
+ int value;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/PcmType.aidl b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/PcmType.aidl
new file mode 100644
index 000000000000..79bfa625ba8e
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/1/android/media/audio/common/PcmType.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.audio.common;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum PcmType {
+ DEFAULT = 0,
+ UINT_8_BIT = 0,
+ INT_16_BIT = 1,
+ INT_32_BIT = 2,
+ FIXED_Q_8_24 = 3,
+ FLOAT_32_BIT = 4,
+ INT_24_BIT = 5,
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/.hash b/media/aidl_api/android.media.soundtrigger.types/1/.hash
new file mode 100644
index 000000000000..52fd9ff1c053
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/.hash
@@ -0,0 +1 @@
+8c9bb119feca43f118028b89bd5d1077bc23bb39
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/AudioCapabilities.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/AudioCapabilities.aidl
new file mode 100644
index 000000000000..5d88305484d0
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/AudioCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioCapabilities {
+ ECHO_CANCELLATION = 1,
+ NOISE_SUPPRESSION = 2,
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ConfidenceLevel.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ConfidenceLevel.aidl
new file mode 100644
index 000000000000..5127a110efc5
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ConfidenceLevel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ConfidenceLevel {
+ int userId;
+ int levelPercent;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ModelParameter.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ModelParameter.aidl
new file mode 100644
index 000000000000..aadbf80b4f96
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ModelParameter.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ModelParameter {
+ INVALID = -1,
+ THRESHOLD_FACTOR = 0,
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ModelParameterRange.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ModelParameterRange.aidl
new file mode 100644
index 000000000000..f29b7284a275
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/ModelParameterRange.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ModelParameterRange {
+ int minInclusive;
+ int maxInclusive;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Phrase.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Phrase.aidl
new file mode 100644
index 000000000000..11029ba9d25f
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Phrase.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Phrase {
+ int id;
+ int recognitionModes;
+ int[] users;
+ String locale;
+ String text;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseRecognitionEvent.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseRecognitionEvent.aidl
new file mode 100644
index 000000000000..b75d1b83c72a
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseRecognitionEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable PhraseRecognitionEvent {
+ android.media.soundtrigger.RecognitionEvent common;
+ android.media.soundtrigger.PhraseRecognitionExtra[] phraseExtras;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseRecognitionExtra.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseRecognitionExtra.aidl
new file mode 100644
index 000000000000..e417c69454a5
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseRecognitionExtra.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable PhraseRecognitionExtra {
+ int id;
+ int recognitionModes;
+ int confidenceLevel;
+ android.media.soundtrigger.ConfidenceLevel[] levels;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseSoundModel.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseSoundModel.aidl
new file mode 100644
index 000000000000..b4b3854d4926
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/PhraseSoundModel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable PhraseSoundModel {
+ android.media.soundtrigger.SoundModel common;
+ android.media.soundtrigger.Phrase[] phrases;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Properties.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Properties.aidl
new file mode 100644
index 000000000000..068db52a2a6b
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Properties.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Properties {
+ String implementor;
+ String description;
+ int version;
+ String uuid;
+ String supportedModelArch;
+ int maxSoundModels;
+ int maxKeyPhrases;
+ int maxUsers;
+ int recognitionModes;
+ boolean captureTransition;
+ int maxBufferMs;
+ boolean concurrentCapture;
+ boolean triggerInEvent;
+ int powerConsumptionMw;
+ int audioCapabilities;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionConfig.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionConfig.aidl
new file mode 100644
index 000000000000..63cd2cbbb797
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable RecognitionConfig {
+ boolean captureRequested;
+ android.media.soundtrigger.PhraseRecognitionExtra[] phraseRecognitionExtras;
+ int audioCapabilities;
+ byte[] data;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionEvent.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionEvent.aidl
new file mode 100644
index 000000000000..0209602a1535
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionEvent.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable RecognitionEvent {
+ android.media.soundtrigger.RecognitionStatus status = android.media.soundtrigger.RecognitionStatus.INVALID;
+ android.media.soundtrigger.SoundModelType type = android.media.soundtrigger.SoundModelType.INVALID;
+ boolean captureAvailable;
+ int captureDelayMs;
+ int capturePreambleMs;
+ boolean triggerInData;
+ @nullable android.media.audio.common.AudioConfig audioConfig;
+ byte[] data;
+ boolean recognitionStillActive;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionMode.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionMode.aidl
new file mode 100644
index 000000000000..588291084f4a
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum RecognitionMode {
+ VOICE_TRIGGER = 1,
+ USER_IDENTIFICATION = 2,
+ USER_AUTHENTICATION = 4,
+ GENERIC_TRIGGER = 8,
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionStatus.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionStatus.aidl
new file mode 100644
index 000000000000..7881c28c7ecf
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/RecognitionStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum RecognitionStatus {
+ INVALID = -1,
+ SUCCESS = 0,
+ ABORTED = 1,
+ FAILURE = 2,
+ FORCED = 3,
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/SoundModel.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/SoundModel.aidl
new file mode 100644
index 000000000000..fe382643f3d2
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/SoundModel.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SoundModel {
+ android.media.soundtrigger.SoundModelType type = android.media.soundtrigger.SoundModelType.INVALID;
+ String uuid;
+ String vendorUuid;
+ @nullable ParcelFileDescriptor data;
+ int dataSize;
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/SoundModelType.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/SoundModelType.aidl
new file mode 100644
index 000000000000..ac7864170535
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/SoundModelType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum SoundModelType {
+ INVALID = -1,
+ KEYPHRASE = 0,
+ GENERIC = 1,
+}
diff --git a/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Status.aidl b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Status.aidl
new file mode 100644
index 000000000000..29f3167ac196
--- /dev/null
+++ b/media/aidl_api/android.media.soundtrigger.types/1/android/media/soundtrigger/Status.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media.soundtrigger;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Status {
+ INVALID = -1,
+ SUCCESS = 0,
+ RESOURCE_CONTENTION = 1,
+ OPERATION_NOT_SUPPORTED = 2,
+ TEMPORARY_PERMISSION_DENIED = 3,
+ DEAD_OBJECT = 4,
+ INTERNAL_ERROR = 5,
+}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 491a5cda2950..e7eda3ea4552 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -5898,14 +5898,8 @@ public class AudioManager {
*/
@UnsupportedAppUsage
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public void setWiredDeviceConnectionState(int device, int state, String address,
- String name) {
- final IAudioService service = getService();
- int role = isOutputDevice(device)
- ? AudioDeviceAttributes.ROLE_OUTPUT : AudioDeviceAttributes.ROLE_INPUT;
- AudioDeviceAttributes attributes = new AudioDeviceAttributes(
- role, AudioDeviceInfo.convertInternalDeviceToDeviceType(device), address,
- name, new ArrayList<>()/*mAudioProfiles*/, new ArrayList<>()/*mAudioDescriptors*/);
+ public void setWiredDeviceConnectionState(int device, int state, String address, String name) {
+ AudioDeviceAttributes attributes = new AudioDeviceAttributes(device, address, name);
setWiredDeviceConnectionState(attributes, state);
}
diff --git a/media/tests/aidltests/Android.bp b/media/tests/aidltests/Android.bp
index c3d5fa2ae224..7a25b6d40c1f 100644
--- a/media/tests/aidltests/Android.bp
+++ b/media/tests/aidltests/Android.bp
@@ -33,7 +33,6 @@ android_test {
libs: [
"framework",
],
- sdk_version: "current",
platform_apis: true,
test_suites: ["device-tests"],
certificate: "platform",
diff --git a/mms/OWNERS b/mms/OWNERS
index 2e419c1e529c..7daef4e0dab0 100644
--- a/mms/OWNERS
+++ b/mms/OWNERS
@@ -1,18 +1,4 @@
set noparent
-tgunn@google.com
-breadley@google.com
-rgreenwalt@google.com
-amitmahajan@google.com
-fionaxu@google.com
-jackyu@google.com
-jminjie@google.com
-satk@google.com
-shuoq@google.com
-sarahchin@google.com
-xiaotonj@google.com
-huiwang@google.com
-jayachandranc@google.com
-chinmayd@google.com
-amruthr@google.com
-sasindran@google.com
+file:platform/frameworks/base:/telephony/OWNERS
+
diff --git a/packages/CarrierDefaultApp/OWNERS b/packages/CarrierDefaultApp/OWNERS
index a2352e20f841..447cd512da20 100644
--- a/packages/CarrierDefaultApp/OWNERS
+++ b/packages/CarrierDefaultApp/OWNERS
@@ -1,18 +1,3 @@
set noparent
-tgunn@google.com
-breadley@google.com
-rgreenwalt@google.com
-amitmahajan@google.com
-fionaxu@google.com
-jackyu@google.com
-jminjie@google.com
-satk@google.com
-shuoq@google.com
-sarahchin@google.com
-xiaotonj@google.com
-huiwang@google.com
-jayachandranc@google.com
-chinmayd@google.com
-amruthr@google.com
-sasindran@google.com
+file:platform/frameworks/base:/telephony/OWNERS
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 89205efd6b69..3f86dd5d000c 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Stroom jou foon se programme"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Dienste"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
<string name="summary_generic" msgid="2346762210105903720"></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_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Terug"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Dra programtoestemmings na jou horlosie toe oor"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Om dit makliker te maak om jou horlosie op te stel, sal programme wat gedurende opstelling op jou horlosie geïnstalleer word, dieselfde toestemmings as jou foon gebruik.\n\n Hierdie toestemmings kan toegang tot jou horlosie se mikrofoon en ligging insluit."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 7b699db2e3ad..0c8504768e73 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"የስልክዎን መተግበሪያዎች በዥረት ይልቀቁ"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> የእርስዎን ስልክ ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ለመድረስ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ ላይ እንዲደርስ ይፍቀዱለት"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"ፎቶዎች እና ሚዲያ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"የGoogle Play አገልግሎቶች"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
<string name="consent_no" msgid="2640796915611404382">"አትፍቀድ"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"ተመለስ"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"የመተግበሪያ ፈቃዶችን ወደ የእጅ ሰዓትዎ ያስተላልፉ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"የእጅ ሰዓትዎን ማቀናበርን ለማቅለል በማዋቀር ጊዜ በእጅ ሰዓትዎ ላይ የተጫኑ መተግበሪያዎች እንደ ስልክዎ ተመሳሳይ ፈቃዶችን ይጠቀማሉ።\n\n እነዚህ ፈቃዶች የእጅ ሰዓትዎ ማይክሮፎን እና አካባቢ መዳረሻን ሊያካትቱ ይችላሉ።"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index c8941077732a..32264b431f0c 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Трансліруйце змесціва праграм з вашага тэлефона"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на доступ да фота, медыяфайлаў і апавяшчэнняў вашага тэлефона"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Фота і медыяфайлы"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сэрвісы Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на перадачу праграм плынню паміж вашымі прыладамі"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дазваляць"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перанос дазволаў праграм на ваш гадзіннік"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Для праграм, усталяваных на гадзіннік падчас наладжвання, будуць дзейнічаць тыя самыя дазволы, што і на тэлефоне.\n\n Так гадзіннік можа атрымаць доступ да мікрафона і даных пра месцазнаходжанне."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 110a2214c173..b603cb2b638a 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Поточно предаване на приложенията на телефона ви"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за достъп до снимките, мултимедията и известията на телефона ви"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Снимки и мултимедия"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги за Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
<string name="consent_no" msgid="2640796915611404382">"Забраняване"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Прехвърляне на разрешенията за приложенията към часовника"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"За по-лесно конфигуриране на часовника ви приложенията, инсталирани на него по време на настройването, ще използват същите разрешения като предоставените на телефона ви.\n\nТе може да включват достъп до микрофона и местоположението на часовника ви."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index fb1ede00a257..498ea9a10b9d 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"আপনার ফোনের অ্যাপ স্ট্রিমিংয়ের মাধ্যমে কাস্ট করুন"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-কে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"ফটো ও মিডিয়া"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
<string name="consent_no" msgid="2640796915611404382">"অনুমতি দেবেন না"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"ফিরুন"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"অ্যাপকে দেওয়া অনুমতি আপনার ঘড়িতে ট্রান্সফার করুন"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ঘড়ি আরও সহজে সেট আপ করতে, সেট আপ চলাকালীন আপনার ঘড়িতে ইনস্টল করা অ্যাপ ফোনের মতো একই অনুমতি ব্যবহার করবে।\n\n এইসব অনুমতির মধ্যে আপনার ঘড়ির মাইক্রোফোন ও লোকেশন সম্পর্কে তথ্যের অ্যাক্সেস অন্তর্ভুক্ত থাকতে পারে।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 527a3f207d19..dc7efa0a3650 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -26,7 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Prenosite aplikacije s telefona"</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="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> da pristupi fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima vašeg telefona"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dozvolite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa ovim informacijama s vašeg telefona"</string>
@@ -36,12 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za streamanje aplikacija između vaših uređaja"</string>
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
<string name="consent_no" msgid="2640796915611404382">"Nemoj dozvoliti"</string>
- <string name="consent_back" msgid="2560683030046918882">"Natrag"</string>
+ <string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prijenos odobrenja za aplikaciju na sat"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Radi lakšeg postavljanja sata, aplikacije instalirane na satu tokom postavljanja će koristiti ista odobrenja kao i na telefonu.\n\n Ta odobrenja mogu uključivati pristup mikrofonu i lokaciji sata."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index cfa9ba205ab3..34fc76a6cf63 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Reprodueix en continu aplicacions del telèfon"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per accedir a les fotos, el contingut multimèdia i les notificacions del telèfon"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos i contingut multimèdia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Serveis de Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per reproduir en continu aplicacions entre els dispositius"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
<string name="consent_no" msgid="2640796915611404382">"No permetis"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Enrere"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfereix els permisos de les aplicacions al teu rellotge"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Per facilitar la configuració del rellotge, les aplicacions instal·lades al rellotge durant la configuració utilitzaran els mateixos permisos que al teu telèfon.\n\n Aquests permisos poden incloure l\'accés al micròfon i a la ubicació del rellotge."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index 478136119bf4..e8c7b0983d54 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikace v telefonu"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění k přístupu k fotkám, médiím a oznámením v telefonu"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotky a média"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
<string name="consent_no" msgid="2640796915611404382">"Nepovolovat"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Zpět"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Přesunout oprávnění aplikací do hodinek"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Abychom vám usnadnili nastavení hodinek, aplikace nainstalované do hodinek během úvodního nastavení budou používat stejná oprávnění jako váš telefon.\n\n Tato oprávnění mohou zahrnovat přístup k mikrofonu a poloze hodinek."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 41bbca58c193..df413002ee68 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Stream din telefons apps"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Tillad, at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; får adgang til disse oplysninger fra din telefon"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Billeder og medier"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillad"</string>
<string name="consent_no" msgid="2640796915611404382">"Tillad ikke"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Tilbage"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Overfør apptilladelser til dit ur"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"For at gøre det nemmere at konfigurere dit ur vil de apps, der installeres under konfigurationen, anvende de samme tilladelser som din telefon.\n\n Disse tilladelser kan omfatte adgang til dit urs mikrofon og lokation."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 56a9633176a0..4713c5d6948d 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Μεταδώστε σε ροή τις εφαρμογές του τηλεφώνου σας"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Επιτρέψτε στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να έχει πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Φωτογραφίες και μέσα"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Υπηρεσίες Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
<string name="consent_no" msgid="2640796915611404382">"Να μην επιτρέπεται"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Πίσω"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Μεταφορά αδειών εφαρμογών στο ρολόι σας"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Για να είναι πιο εύκολη η ρύθμιση του ρολογιού σας, οι εφαρμογές που εγκαθίστανται στο ρολόι σας κατά τη ρύθμιση, θα χρησιμοποιούν τις ίδιες άδειες με το τηλέφωνό σας.\n\n Στις άδειες ενδέχεται να περιλαμβάνεται άδεια πρόσβασης στο μικρόφωνο και την τοποθεσία του ρολογιού σας."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 514c2cb18f52..60b136ae1bf2 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Transmitir las apps de tu teléfono"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, el contenido multimedia y las notificaciones de tu teléfono"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para transmitir apps entre dispositivos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfiere los permisos de la app a tu reloj"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para que sea más fácil configurar tu reloj, las apps que se instalen en este durante la configuración usarán los mismos permisos que tu teléfono.\n\n Es posible que estos permisos incluyan el acceso al micrófono y a la ubicación del reloj."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index 79e554cae429..bcf6621ed5b6 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Emite las aplicaciones de tu teléfono"</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 desde tu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, los archivos multimedia y las notificaciones de tu teléfono"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde tu teléfono"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos y elementos multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir permisos de aplicaciones a tu reloj"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para configurar fácilmente tu reloj, las aplicaciones que instales en él durante la configuración usarán los mismos permisos que tengan en tu teléfono.\n\n Estos permisos pueden incluir acceso al micrófono y a la ubicación del reloj."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 52b0d4d54541..49483ec46a54 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefoni rakenduste voogesitamine"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
<string name="consent_no" msgid="2640796915611404382">"Ära luba"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Tagasi"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Rakenduste lubade kellale ülekandmine"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Selleks et muuta kella seadistamine lihtsamaks, kasutavad teie kellas seadistamise ajal installitud rakendused samasid lubasid, mis neile telefonis antud on.\n\n Need load võivad hõlmata juurdepääsuluba kella mikrofonile ja asukohale."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index fafbe23b3a39..ec0ac2001449 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Igorri zuzenean telefonoko 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 bat baino gehiagotarako zerbitzuak"</string>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak atzitzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Eman informazio hori telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Argazkiak eta multimedia-edukia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
<string name="summary_generic" msgid="2346762210105903720"></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_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Atzera"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferitu aplikazio-baimenak erlojura"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Erlojua errazago konfiguratzeko, konfigurazio-prozesua abian zen bitartean erlojuan instalatutako aplikazioek telefonoak darabiltzan baimen berak erabiliko dituzte.\n\n Baliteke baimen horien artean erlojuaren mikrofonoa eta kokapena atzitzeko baimenak egotea."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index b212b5fdb9c4..663d7c5d9cc5 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"جاری‌سازی برنامه‌های تلفن"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه می‌خواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> به عکس‌ها، رسانه، و اعلان‌های تلفن شما دسترسی پیدا کند"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; مجاز می‌شود به این اطلاعات در دستگاهتان دسترسی پیدا کند"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"عکس‌ها و رسانه‌ها"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"‏خدمات Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه می‌خواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> برنامه‌ها را بین دستگاه‌های شما جاری‌سازی کند"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"مجاز است"</string>
<string name="consent_no" msgid="2640796915611404382">"مجاز نبودن"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"برگشت"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"انتقال اجازه‌های برنامه به ساعت"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"برای آسان‌تر کردن راه‌اندازی ساعت، برنامه‌های نصب‌شده در ساعت درحین راه‌اندازی از همان اجازه‌های تلفن استفاده خواهند کرد.\n\n ممکن است این اجازه‌ها شامل دسترسی به میکروفون و مکان ساعت باشد."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index cde38646dc5c..b10dc6951e98 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Striimaa puhelimen sovelluksia"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteeltasi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Salli pääsy tähän tietoon puhelimellasi: &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Kuvat ja media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Palvelut"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteeltasi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) lupaa striimata sovelluksia laitteidesi välillä"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Salli"</string>
<string name="consent_no" msgid="2640796915611404382">"Älä salli"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Takaisin"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Siirrä sovellusluvat kelloon"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Sovellukset, jotka on asennettu kelloon käyttöönoton aikana, käyttävät samoja lupia kuin puhelin. Näin kello on helpompi ottaa käyttöön.\n\n Näihin lupiin saattaa kuulua pääsy kellon mikrofoniin ja sijaintiin."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 3b2eeff389d6..8d2b99e95696 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Diffusez les applications de votre téléphone"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Retour"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transférer les autorisations de l\'application à votre montre"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Pour faciliter la configuration de votre montre, les applications installées sur celle-ci reprennent les mêmes autorisations que celles installées sur votre téléphone.\n\n Ces autorisations peuvent comprendre l\'accès au microphone et à la position de votre montre."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 9c54bac87b91..e6167cd8e2fb 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Caster les applis de votre téléphone"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, contenus multimédias et notifications de votre téléphone"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos et contenus multimédias"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Retour"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transférer les autorisations de l\'appli vers la montre"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Pour que votre montre soit plus facile à configurer, les applis qui y sont installées pendant la configuration utiliseront les mêmes autorisations que votre téléphone.\n\n Il peut s\'agir, par exemple, de l\'accès au micro et à la position de votre montre."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 275d7dc1b61d..3a948630ea34 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Emite as aplicacións do teu teléfono"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para acceder ás fotos, ao contido multimedia e ás notificacións do teléfono"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permitir que &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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e contido multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servizos de Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para emitir aplicacións entre os teus aparellos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Non permitir"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir os permisos de aplicacións ao reloxo"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para que che resulte máis doado configurar o reloxo, as aplicacións que instales nel durante a configuración usarán os mesmos permisos que o teléfono.\n\n Entre estes permisos poden estar incluídos os de acceso ao micrófono e á localización do teléfono."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index baf0b9f55be1..1ea2de1ad792 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"A telefon alkalmazásainak streamelése"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében a telefonon tárolt fotókhoz, médiatartalmakhoz és értesítésekhez való hozzáféréshez"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-szolgáltatások"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
<string name="summary_generic" msgid="2346762210105903720"></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_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Vissza"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Alkalmazásengedélyek átvitele az órára"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Az óra beállításának megkönnyítése érdekében a beállítás során az órára telepített alkalmazások ugyanazokat az engedélyeket használják majd, mint a telefonja.\n\n Ezek az engedélyek magukban foglalhatják az óra mikrofonjához és helyadataihoz való hozzáférést."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 8a6ae3f46ae6..592a6c33624f 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Հեռարձակել հեռախոսի հավելվածները"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր հեռախոսի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Լուսանկարներ և մուլտիմեդիա"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
<string name="consent_no" msgid="2640796915611404382">"Չթույլատրել"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Հետ"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Հավելվածների թույլտվությունների տեղափոխում ժամացույց"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Կարգավորման ժամանակ ժամացույցում տեղադրված հավելվածների համար կօգտագործվեն նույն թույլտվությունները, ինչ հեռախոսում։\n\n Այդ թույլտվությունները կարող են ներառել ժամացույցի խոսափողի կամ տեղադրության տվյալների օգտագործումը։"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 225967920afb..905f7c548f2c 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Melakukan streaming aplikasi ponsel 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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk mengakses foto, media, dan notifikasi ponsel Anda"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses informasi ini dari ponsel Anda"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
<string name="consent_no" msgid="2640796915611404382">"Jangan izinkan"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer izin aplikasi ke smartwatch"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Untuk mempermudah penyiapan smartwatch, aplikasi yang diinstal di smartwatch selama penyiapan akan menggunakan izin yang sama dengan ponsel.\n\n Izin ini dapat meliputi akses ke mikrofon dan lokasi smartwatch."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index 3e559485b11f..b389184cf9ae 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streymdu forritum símans"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um aðgang að myndum, margmiðlunarefni og tilkynningum símans þíns fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Myndir og efni"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Þjónusta Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um heimild fyrir straumspilun forrita á milli tækjanna þinna fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
<string name="consent_no" msgid="2640796915611404382">"Ekki leyfa"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Til baka"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Flytja heimildir forrita yfir í úrið"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Til að auðvelda uppsetningu úrsins munu forrit sem eru sett upp í úrinu við uppsetningu nota sömu heimildir og stilltar eru í símanum.\n\n Þessar heimildir kunna að fela í sér aðgang að hljóðnema og staðsetningu úrsins."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 5f04e0f03dd1..ccf7e5557a51 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Trasmetti in streaming le app del tuo telefono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Consenti all\'app &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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione ad accedere a foto, contenuti multimediali e notifiche del telefono"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a questa informazione dal tuo telefono"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto e contenuti multimediali"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
<string name="consent_no" msgid="2640796915611404382">"Non consentire"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Indietro"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Trasferisci le autorizzazioni app all\'orologio"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Per facilitare la configurazione dell\'orologio, le app installate su quest\'ultimo durante la configurazione useranno le stesse autorizzazioni delle app sul telefono.\n\n Queste autorizzazioni potrebbero includere l\'accesso al microfono e alla posizione dell\'orologio."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index d8af8aa1e44a..2f9c7e4f8bdb 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"שידור אפליקציות מהטלפון"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור ה‑<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"תמונות ומדיה"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור ה‑<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
<string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"חזרה"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"העברת ההרשאות הניתנות לאפליקציות אל השעון שלך"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"כדי לפשט את הגדרת השעון, אפליקציות שמותקנות במהלך ההגדרה יקבלו את אותן הרשאות שניתנו בטלפון.\n\n ההרשאות האלה עשויות לכלול גישה למיקרופון ולמיקום של השעון."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index 54371c7ef725..7c887ffc66ab 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"スマートフォンのアプリのストリーミング"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってスマートフォンの写真、メディア、通知にアクセスする権限をリクエストしています"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"このスマートフォンからの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"写真とメディア"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 開発者サービス"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"許可"</string>
<string name="consent_no" msgid="2640796915611404382">"許可しない"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"戻る"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"スマートウォッチへのアプリの権限の移行"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"スマートウォッチのセットアップを簡単にするため、セットアップ時にスマートウォッチにインストールされたアプリに、スマートフォンと同じ権限が適用されます。\n\n これらの権限には、スマートウォッチのマイクや位置情報へのアクセス権も含まれることがあります。"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index f0c3dc98f380..5b56c33441ae 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"თქვენი ტელეფონის აპების სტრიმინგი"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ წვდომა ჰქონდეს თქვენი ტელეფონის ფოტოებზე, მედიასა და შეტყობინებებზე"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ნება დართეთ, რომ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"ფოტოები და მედია"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის სტრიმინგი შეძლოს"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
<string name="consent_no" msgid="2640796915611404382">"არ დაიშვას"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"უკან"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"აპის ნებართვების საათისთვის გადაცემა"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"საათის დაყენების გასამარტივებლად თქვენს საათში დაინსტალირებული აპები იმავე ნებართვებს გამოიყენებს, რასაც ტელეფონზე იყენებს.\n\n ეს ნებართვები, შესაძლოა, მოიცავდეს თქვენი საათის მიკროფონსა და მდებარეობაზე წვდომას."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 6e46869ab293..67d3e8e8786f 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Телефон қолданбаларын трансляциялайды."</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан телефондағы фотосуреттерді, медиафайлдар мен хабарландыруларды пайдалану үшін рұқсат сұрайды."</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотосуреттер мен медиафайлдар"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play қызметтері"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
<string name="consent_no" msgid="2640796915611404382">"Рұқсат бермеу"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Артқа"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Қолданба рұқсаттарын сағатқа ауыстыру"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Реттеу кезінде сағатқа орнатылған қолданбалар телефондағыдай рұқсаттарды пайдаланады. Осылайша сағат оңай реттеледі.\n\n Бұл рұқсаттар сағаттың микрофоны мен геодерегін пайдалануды қамтиды."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 814b327cc4f9..6c9c87475f18 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"បញ្ចាំងកម្មវិធីរបស់ទូរសព្ទអ្នក"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីចូលប្រើរូបថត មេឌៀ និងការជូនដំណឹងរបស់ទូរសព្ទអ្នក"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលមើលព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"រូបថត និងមេឌៀ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"សេវាកម្ម Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
<string name="consent_no" msgid="2640796915611404382">"កុំអនុញ្ញាត"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"ថយក្រោយ"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ផ្ទេរការអនុញ្ញាតកម្មវិធីទៅនាឡិការបស់អ្នក"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ដើម្បីជួយឱ្យការរៀបចំនាឡិការបស់អ្នកកាន់តែងាយស្រួល កម្មវិធីដែលបានដំឡើងនៅលើនាឡិការបស់អ្នកអំឡុងពេលរៀបចំនឹងប្រើការអនុញ្ញាតដូចគ្នានឹងទូរសព្ទរបស់អ្នកដែរ។\n\n ការអនុញ្ញាតទាំងនេះអាចរួមបញ្ចូលសិទ្ធិចូលប្រើទីតាំង និងមីក្រូហ្វូនរបស់នាឡិកាអ្នក។"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 35ca2032e13b..8a3ad35ff309 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"휴대전화의 앱을 스트리밍합니다."</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 휴대전화의 사진, 미디어, 알림에 액세스할 수 있는 권한을 요청하고 있습니다."</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"사진 및 미디어"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 서비스"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"허용"</string>
<string name="consent_no" msgid="2640796915611404382">"허용 안함"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"뒤"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"앱 권한을 시계로 이전"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"시계를 더 쉽게 설정하기 위해 설정하는 동안 시계에 설치된 앱에서 휴대전화와 동일한 권한을 사용합니다.\n\n 이러한 권한에는 시계의 마이크 및 위치 정보에 대한 액세스가 포함될 수 있습니다."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 0f1d82e07012..51252975b45f 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Телефондогу колдонмолорду алып ойнотуу"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медианы жана билдирмелерди колдонууга уруксат сурап жатат"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Сүрөттөр жана медиа"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду тышкы экранга чыгарууга уруксат сурап жатат"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Уруксат берүү"</string>
<string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Артка"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Колдонмонун уруксаттарын саатка өткөрүү"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Сааттын жөндөлүшүн жеңилдетүү үчүн жөндөө учурунда саатыңызга орнотулган колдонмолор телефонуңуздагы уруксаттарды колдонот.\n\n Мындай уруксаттарга саатыңыздын микрофонун же жайгашкан жерин колдонуу кириши мүмкүн."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index e353659fe6db..42400a0543e9 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ສະຕຣີມແອັບຂອງໂທລະສັບທ່ານ"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອເຂົ້າເຖິງຮູບພາບ, ມີເດຍ ແລະ ການແຈ້ງເຕືອນຂອງໂທລະສັບທ່ານ"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"ຮູບພາບ ແລະ ມີເດຍ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"ບໍລິການ Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຂອງທ່ານ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
<string name="consent_no" msgid="2640796915611404382">"ບໍ່ອະນຸຍາດ"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"ກັບຄືນ"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ໂອນຍ້າຍການອະນຸຍາດແອັບໄປຫາໂມງຂອງທ່ານ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ເພື່ອເຮັດໃຫ້ຕັ້ງຄ່າໂມງຂອງທ່ານໄດ້ງ່າຍຂຶ້ນ, ແອັບທີ່ຕິດຕັ້ງຢູ່ໂມງຂອງທ່ານໃນລະຫວ່າງການຕັ້ງຄ່າຈະໃຊ້ການອະນຸຍາດດຽວກັນກັບໂທລະສັບຂອງທ່ານ.\n\n ການອະນຸຍາດເຫຼົ່ານີ້ອາດຮວມສິດເຂົ້າເຖິງໄມໂຄຣໂຟນ ແລະ ສະຖານທີ່ຂອງທ່ານນຳ."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index c795c0d86efd..f79ea0767fd4 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefono programų perdavimas srautu"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų pasiekti telefono nuotraukas, mediją ir pranešimus"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Nuotraukos ir medija"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"„Google Play“ paslaugos"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
<string name="consent_no" msgid="2640796915611404382">"Neleisti"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Atgal"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Laikrodžio programų perkėlimo leidimai"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Kad būtų lengviau nustatyti laikrodį, jame atliekant sąranką įdiegtoms programoms bus naudojami tie patys leidimai kaip jūsų telefone.\n\n Šie leidimai gali apimti prieigą prie laikrodžio mikrofono ir vietovės."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 6ee557be8bf9..ce4f7ac9129a 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Var straumēt jūsu tālruņa lietotnes"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju piekļūt jūsu tālruņa fotoattēliem, multivides saturam un paziņojumiem šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotoattēli un multivides faili"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play pakalpojumi"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<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="DEVICE_TYPE">%2$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
<string name="consent_no" msgid="2640796915611404382">"Neatļaut"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Atpakaļ"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Lietotņu atļauju pārsūtīšana uz pulksteni"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Lai atvieglotu pulksteņa iestatīšanu, iestatīšanas laikā pulkstenī instalētās lietotnes saņems tādas pašas atļaujas, kādas tām ir tālrunī.\n\n Tostarp lietotnes var saņemt atļauju piekļūt pulksteņa mikrofonam un atrašanās vietai."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index d2aa48ca7cbc..30e6820d9712 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"फोनवरील ॲप्स स्ट्रीम करा"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"तुमच्या फोनमधील फोटो, मीडिया आणि सूचना ॲक्सेस करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवा"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
<string name="consent_no" msgid="2640796915611404382">"अनुमती देऊ नका"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"मागे जा"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"अ‍ॅप परवानग्या तुमच्या वॉचवर ट्रान्सफर करा"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"तुमचे वॉच सेट करणे आणखी सोपे करण्यासाठी, सेटअपदरम्यान तुमच्या वॉचवर इंस्टॉल केलेली ॲप्स ही तुमच्या फोनप्रमाणेच परवानग्या वापरतील.\n\n या परवानग्यांमध्ये तुमच्या वॉचचा मायक्रोफोन आणि स्थानाच्या अ‍ॅक्सेसचा समावेश असू शकतो."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 96e346e3b3ac..31663e34d927 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"သင့်ဖုန်းရှိအက်ပ်များကို တိုက်ရိုက်လွှင့်နိုင်သည်"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် သင်၏ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"ဓာတ်ပုံနှင့် မီဒီယာများ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ဝန်ဆောင်မှုများ"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် သင်၏ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
<string name="consent_no" msgid="2640796915611404382">"ခွင့်မပြုပါ"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"နောက်သို့"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"သင်၏နာရီသို့ အက်ပ်ခွင့်ပြုချက်များ လွှဲပြောင်းရန်"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"သင်၏နာရီ စနစ်ထည့်သွင်းရာတွင် ပိုလွယ်ကူစေရန် စနစ်ထည့်သွင်းနေစဉ်အတွင်း နာရီတွင်ထည့်သွင်းသော အက်ပ်များသည် သင့်ဖုန်းနှင့် အလားတူခွင့်ပြုချက်များကို သုံးပါမည်။\n\n ဤခွင့်ပြုချက်များတွင် သင့်နာရီ၏ မိုက်ခရိုဖုန်းနှင့် တည်နေရာတို့ကို သုံးခွင့် ပါဝင်နိုင်သည်။"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 8bbe71b501fa..3f4db79064f3 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Strøm appene på telefonen"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> for å få tilgang til bilder, medier og varsler på telefonen din"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Bilder og medier"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> for å strømme apper mellom enhetene dine"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillat"</string>
<string name="consent_no" msgid="2640796915611404382">"Ikke tillat"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Tilbake"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Overfør apptillatelser til klokken din"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"For å gjøre det enklere å konfigurere klokken din bruker apper som installeres på klokken under konfigureringen, samme tillatelser som på telefonen.\n\n Disse tillatelsene kan inkludere tilgang til mikrofonen på klokken og posisjon."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 2a27219275a6..b13741e4340c 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"आफ्नो फोनका एपहरू प्रयोग गर्नुहोस्"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंको फोनमा भएका फोटो, मिडिया र सूचनाहरू हेर्ने तथा प्रयोग गर्ने अनुमति माग्दै छ"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"फोटो र मिडिया"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
<string name="consent_no" msgid="2640796915611404382">"अनुमति नदिनुहोस्"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"पछाडि"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"एपलाई दिइएका अनुमति घडीमा ट्रान्स्फर गर्नुहोस्"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"तपाईंको घडी सेटअप गर्ने कार्य सजिलो बनाउनका लागि सेटअप गर्ने क्रममा तपाईंको घडीमा इन्स्टल गरिएका एपहरूले पनि तपाईंको फोनमा दिइएको जस्तै अनुमति प्रयोग गर्ने छन्।\n\n यी अनुमतिमा तपाईंको घडीको माइक्रोफोन र लोकेसन प्रयोग गर्ने जस्ता अनुमति पर्न सक्छन्।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 3b27f9dc6deb..4001c811d9a9 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"De apps van je telefoon streamen"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-services"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string>
<string name="consent_no" msgid="2640796915611404382">"Niet toestaan"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Terug"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"App-rechten overzetten naar je horloge"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"We willen het makkelijker voor je maken om je horloge in te stellen. Daarom gebruiken apps die tijdens het instellen worden geïnstalleerd op je horloge, dezelfde rechten als op je telefoon.\n\n Deze rechten kunnen toegang tot de microfoon en locatie van je horloge omvatten."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 540a1db03cbf..888f6e3864a9 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ଆପଣଙ୍କ ଫୋନର ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରନ୍ତୁ"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"ଆପଣଙ୍କ ଫୋନର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"ଫଟୋ ଏବଂ ମିଡିଆ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ସେବାଗୁଡ଼ିକ"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="consent_no" msgid="2640796915611404382">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"ପଛକୁ ଫେରନ୍ତୁ"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ଆପଣଙ୍କ ୱାଚକୁ ଆପ ଅନୁମତିଗୁଡ଼ିକ ଟ୍ରାନ୍ସଫର କରନ୍ତୁ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ଆପଣଙ୍କ ୱାଚ ସେଟ ଅପ କରିବାକୁ ସହଜ କରିବା ପାଇଁ, ସେଟଅପ ସମୟରେ ଆପଣଙ୍କର ୱାଚରେ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ଆପଗୁଡ଼ିକ ଆପଣଙ୍କ ଫୋନରେ ଥିବା ଆପଗୁଡ଼ିକ ପରି ସମାନ ଅନୁମତିଗୁଡ଼ିକ ବ୍ୟବହାର କରିବ।\n\n ଏହି ଅନୁମତିଗୁଡ଼ିକରେ ଆପଣଙ୍କ ୱାଚର ମାଇକ୍ରୋଫୋନ ଏବଂ ଲୋକେସନକୁ ଆକ୍ସେସ ଅନ୍ତର୍ଭୁକ୍ତ ହୋଇପାରେ।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 04199d696429..8f16c54ec1cd 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ਆਪਣੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰੋ"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ਸੇਵਾਵਾਂ"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ਇਜਾਜ਼ਤ ਦਿਓ"</string>
<string name="consent_no" msgid="2640796915611404382">"ਇਜਾਜ਼ਤ ਨਾ ਦਿਓ"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"ਪਿੱਛੇ"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ਐਪ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਆਪਣੀ ਘੜੀ \'ਤੇ ਟ੍ਰਾਂਸਫ਼ਰ ਕਰੋ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ਤੁਹਾਡੀ ਘੜੀ ਦਾ ਸੈੱਟਅੱਪ ਕਰਨਾ ਆਸਾਨ ਬਣਾਉਣ ਲਈ, ਤੁਹਾਡੀ ਘੜੀ \'ਤੇ ਸਥਾਪਤ ਐਪਾਂ ਸੈੱਟਅੱਪ ਦੌਰਾਨ ਉਹੀ ਇਜਾਜ਼ਤਾਂ ਵਰਤਣਗੀਆਂ ਜੋ ਤੁਹਾਡਾ ਫ਼ੋਨ ਵਰਤਦਾ ਹੈ।\n\n ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਵਿੱਚ ਤੁਹਾਡੀ ਘੜੀ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਤੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index e5f8553101a6..840323854852 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Odtwarzaj strumieniowo aplikacje z telefonu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Zezwól aplikacji &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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące dostępu do zdjęć, multimediów i powiadomień na telefonie"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Zezwól aplikacji &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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Zdjęcia i multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Usługi Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania aplikacji między urządzeniami"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
<string name="consent_no" msgid="2640796915611404382">"Nie zezwalaj"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Wstecz"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Przenieś uprawnienia aplikacji na zegarek"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Aby łatwiej było skonfigurować zegarek, aplikacje zainstalowane na nim podczas konfiguracji będą korzystały z tych samych uprawnień co telefon.\n\n Może to oznaczać dostęp do mikrofonu i lokalizacji na zegarku."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 7cd3a37d0f34..7f081f0c9f4d 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</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 essas informações do smartphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorizar que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse essas informações do smartphone"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir as permissões de apps para o relógio"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do relógio, os apps instalados nele durante a configuração vão usar as mesmas permissões que o smartphone.\n\n Essas permissões podem incluir acesso ao microfone ou à localização do relógio."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index de412ebc9df0..6b0ac35c9ff7 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Faça stream das apps do telemóvel"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para aceder às fotos, conteúdo multimédia e notificações do seu telemóvel"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e multimédia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfira as autorizações da app para o seu relógio"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do seu relógio, as apps instaladas no mesmo durante a configuração utilizarão as mesmas autorizações que o telemóvel.\n\n Estas autorizações podem incluir o acesso ao microfone e à localização do seu relógio."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 7cd3a37d0f34..7f081f0c9f4d 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</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 essas informações do smartphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorizar que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse essas informações do smartphone"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir as permissões de apps para o relógio"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do relógio, os apps instalados nele durante a configuração vão usar as mesmas permissões que o smartphone.\n\n Essas permissões podem incluir acesso ao microfone ou à localização do relógio."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 3fe10b30bfb7..2b24fa212bf7 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Трансляция приложений с телефона."</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы получить доступ к фотографиям, медиаконтенту и уведомлениям на телефоне."</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; получать эту информацию с вашего телефона"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотографии и медиафайлы"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает доступ от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы транслировать приложения между вашими устройствами."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
<string name="consent_no" msgid="2640796915611404382">"Запретить"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перенос разрешений для приложений на часы"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Для приложений, установленных на часы во время настройки, будут использоваться те же разрешения, что и на телефоне.\n\n Например, может быть включен доступ к микрофону на часах или сведениям о местоположении."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 548e0c207252..94078a49db86 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ඔබගේ දුරකථනයේ යෙදුම් ප්‍රවාහ කරන්න"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්‍ය සහ දැනුම්දීම් වෙත ප්‍රවේශ වීමට අවසරය ඉල්ලමින් සිටී"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"ඡායාරූප සහ මාධ්‍ය"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play සේවා"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්‍රවාහ කිරීමට අවසරය ඉල්ලමින් සිටී"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
<string name="consent_no" msgid="2640796915611404382">"ඉඩ නොදෙන්න"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"ආපසු"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ඔබගේ ඔරලෝසුවට යෙදුම් අවසර මාරු කිරීම"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ඔබගේ ඔරලෝසුව පිහිටුවීම පහසු කිරීමට, පිහිටුවීමේදී ඔබගේ ඔරලෝසුවේ ස්ථාපනය කර ඇති යෙදුම් ඔබගේ දුරකථනයට සමාන අවසර භාවිත කරනු ඇත.\n\n මෙම අවසරවලට ඔබගේ ඔරලෝසුවේ මයික්‍රෆෝනයට සහ ස්ථානයට ප්‍රවේශය ඇතුළත් විය හැකිය."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 878d26461a49..9a5c87ea6ac9 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikácie telefónu"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotky a médiá"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
<string name="consent_no" msgid="2640796915611404382">"Nepovoliť"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Späť"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Presun povolení aplikácie do hodiniek"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"V rámci zjednodušenia nastavenia hodiniek budú aplikácie nainštalované do hodiniek pri nastavovaní používať rovnaké povolenia ako váš telefón.\n\n Tieto povolenia môžu zahrnovať prístup k mikrofónu a polohe hodiniek."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 0734ee1ff271..e28ba2f6ead7 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Pretočno predvajanje aplikacij telefona"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za dostop do fotografij, predstavnosti in obvestil v telefonu."</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografije in predstavnost"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Storitve Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne dovoli"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Nazaj"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prenos dovoljenj za aplikacije v uro"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Za lažjo nastavitev ure bodo aplikacije, ki so bile med nastavljanjem nameščene v uri, uporabljale enaka dovoljenja kot tiste v telefonu.\n\n Ta dovoljenja lahko vključujejo dostop do mikrofona in lokacije ure."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index 7352a0dbdc52..ba13505e1438 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Transmeto aplikacionet e telefonit tënd"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografitë dhe media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
<string name="consent_no" msgid="2640796915611404382">"Mos lejo"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Pas"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfero lejet e aplikacionit te ora jote"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Për ta bërë më të lehtë konfigurimin e orës, aplikacionet e instaluara në orën tënde gjatë konfigurimit do të përdorin të njëjtat leje si telefoni yt.\n\n Këto leje mund të përfshijnë qasje në mikrofonin dhe vendndodhjen e orës."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 198c3081750d..19a245658727 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streama telefonens appar"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att ge <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> åtkomst till foton, mediefiler och aviseringar på telefonen"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Foton och media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjänster"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> streama appar mellan enheter"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="2346762210105903720"></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_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Tillbaka"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Överför appbehörigheter till klockan"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Appar som installeras på klockan under konfigureringen får samma behörigheter som de har på telefonen så att konfigureringen ska bli enklare.\n\n Behörigheterna kan omfatta åtkomst till klockans mikrofon och plats."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index a0f99dd2fe9d..68a15348b506 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Tiririsha programu za simu 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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili kufikia picha, maudhui na arifa za simu yako"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Picha na maudhui"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Huduma za Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili kutiririsha programu kati ya vifaa vyako"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
<string name="consent_no" msgid="2640796915611404382">"Usiruhusu"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Nyuma"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Hamishia idhini za programu kwenye saa yako"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Ili kurahisisha kuweka mipangilio ya saa yako, programu ambazo zimesakinishwa kwenye saa yako wakati wa kuweka mipangilio zitatumia ruhusa sawa na zinazotumika kwenye simu yako.\n\n Ruhusa hizi huenda zikajumuisha ufikiaji wa maikrofoni ya saa yako na maelezo ya mahali ilipo saa yako."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 37031ef28b26..8e0938ba004a 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun uygulamalarını akışla aktarın"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotoğraflar ve medya"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play hizmetleri"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
<string name="consent_no" msgid="2640796915611404382">"İzin verme"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Geri"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Uygulama izinlerini saatinize aktarma"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Kurulum sırasında saatinize yüklenen uygulamalar, saat kurulumunuzu kolaylaştırmak için telefonunuzla aynı izinleri kullanır.\n\n Saatinizin mikrofonuna ve konumuna erişim bu izinlere dahil olabilir."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index b90f507808f0..3638058d2707 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Транслювати додатки телефона"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на доступ до фотографій, медіафайлів і сповіщень вашого телефона"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Надайте додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотографії та медіафайли"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сервіси Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на трансляцію додатків між вашими пристроями"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дозволяти"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перенести дозволи для додатків на годинник"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Задля зручності додатки, установлені на годиннику протягом налаштування, використовуватимуть ті самі дозволи, що й на телефоні.\n\n До таких дозволів може належати доступ до мікрофона й геоданих годинника."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index cc7ca6e094ca..455f9efce52f 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefondagi ilovalarni translatsiya qilish"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Telefoningizdagi rasm, media va bildirishnomalarga kirish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Suratlar va media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xizmatlari"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
<string name="consent_no" msgid="2640796915611404382">"Ruxsat berilmasin"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Orqaga"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Ilova uchun ruxsatlarni soatingizga uzating"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Soatingizni sozlashni qulaylashtirish maqsadida sozlash paytida soatingizga oʻrnatilgan ilovalar telefoningiz bilan bir xil ruxsatlardan foydalanadi.\n\n Bunday ruxsatlarga soatingiz mikrofoni va joylashuv axborotiga ruxsatlar kirishi mumkin."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 32efbec5c8be..0cc362b8d49e 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Truyền các ứng dụng trên điện thoại 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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"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>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"Ảnh và nội dung nghe nhìn"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Dịch vụ Google Play"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%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>
<string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
<string name="summary_generic" msgid="2346762210105903720"></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_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"Quay lại"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Chuyển quyền cho ứng dụng sang đồng hồ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Để thiết lập đồng hồ dễ dàng hơn, trong quá trình thiết lập, các ứng dụng được cài đặt trên đồng hồ của bạn sẽ sử dụng các quyền giống như trên điện thoại.\n\n Các quyền này có thể bao gồm quyền sử dụng micrô và thông tin vị trí của đồng hồ."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 42d93eb13857..5286d75eb983 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"流式传输手机的应用内容"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求访问您手机上的照片、媒体内容和通知"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允许 &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 访问您手机中的这项信息"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"照片和媒体内容"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允许"</string>
<string name="consent_no" msgid="2640796915611404382">"不允许"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"返回"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"将应用权限转让给手表"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"为了让您更轻松地设置手表,在设置过程中安装在手表上的应用将使用与手机相同的权限。\n\n这些权限可能包括使用手表的麦克风和位置信息。"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index d665d0f0c0d7..1e6f515e17f5 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"串流播放手機應用程式內容"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求必要權限,以便存取手機上的相片、媒體和通知"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取您手機中的這項資料"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求必要權限,以便在裝置之間串流應用程式內容"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允許"</string>
<string name="consent_no" msgid="2640796915611404382">"不允許"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"返回"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"將應用程式權限轉移至手錶"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"為簡化手錶的設定程序,在設定過程中安裝到手錶上的應用程式都將沿用手機上的權限。\n\n這些權限可能包括手錶麥克風和位置的存取權。"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 68958ad67fba..9cb91d0f1ef7 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -26,8 +26,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"串流傳輸手機應用程式內容"</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>
- <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便存取手機上的相片、媒體和通知"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取你手機中的這項資訊"</string>
@@ -37,14 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
- <!-- no translation found for helper_summary_computer (1676407599909474428) -->
- <skip />
+ <string name="helper_summary_computer" msgid="1676407599909474428">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便在裝置之間串流傳輸應用程式內容"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允許"</string>
<string name="consent_no" msgid="2640796915611404382">"不允許"</string>
- <!-- no translation found for consent_back (2560683030046918882) -->
- <skip />
+ <string name="consent_back" msgid="2560683030046918882">"返回"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"將應用程式權限轉移到手錶上"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"為簡化手錶的設定程序,只要是在設定過程中安裝到手錶上的應用程式,都將沿用手機上的權限。\n\n 這些權限可能包括手錶的麥克風和位置資訊存取權。"</string>
</resources>
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index 3a3565941489..55626844594d 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -110,6 +110,7 @@ public class DynamicSystemInstallationService extends Service
private static final int EVENT_DSU_PROGRESS_UPDATE = 120000;
private static final int EVENT_DSU_INSTALL_COMPLETE = 120001;
private static final int EVENT_DSU_INSTALL_FAILED = 120002;
+ private static final int EVENT_DSU_INSTALL_INSUFFICIENT_SPACE = 120003;
protected static void logEventProgressUpdate(
String partitionName,
@@ -136,6 +137,10 @@ public class DynamicSystemInstallationService extends Service
EventLog.writeEvent(EVENT_DSU_INSTALL_FAILED, cause);
}
+ protected static void logEventInsufficientSpace() {
+ EventLog.writeEvent(EVENT_DSU_INSTALL_INSUFFICIENT_SPACE);
+ }
+
/*
* IPC
*/
@@ -258,6 +263,8 @@ public class DynamicSystemInstallationService extends Service
if (result == RESULT_CANCELLED) {
logEventFailed("Dynamic System installation task is canceled by the user.");
+ } else if (detail instanceof InstallationAsyncTask.InsufficientSpaceException) {
+ logEventInsufficientSpace();
} else {
logEventFailed("error: " + detail);
}
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags
index 407314384be8..8d8be1030b8e 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/EventLogTags.logtags
@@ -5,3 +5,4 @@ option java_package com.android.dynsystem
120000 dsu_progress_update (partition_name|3),(installed_bytes|2|5),(total_bytes|2|5),(partition_number|1|5),(total_partition_number|1|5),(total_progress_percentage|1|5)
120001 dsu_install_complete
120002 dsu_install_failed (cause|3)
+120003 dsu_install_insufficient_space
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 38d851eb76aa..62e53d62fd2a 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -18,6 +18,7 @@ package com.android.dynsystem;
import android.content.Context;
import android.gsi.AvbPublicKey;
+import android.gsi.IGsiService;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@@ -27,6 +28,7 @@ import android.os.SystemProperties;
import android.os.image.DynamicSystemManager;
import android.service.persistentdata.PersistentDataBlockManager;
import android.util.Log;
+import android.util.Pair;
import android.util.Range;
import android.webkit.URLUtil;
@@ -106,8 +108,15 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
}
}
+ static class InsufficientSpaceException extends IOException {
+ InsufficientSpaceException(String message) {
+ super(message);
+ }
+ }
+
/** UNSET means the installation is not completed */
static final int RESULT_UNSET = 0;
+
static final int RESULT_OK = 1;
static final int RESULT_CANCELLED = 2;
static final int RESULT_ERROR_IO = 3;
@@ -157,6 +166,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
private final boolean mIsNetworkUrl;
private final boolean mIsDeviceBootloaderUnlocked;
private final boolean mWantScratchPartition;
+ private int mCreatePartitionStatus;
private DynamicSystemManager.Session mInstallationSession;
private KeyRevocationList mKeyRevocationList;
@@ -364,7 +374,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
mIsZip = true;
} else {
throw new UnsupportedFormatException(
- String.format(Locale.US, "Unsupported file format: %s", mUrl));
+ String.format(Locale.US, "Unsupported file format: %s", mUrl));
}
if (mIsNetworkUrl) {
@@ -435,14 +445,19 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
throws IOException {
Log.d(TAG, "Creating writable partition: " + partitionName + ", size: " + partitionSize);
- Thread thread = new Thread() {
- @Override
- public void run() {
- mInstallationSession =
- mDynSystem.createPartition(
- partitionName, partitionSize, /* readOnly= */ false);
- }
- };
+ mCreatePartitionStatus = 0;
+ mInstallationSession = null;
+ Thread thread =
+ new Thread() {
+ @Override
+ public void run() {
+ Pair<Integer, DynamicSystemManager.Session> result =
+ mDynSystem.createPartition(
+ partitionName, partitionSize, /* readOnly = */ false);
+ mCreatePartitionStatus = result.first;
+ mInstallationSession = result.second;
+ }
+ };
initPartitionProgress(partitionName, partitionSize, /* readonly = */ false);
publishProgress(/* installedSize = */ 0L);
@@ -468,13 +483,17 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
}
}
- if (prevInstalledSize != partitionSize) {
- publishProgress(partitionSize);
- }
-
if (mInstallationSession == null) {
- throw new IOException(
- "Failed to start installation with requested size: " + partitionSize);
+ if (mCreatePartitionStatus == IGsiService.INSTALL_ERROR_NO_SPACE
+ || mCreatePartitionStatus == IGsiService.INSTALL_ERROR_FILE_SYSTEM_CLUTTERED) {
+ throw new InsufficientSpaceException(
+ "Failed to create "
+ + partitionName
+ + " partition: storage media has insufficient free space");
+ } else {
+ throw new IOException(
+ "Failed to start installation with requested size: " + partitionSize);
+ }
}
// Reset installation session and verify that installation completes successfully.
@@ -482,6 +501,11 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
if (!mDynSystem.closePartition()) {
throw new IOException("Failed to complete partition installation: " + partitionName);
}
+
+ // Ensure a 100% mark is published.
+ if (prevInstalledSize != partitionSize) {
+ publishProgress(partitionSize);
+ }
}
private void installScratch() throws IOException {
@@ -606,10 +630,19 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
throw new IOException("Cannot get raw size for " + partitionName);
}
- Thread thread = new Thread(() -> {
- mInstallationSession =
- mDynSystem.createPartition(partitionName, partitionSize, true);
- });
+ mCreatePartitionStatus = 0;
+ mInstallationSession = null;
+ Thread thread =
+ new Thread() {
+ @Override
+ public void run() {
+ Pair<Integer, DynamicSystemManager.Session> result =
+ mDynSystem.createPartition(
+ partitionName, partitionSize, /* readOnly = */ true);
+ mCreatePartitionStatus = result.first;
+ mInstallationSession = result.second;
+ }
+ };
Log.d(TAG, "Start creating partition: " + partitionName);
thread.start();
@@ -627,8 +660,16 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
}
if (mInstallationSession == null) {
- throw new IOException(
- "Failed to start installation with requested size: " + partitionSize);
+ if (mCreatePartitionStatus == IGsiService.INSTALL_ERROR_NO_SPACE
+ || mCreatePartitionStatus == IGsiService.INSTALL_ERROR_FILE_SYSTEM_CLUTTERED) {
+ throw new InsufficientSpaceException(
+ "Failed to create "
+ + partitionName
+ + " partition: storage media has insufficient free space");
+ } else {
+ throw new IOException(
+ "Failed to start installation with requested size: " + partitionSize);
+ }
}
Log.d(TAG, "Start installing: " + partitionName);
@@ -688,11 +729,6 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
installedSize += numBytesRead;
}
- // Ensure a 100% mark is published.
- if (prevInstalledSize != partitionSize) {
- publishProgress(partitionSize);
- }
-
AvbPublicKey avbPublicKey = new AvbPublicKey();
if (!mInstallationSession.getAvbPublicKey(avbPublicKey)) {
imageValidationThrowOrWarning(new PublicKeyException("getAvbPublicKey() failed"));
@@ -708,6 +744,11 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
if (!mDynSystem.closePartition()) {
throw new IOException("Failed to complete partition installation: " + partitionName);
}
+
+ // Ensure a 100% mark is published.
+ if (prevInstalledSize != partitionSize) {
+ publishProgress(partitionSize);
+ }
}
private static String toHexString(byte[] bytes) {
diff --git a/packages/SettingsLib/AndroidManifest.xml b/packages/SettingsLib/AndroidManifest.xml
index 13f8a372c9b5..3e67abfe1960 100644
--- a/packages/SettingsLib/AndroidManifest.xml
+++ b/packages/SettingsLib/AndroidManifest.xml
@@ -22,6 +22,16 @@
<activity
android:name="com.android.settingslib.users.AvatarPickerActivity"
android:theme="@style/SudThemeGlifV2.DayNight"/>
+
+ <activity
+ android:name="com.android.settingslib.qrcode.QrCodeScanModeActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.settings.BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+
</application>
</manifest>
diff --git a/packages/SettingsLib/HelpUtils/res/values-ar/strings.xml b/packages/SettingsLib/HelpUtils/res/values-ar/strings.xml
index 5b12fc586ef9..0eba119d58ee 100644
--- a/packages/SettingsLib/HelpUtils/res/values-ar/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-ar/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="help_feedback_label" msgid="7106780063063027882">"المساعدة والملاحظات والآراء"</string>
+ <string name="help_feedback_label" msgid="7106780063063027882">"المساعدة والملاحظات"</string>
</resources>
diff --git a/packages/SettingsLib/res/drawable-v31/settingslib_tabs_background.xml b/packages/SettingsLib/res/drawable-v31/settingslib_tabs_background.xml
index f10b56315546..5378eeef97e0 100644
--- a/packages/SettingsLib/res/drawable-v31/settingslib_tabs_background.xml
+++ b/packages/SettingsLib/res/drawable-v31/settingslib_tabs_background.xml
@@ -18,6 +18,8 @@
android:color="?android:colorControlHighlight">
<item android:id="@android:id/mask">
<inset
+ android:insetTop="6dp"
+ android:insetBottom="6dp"
android:insetLeft="4dp"
android:insetRight="4dp">
<shape android:shape="rectangle">
@@ -29,8 +31,10 @@
<item android:id="@android:id/background">
<inset
- android:insetLeft="4dp"
- android:insetRight="4dp">
+ android:insetTop="6dp"
+ android:insetBottom="6dp"
+ android:insetLeft="4dp"
+ android:insetRight="4dp">
<shape android:shape="rectangle">
<solid android:color="@color/settingslib_colorSurface" />
<corners android:radius="12dp" />
diff --git a/packages/SettingsLib/res/drawable-v31/settingslib_tabs_indicator_background.xml b/packages/SettingsLib/res/drawable-v31/settingslib_tabs_indicator_background.xml
index f5a97825870c..9c10a5b59281 100644
--- a/packages/SettingsLib/res/drawable-v31/settingslib_tabs_indicator_background.xml
+++ b/packages/SettingsLib/res/drawable-v31/settingslib_tabs_indicator_background.xml
@@ -15,6 +15,8 @@
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetTop="6dp"
+ android:insetBottom="6dp"
android:insetLeft="4dp"
android:insetRight="4dp">
<shape android:shape="rectangle">
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 0a3178a9a42a..cffd1f65b267 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Kon nie \'n nuwe gebruiker skep nie"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Kon nie ’n nuwe gas skep nie"</string>
<string name="user_nickname" msgid="262624187455825083">"Bynaam"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Voeg gebruiker by"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Voeg gas by"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Verwyder gas"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Stel gassessie terug"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Stel gassessie terug?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Verwyder gas?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Stel terug"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Stel tans gassessie terug …"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Kies foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Te veel verkeerde pogings. Hierdie toestel se data sal uitgevee word."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Te veel verkeerde pogings. Hierdie gebruiker sal uitgevee word."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Te veel verkeerde pogings. Hierdie werkprofiel en die data daarin sal uitgevee word."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Maak toe"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Toestelverstek"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Gedeaktiveer"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Geaktiveer"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Skakel skerm aan"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Laat toe dat die skerm aangeskakel word"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Laat ’n program toe om die skerm aan te skakel. As jy toestemming gee, kan die program die skerm enige tyd sonder jou uitdruklike bedoeling aanskakel."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index a55cb4f7c628..26c46f183f76 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"አዲስ ተጠቃሚን መፍጠር አልተሳካም"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"አዲስ እንግዳ መፍጠር አልተሳካም"</string>
<string name="user_nickname" msgid="262624187455825083">"ቅጽል ስም"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"ተጠቃሚን አክል"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"እንግዳን አክል"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"እንግዳን አስወግድ"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"እንግዳን ዳግም አስጀምር"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"እንግዳ ዳግም ይጀምር?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"እንግዳ ይወገድ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ዳግም አስጀምር"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"እንግዳን ዳግም በማስጀመር ላይ…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ፎቶ አንሳ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ምስል ይምረጡ"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ፎቶ ይምረጡ"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"በጣም ብዙ ትክክል ያልሆኑ ሙከራዎች። የዚህ መሣሪያ ውሂብ ይሰረዛል።"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"በጣም ብዙ ትክክል ያልሆኑ ሙከራዎች። ይህ ተጠቃሚ ይሰረዛል።"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"በጣም ብዙ ትክክል ያልሆኑ ሙከራዎች። የዚህ የሥራ መገለጫ እና ውሂቡ ይሰረዛሉ።"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"አሰናብት"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"የመሣሪያ ነባሪ"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ተሰናክሏል"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ነቅቷል"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 56e88cf0dddd..5b5cbbbe9d06 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -549,7 +549,7 @@
<string name="media_transfer_this_phone" msgid="7194341457812151531">"هذا الهاتف"</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>
+ <string name="help_label" msgid="3528360748637781274">"المساعدة والملاحظات"</string>
<string name="storage_category" msgid="2287342585424631813">"مساحة التخزين"</string>
<string name="shared_data_title" msgid="1017034836800864953">"البيانات المشتركة"</string>
<string name="shared_data_summary" msgid="5516326713822885652">"عرض البيانات المشتركة وتعديلها"</string>
@@ -598,6 +598,8 @@
<!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
<skip />
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"إعادة الضبط"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"جارٍ إعادة ضبط جلسة الضيف…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"التقاط صورة"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"اختيار صورة"</string>
@@ -657,4 +659,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index bb8fb28856d9..2919e4db40e7 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"অতিথিৰ ছেশ্বন ৰিছেট কৰিবনে?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"অতিথি আঁতৰাবনে?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ৰিছেট কৰক"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"অতিথিৰ ছেশ্বন ৰিছেট কৰি থকা হৈছে…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"এখন ফট’ তোলক"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index ece3956fbe4d..cd50bcc6b5c6 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Qonaq məlumatı sıfırlansın?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Qonaq silinsin?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Sıfırlayın"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Qonaq məlumatı sıfırlanır…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Foto çəkin"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Şəkil seçin"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ekranı aktiv etmək"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Ekranı aktiv etməyə icazə verin"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Tətbiqin ekranı aktiv etməsinə icazə verin. İcazə verilərsə, tətbiq istənilən vaxt sizə soruşmadan ekranı aktiv edə bilər."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index e7c281397e2d..936aec7f05bc 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Želite li da resetujete sesiju gosta?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Želite li da uklonite gosta?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Sesija gosta se resetuje…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Uključite ekran"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Dozvoli uključivanje ekrana"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dozvoljava aplikaciji da uključi ekran. Ako se omogući, aplikacija može da uključi ekran u bilo kom trenutku bez vaše eksplicitne namere."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index ddc155c37d60..86b3519d05d8 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Не ўдалося стварыць новага карыстальніка"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Не ўдалося стварыць новага госця"</string>
<string name="user_nickname" msgid="262624187455825083">"Псеўданім"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Дадаць карыстальніка"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Дадаць госця"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Выдаліць госця"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Скінуць гасцявы сеанс"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Скінуць гасцявы сеанс?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Выдаліць госця?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Скінуць"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Ідзе скід гасцявога сеанса…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Зрабіць фота"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Выбраць відарыс"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Выбраць фота"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Занадта шмат няўдалых спроб. Даныя з гэтай прылады будуць выдалены."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Занадта шмат няўдалых спроб. Гэты карыстальнік будзе выдалены."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Занадта шмат няўдалых спроб. Гэты працоўны профіль і звязаныя з ім даныя будуць выдалены."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Закрыць"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Стандартная прылада"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Выключана"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Уключана"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 0398c1851da6..758a7079065c 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Неуспешно създаване на нов потребител"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Създаването на нов гост не бе успешно"</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Добавяне на потребител"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавяне на гост"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Премахване на госта"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Нулиране на сесията като гост"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Да се нулира ли сесията като гост?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Да се премахне ли гостът?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Нулиране"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Сесията като гост се нулира…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Правене на снимка"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Избиране на изображение"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Избиране на снимката"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Твърде много неправилни опити. Данните от това устройство ще бъдат изтрити."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Твърде много неправилни опити. Този потребител ще бъде изтрит."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Твърде много неправилни опити. Този служебен потребителски профил и данните в него ще бъдат изтрити."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Отхвърляне"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Стандартна настройка за у-вото"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Деактивирано"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Активирано"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index a0cf42bb79cd..ad83af675390 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"নতুন ব্যবহারকারী যোগ করা যায়নি"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"নতুন অতিথি তৈরি করা যায়নি"</string>
<string name="user_nickname" msgid="262624187455825083">"বিশেষ নাম"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"ব্যবহারকারীর অ্যাকাউন্ট যোগ করুন"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ করুন"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি সরান"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"অতিথি সেশন রিসেট করুন"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"গেস্ট সেশন রিসেট করবেন?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"অতিথিকে সরাবেন?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"রিসেট করুন"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"গেস্ট সেশন রিসেট করা হচ্ছে..."</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ফটো তুলুন"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"একটি ইমেজ বেছে নিন"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ফটো বেছে নিন"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"একাধিকবার ভুল ইনপুট দিয়েছেন। এই ডিভাইসের ডেটা মুছে ফেলা হবে।"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"একাধিকবার ভুল ইনপুট দিয়েছেন। এই ব্যবহারকারীর প্রোফাইল মুছে ফেলা হবে।"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"একাধিকবার ভুল ইনপুট দিয়েছেন। এই অফিস প্রোফাইল ও এর ডেটা মুছে ফেলা হবে।"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"বাতিল করুন"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ডিভাইসের ডিফল্ট"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"বন্ধ করা আছে"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"চালু করা আছে"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index faa7333e7dfd..9b972ab10227 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -589,20 +589,22 @@
<string name="add_user_failed" msgid="4809887794313944872">"Kreiranje novog korisnika nije uspjelo"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Kreiranje novog gosta nije uspjelo"</string>
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
- <string name="user_add_user" msgid="7876449291500212468">"Dodavanje korisnika"</string>
+ <string name="user_add_user" msgid="7876449291500212468">"Dodaj korisnika"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Poništi sesiju gosta"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Poništiti sesiju gosta?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Ukloniti gosta?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Poništi"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Poništavanje sesije gosta…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Odabir fotografije"</string>
- <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Previše netočnih pokušaja. S uređaja će se izbrisati podaci."</string>
- <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Previše netočnih pokušaja. Ovaj će se korisnik izbrisati."</string>
- <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Previše netočnih pokušaja. Ovaj će se radni profil izbrisati zajedno sa svim svojim podacima."</string>
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Previše je neispravnih pokušaja. Podaci ovog uređaja će se izbrisati."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Previše je neispravnih pokušaja. Ovaj korisnik će se izbrisati."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Previše je neispravnih pokušaja. Ovaj poslovni profil i njegovi podaci će se izbrisati."</string>
<string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Odbaci"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Zadana postavka uređaja"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Onemogućeno"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Uključi ekran"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Dozvolite uključivanje ekrana"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dozvolite aplikaciji da uključi ekran. Ako se odobri, aplikacija može uključiti ekran bilo kada bez vaše izričite namjere."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 0c95e18d3c75..342172846618 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -311,7 +311,7 @@
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"No s\'ha pogut connectar"</string>
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostra les opcions per a la certificació de pantalla sense fil"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Augmenta el nivell de registre de la connexió Wi‑Fi i es mostra per SSID RSSI al selector de Wi‑Fi"</string>
- <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Redueix el consum de bateria i millora el rendiment de la xarxa"</string>
+ <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Exhaureix menys la bateria i millora el rendiment de la xarxa"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Quan aquest mode està activat, és possible que l’adreça MAC d\'aquest dispositiu canviï cada vegada que es connecti a una xarxa amb l\'aleatorització d\'adreces MAC activada."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"D\'ús mesurat"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"D\'ús no mesurat"</string>
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"No s\'ha pogut crear l\'usuari"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"No s\'ha pogut crear un convidat"</string>
<string name="user_nickname" msgid="262624187455825083">"Àlies"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Afegeix un usuari"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Afegeix un convidat"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Suprimeix el convidat"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Restableix el convidat"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Vols restablir el convidat?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Vols suprimir el convidat?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restableix"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"S\'està restablint el convidat…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Selecciona una foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Has superat el nombre d\'intents incorrectes permesos. Les dades d\'aquest dispositiu se suprimiran."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Has superat el nombre d\'intents incorrectes permesos. Aquest usuari se suprimirà."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Has superat el nombre d\'intents incorrectes permesos. Aquest perfil de treball i les dades que contingui se suprimiran."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Ignora"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Opció predeter. del dispositiu"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desactivat"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Activa la pantalla"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permet que activi la pantalla"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permet que una aplicació activi la pantalla. Si concedeixes aquest permís, pot ser que l\'aplicació activi la pantalla en qualsevol moment sense la teva intenció explícita."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 5780f7deef67..4240b14ac8c3 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nového uživatele se nepodařilo vytvořit"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Vytvoření nového hosta se nezdařilo"</string>
<string name="user_nickname" msgid="262624187455825083">"Přezdívka"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Přidat uživatele"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Přidat hosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odstranit hosta"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Resetovat hosta"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Resetovat hosta?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Odstranit hosta?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetovat"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Resetování hosta…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Pořídit fotku"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrat obrázek"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Vybrat fotku"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Příliš mnoho neplatných pokusů. Data v tomto zařízení budou smazána."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Příliš mnoho neplatných pokusů. Tento uživatel bude smazán."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Příliš mnoho neplatných pokusů. Tento pracovní profil a přidružená data budou smazána."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Zavřít"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Výchozí nastavení zařízení"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Vypnuto"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuto"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Zapínat obrazovku"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Povolit zapínání obrazovky"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Povolte aplikaci zapínat obrazovku. Pokud aplikace bude mít toto oprávnění, může kdykoli zapnout obrazovku bez explicitního intentu."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 91009aa24674..24d613cba5cf 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Der kunne ikke oprettes en ny bruger"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Der kunne ikke oprettes en ny gæst"</string>
<string name="user_nickname" msgid="262624187455825083">"Kaldenavn"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Tilføj bruger"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tilføj gæst"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gæsten"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Nulstil gæstesession"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Vil du nulstille gæsten?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Vil du fjerne gæsten?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nulstil"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Nulstiller gæst…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tag et billede"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Vælg et billede"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Vælg billede"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"For mange forkerte forsøg. Dataene på denne enhed slettes."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"For mange forkerte forsøg. Denne bruger slettes."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"For mange forkerte forsøg. Denne arbejdsprofil og de tilhørende data slettes."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Luk"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Enhedens standardindstilling"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiveret"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiveret"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Aktivér skærmen"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Tillad aktivering af skærmen"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Tillad, at en app aktiverer skærmen. Hvis du giver denne tilladelse, kan appen til enhver tid aktiverer skærmen, uden at du eksplicit har bedt om det."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 2be9872817c4..51f12fc435fc 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Gast zurücksetzen?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Gast entfernen?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Zurücksetzen"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Gast wird zurückgesetzt…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Foto machen"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Bild auswählen"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Display aktivieren"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Aktivieren des Displays erlauben"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Einer App erlauben, das Display zu aktivieren. Wenn du diese Erlaubnis erteilst, kann die App jederzeit das Display aktivieren – auch ohne deine explizite Absicht."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index d0460487abe7..3aec04bfb9c6 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Η δημιουργία νέου χρήστη απέτυχε"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Αποτυχία δημιουργίας νέου προσκεκλημένου"</string>
<string name="user_nickname" msgid="262624187455825083">"Ψευδώνυμο"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Προσθήκη χρήστη"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Προσθήκη επισκέπτη"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Κατάργηση επισκέπτη"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Επαναφορά περιόδου επισκέπτη"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Επαναφορά επισκέπτη;"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Κατάργηση επισκέπτη;"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Επαναφορά"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Επαναφορά επισκέπτη…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Επιλογή φωτογραφίας"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Πάρα πολλές ανεπιτυχείς προσπάθειες. Τα δεδομένα αυτής της συσκευής θα διαγραφούν."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Πάρα πολλές ανεπιτυχείς προσπάθειες. Αυτός ο χρήστης θα διαγραφεί."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Πάρα πολλές ανεπιτυχείς προσπάθειες. Αυτό το προφίλ εργασίας και τα δεδομένα του θα διαγραφούν."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Παράβλεψη"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Προεπιλογή συσκευής"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Ανενεργή"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ενεργή"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 59f5b835db64..b76d447aafcf 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remove guest?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Turn screen on"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Allow turning the screen on"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Allow an app to turn the screen on. If granted, the app may turn on the screen at any time without your explicit intent."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 24bd421e3a8f..76161cf194d1 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remove guest?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Turn screen on"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Allow turning the screen on"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Allow an app to turn the screen on. If granted, the app may turn on the screen at any time without your explicit intent."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 59f5b835db64..b76d447aafcf 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remove guest?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Turn screen on"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Allow turning the screen on"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Allow an app to turn the screen on. If granted, the app may turn on the screen at any time without your explicit intent."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 59f5b835db64..b76d447aafcf 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remove guest?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Turn screen on"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Allow turning the screen on"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Allow an app to turn the screen on. If granted, the app may turn on the screen at any time without your explicit intent."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index b5c5a8469c3d..cda94e95ea78 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -596,6 +596,7 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎Reset guest?‎‏‎‎‏‎"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎Remove guest?‎‏‎‎‏‎"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‎Reset‎‏‎‎‏‎"</string>
+ <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎Remove‎‏‎‎‏‎"</string>
<string name="guest_resetting" msgid="7822120170191509566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎Resetting guest…‎‏‎‎‏‎"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎Take a photo‎‏‎‎‏‎"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎Choose an image‎‏‎‎‏‎"</string>
@@ -651,4 +652,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‎‎‎Turn screen on‎‏‎‎‏‎"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎Allow turning the screen on‎‏‎‎‏‎"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎Allow an app to turn the screen on. If granted, the app may turn on the screen at any time without your explicit intent.‎‏‎‎‏‎"</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 43144e95a200..b46f432b1fa2 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"No se pudo crear el usuario nuevo"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"No se pudo crear un nuevo invitado"</string>
<string name="user_nickname" msgid="262624187455825083">"Sobrenombre"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Agregar usuario"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Agregar invitado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer perfil de invitado"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"¿Quieres restablecer el invitado?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"¿Quieres quitar al invitado?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tomar una foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Elegir una imagen"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Hubo demasiados intentos incorrectos. Se borrarán los datos de este dispositivo."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Hubo demasiados intentos incorrectos. Se borrará este usuario."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Hubo demasiados intentos incorrectos. Se borrarán este perfil de trabajo y sus datos."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Descartar"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Predeterminado del dispositivo"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inhabilitado"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Activar pantalla"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permitir activación de la pantalla"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permite que una app active la pantalla. Si se otorga permiso, la app podría activar la pantalla en cualquier momento sin que lo pidas de manera explícita."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 508a74b22888..8590d0fab526 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"No se ha podido crear el usuario"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"No se ha podido crear un nuevo invitado"</string>
<string name="user_nickname" msgid="262624187455825083">"Apodo"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Añadir usuario"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Añadir invitado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer invitado"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"¿Restablecer invitado?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"¿Quitar invitado?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Ha habido demasiados intentos fallidos. Los datos de este dispositivo se eliminarán."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Ha habido demasiados intentos fallidos. Este usuario se eliminará."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Ha habido demasiados intentos fallidos. Este perfil de trabajo y sus datos se eliminarán."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Cerrar"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Predeterminado por el dispositivo"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inhabilitado"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Encender pantalla"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permitir encender la pantalla"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permite que una aplicación encienda la pantalla. Si das este permiso, la aplicación puede encender la pantalla en cualquier momento sin que se lo pidas."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 3f1cc1991404..b9c9ead45598 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Uue kasutaja loomine ebaõnnestus"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Uue külalise loomine ei õnnestunud"</string>
<string name="user_nickname" msgid="262624187455825083">"Hüüdnimi"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Kasutaja lisamine"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisa külaline"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Lähtesta külastajaseanss"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Kas lähtestada külastajaseanss?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Kas eemaldada külaline?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Lähtesta"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Külastajaseansi lähtestamine …"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Valige foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Liiga palju valesid katseid. Selle seadme andmed kustutatakse."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Liiga palju valesid katseid. See kasutaja kustutatakse."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Liiga palju valesid katseid. See tööprofiil ja selle andmed kustutatakse."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Loobu"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Seadme vaikeseade"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Keelatud"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Lubatud"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ekraani sisselülitamine"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Luba ekraani sisselülitamine"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Rakendusel lubatakse ekraan sisse lülitada. Kui annate loa, võib rakendus ekraani igal ajal sisse lülitada ilma teie sõnaselge kavatsuseta."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index a7041d9802b4..efa45690fd33 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -109,12 +109,9 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Ezk. gailuaren bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. Esk- gailuaren bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktibo"</string>
- <!-- no translation found for bluetooth_hearing_aid_left_active (7084887715570971441) -->
- <skip />
- <!-- no translation found for bluetooth_hearing_aid_right_active (8574683234077567230) -->
- <skip />
- <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (407704460573163973) -->
- <skip />
+ <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktibo, ezkerreko audifonoa soilik"</string>
+ <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktibo, eskuineko audifonoa soilik"</string>
+ <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktibo, ezkerreko eta eskuineko audifonoak"</string>
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Euskarriaren audioa"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefono-deiak"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fitxategi-transferentzia"</string>
@@ -592,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Ezin izan da sortu erabiltzailea"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Ezin izan da sortu beste gonbidatu bat"</string>
<string name="user_nickname" msgid="262624187455825083">"Goitizena"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Gehitu erabiltzaile bat"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gehitu gonbidatua"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Kendu gonbidatua"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Berrezarri gonbidatuentzako saioa"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Gonbidatuentzako saioa berrezarri nahi duzu?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Gonbidatua kendu nahi duzu?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Berrezarri"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Gonbidatuentzako saioa berrezartzen…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Hautatu argazki bat"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Saiakera oker gehiegi egin dituzu. Gailu honetako datuak ezabatu egingo dira."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Saiakera oker gehiegi egin dituzu. Erabiltzailea ezabatu egingo da."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Saiakera oker gehiegi egin dituzu. Laneko profila eta bertako datuak ezabatu egingo dira."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Baztertu"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Gailuaren balio lehenetsia"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desgaituta"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Gaituta"</string>
@@ -660,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Piztu pantaila"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Eman pantaila pizteko baimena"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Eman pantaila pizteko baimena aplikazioei. Baimena emanez gero, aplikazioek edonoiz piztu ahal izango dute pantaila, zuk halako asmorik izan ez arren."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 3f19420bb27e..22a98abc1edc 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"کاربر جدید ایجاد نشد"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"مهمان جدید ایجاد نشد"</string>
<string name="user_nickname" msgid="262624187455825083">"نام مستعار"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"افزودن کاربر"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"افزودن مهمان"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"حذف مهمان"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"بازنشانی مهمان"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"جلسه مهمان بازنشانی شود؟"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"مهمان برداشته شود؟"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"بازنشانی"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"درحال بازنشانی مهمان…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"عکس گرفتن"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"انتخاب تصویر"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"انتخاب عکس"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"تلاش‌های نادرست بسیار زیادی انجام شده است. داده‌های این دستگاه حذف خواهد شد."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"تلاش‌های اشتباه بسیار زیادی انجام شده است. این کاربر حذف خواهد شد."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"تلاش‌های اشتباه بسیار زیادی انجام شده است. این نمایه کاری و داده‌های آن‌ حذف خواهند شد."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"رد شدن"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"پیش‌فرض دستگاه"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"غیرفعال"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 55f9c56371ab..cea4e9c8ffee 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Uuden käyttäjän luominen epäonnistui"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Uutta vierasta ei voitu luoda"</string>
<string name="user_nickname" msgid="262624187455825083">"Lempinimi"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Lisää käyttäjä"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Nollaa vieras"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Nollataanko vieras?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Poistetaaanko vieras?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nollaa"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Nollataan vierasta…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Valitse kuva"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Liian monta virheellistä yritystä. Laitteen data poistetaan."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Liian monta virheellistä yritystä. Tämä käyttäjä poistetaan."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Liian monta virheellistä yritystä. Tämä työprofiili ja sen data poistetaan."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Ohita"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Laitteen oletusasetus"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Ei käytössä"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Käytössä"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Käynnistä näyttö"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Salli näytön käynnistäminen"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Salli sovelluksen käynnistää näyttö. Jos sovellus saa luvan, se voi käynnistää näytön itsenäisesti milloin tahansa."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 0886acacada9..e78be6054441 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Impossible de créer un utilisateur"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Impossible de créer un nouvel invité"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudo"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Ajouter un utilisateur"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Réinitialiser la session Invité"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Réinitialiser la session Invité?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Retirer l\'invité?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Réinitialiser"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Réinitialisation de la session Invité en cours…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Sélectionner une image"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionnez une photo"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Trop de tentatives incorrectes. Les données de cet appareil seront supprimées."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Trop de tentatives incorrectes. Cet utilisateur sera supprimé."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Trop de tentatives incorrectes. Ce profil professionnel sera supprimé, y compris ses données."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Fermer"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Valeur par défaut de l\'appareil"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Désactivé"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Activation de l\'écran"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Autoriser l\'activation de l\'écran"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autorisez une application à activer l\'écran. Lorsque vous accordez cette autorisation, l\'application peut activer l\'écran à tout moment sans votre volonté explicite."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 04db494571fb..f2a1814e81f2 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Échec de la création d\'un utilisateur"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Impossible de créer un profil invité"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudo"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Ajouter un utilisateur"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Réinitialiser la session Invité"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Réinitialiser la session Invité ?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Supprimer l\'invité ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Réinitialiser"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Réinitialisation de la session Invité…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choisir une image"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionner une photo"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Trop de tentatives incorrectes. Les données de cet appareil vont être supprimées."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Trop de tentatives incorrectes. Ce compte utilisateur va être supprimé."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Trop de tentatives incorrectes. Ce profil professionnel et les données associées vont être supprimés."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Fermer"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Paramètre par défaut"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Désactivé"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Activer l\'écran"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Autoriser l\'activation de l\'écran"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autoriser une appli à activer l\'écran. Si l\'autorisation est accordée, l\'appli peut activer l\'écran à tout moment sans votre intention explicite."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 2f4f1d763fa3..9e55f8e41f2b 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Non se puido crear un novo usuario"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Produciuse un erro ao crear o convidado"</string>
<string name="user_nickname" msgid="262624187455825083">"Alcume"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Engadir usuario"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engadir convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar convidado"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer sesión de convidado"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Queres restablecer a sesión de convidado?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Queres quitar o convidado?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Restablecendo sesión de convidado…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escoller imaxe"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Realizaches demasiados intentos incorrectos. Eliminaranse os datos deste dispositivo."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Realizaches demasiados intentos incorrectos. Eliminarase este usuario."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Realizaches demasiados intentos incorrectos. Eliminaranse este perfil de traballo e os datos asociados."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Ignorar"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Funcionamento predeterminado"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desactivado"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activado"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Activar a pantalla"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permitir activación da pantalla"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permite que unha aplicación active a pantalla. Se lle dás permiso, a aplicación poderá activar a pantalla en calquera momento sen que llo pidas."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 5f31d4adeb6c..391536389cfd 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"અતિથિને રીસેટ કરીએ?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"અતિથિને કાઢી નાખીએ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"રીસેટ કરો"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"અતિથિને રીસેટ કરી રહ્યાં છીએ…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ફોટો લો"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"છબી પસંદ કરો"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 214a922bf147..622e33d80fc3 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"क्या आप मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट करना चाहते हैं?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"क्या मेहमान को हटाना है?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रीसेट करें"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट किया जा रहा है…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"फ़ोटो खींचें"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"कोई इमेज चुनें"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 8ffbd549c446..05e9557c952c 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Poništiti gostujuću sesiju?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Ukloniti gosta?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Poništi"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Poništavanje gostujuće sesije…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Uključivanje zaslona"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Dopusti uključivanje zaslona"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dopustite aplikaciji da uključuje zaslon. Ako date to dopuštenje, aplikacija može uključiti zaslon u bilo kojem trenutku bez vaše izričite namjere."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index f9571b83c333..c244416342f6 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Az új felhasználó létrehozása sikertelen"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Az új vendég létrehozása nem sikerült"</string>
<string name="user_nickname" msgid="262624187455825083">"Becenév"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Felhasználó hozzáadása"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Vendég hozzáadása"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Vendég munkamenet eltávolítása"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Vendég munkamenet visszaállítása"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Visszaállítja a vendég munkamenetet?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Eltávolítja a vendéget?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Visszaállítás"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Vendég munkamenet visszaállítása…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Fotó kiválasztása"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Túl sok sikertelen próbálkozás. A rendszer törli az adatokat az eszközről."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Túl sok sikertelen próbálkozás. A rendszer törli ezt a felhasználót."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Túl sok sikertelen próbálkozás. A rendszer törli ezt a munkaprofilt és a kapcsolódó adatokat."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Bezárás"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Alapértelmezett"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Letiltva"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Engedélyezve"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Képernyő bekapcsolása"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"A képernyő bekapcsolásának engedélyezése"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"A képernyő bekapcsolásának engedélyezése az adott alkalmazás számára. Ha megadja az engedélyt, az alkalmazás az Ön kifejezett szándéka nélkül, bármikor bekapcsolhatja a képernyőt."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index cd1b9343cdd0..ba51be82595f 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Չհաջողվեց ստեղծել նոր օգտատեր"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Չհաջողվեց նոր հյուր ստեղծել"</string>
<string name="user_nickname" msgid="262624187455825083">"Կեղծանուն"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Ավելացնել օգտատեր"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ավելացնել հյուր"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Հեռացնել հյուրին"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Վերակայել հյուրի աշխատաշրջանը"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Վերակայե՞լ հյուրի աշխատաշրջանը"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Հեռացնե՞լ հյուրին"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Վերակայել"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Հյուրի աշխատաշրջանը վերակայվում է…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Լուսանկարել"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Ընտրել պատկեր"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Ընտրեք լուսանկար"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Չափից շատ սխալ փորձեր են արվել։ Այս սարքի տվյալները կջնջվեն։"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Չափից շատ սխալ փորձեր են արվել։ Oգտատիրոջ պրոֆիլը կջնջվի։"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Չափից շատ սխալ փորձեր են արվել։ Աշխատանքային պրոֆիլը և դրա տվյալները կջնջվեն։"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Փակել"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Կանխադրված տարբերակ"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Անջատված է"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Միացված է"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index ff14ad36056d..b4c7cab3675f 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Gagal membuat pengguna baru"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Gagal membuat tamu baru"</string>
<string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Tambahkan pengguna"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tambahkan tamu"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Hapus tamu"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Reset tamu"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset tamu?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Hapus tamu?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Mereset tamu …"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih gambar"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Terlalu banyak percobaan yang salah. Data perangkat ini akan dihapus."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Terlalu banyak percobaan yang salah. Pengguna ini akan dihapus."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Terlalu banyak percobaan yang salah. Profil kerja ini dan datanya akan dihapus."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Tutup"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Default perangkat"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Nonaktif"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktif"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Aktifkan 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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 3634d5f63e3e..da25edb8a8a4 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Ekki tókst að stofna nýjan notanda"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Ekki tókst að búa til nýjan gest"</string>
<string name="user_nickname" msgid="262624187455825083">"Gælunafn"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Bæta notanda við"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Bæta gesti við"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjarlægja gest"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Endurstilla gestastillingu"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Endurstilla gestastillingu?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Fjarlægja gest?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Endurstilla"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Endurstillir gest…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Velja mynd"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Of margar rangar tilraunir. Gögnum tækisins verður eytt."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Of margar rangar tilraunir. Þessum notanda verður eytt."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Of margar rangar tilraunir. Þessu vinnusniði og gögnum þess verður eytt."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Hunsa"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Sjálfgefin stilling tækis"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Slökkt"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Virkt"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Kveikja á skjánum"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Leyfa að kveikt sé á skjánum"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Leyfa forriti að kveikja á skjánum. Ef þetta er leyft getur forritið kveikt á skjánum hvenær sem er án þess að þú samþykkir það sérstaklega."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index af308e41074b..297ddf62f6c3 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Creazione nuovo utente non riuscita"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Impossibile creare un nuovo ospite"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Aggiungi utente"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Aggiungi ospite"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Rimuovi ospite"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Reimposta sessione Ospite"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reimpostare sessione Ospite?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Vuoi rimuovere l\'ospite?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reimposta"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Reimpostazione sessione Ospite in corso…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Seleziona la foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Troppi tentativi sbagliati. I dati del dispositivo verranno eliminati."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Troppi tentativi sbagliati. Questo utente verrà eliminato."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Troppi tentativi sbagliati. Questo profilo di lavoro e i relativi dati verranno eliminati."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Ignora"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Parametro predefinito"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Non attivo"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Attivo"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Attiva lo schermo"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Consenti l\'attivazione dello schermo"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Consenti a un\'app di attivare lo schermo. Se la autorizzi, l\'app può attivare lo schermo in qualsiasi momento senza la tua autorizzazione esplicita."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 93b1c97b0703..b2e66a5cd139 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -109,12 +109,9 @@
<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>
- <!-- no translation found for bluetooth_hearing_aid_left_active (7084887715570971441) -->
- <skip />
- <!-- no translation found for bluetooth_hearing_aid_right_active (8574683234077567230) -->
- <skip />
- <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (407704460573163973) -->
- <skip />
+ <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>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"שיחות טלפון"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"העברת קבצים"</string>
@@ -592,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"לא ניתן היה ליצור משתמש חדש"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"יצירת אורח חדש נכשלה"</string>
<string name="user_nickname" msgid="262624187455825083">"כינוי"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"הוספת משתמש"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"הוספת אורח"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"הסרת אורח/ת"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"איפוס הגלישה כאורח"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"לאפס את הגלישה כאורח?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"להסיר את האורח/ת?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"איפוס"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"מתבצע איפוס של הגלישה כאורח…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"צילום תמונה"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"לבחירת תמונה"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"בחירת תמונה"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"נעשו יותר מדי ניסיונות שגויים. הנתונים במכשיר יימחקו."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"נעשו יותר מדי ניסיונות שגויים. המשתמש הזה יימחק."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"נעשו יותר מדי ניסיונות שגויים. פרופיל העבודה והנתונים שמשויכים אליו יימחקו."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"סגירה"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ברירת המחדל של המכשיר"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"מושבת"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"מופעל"</string>
@@ -660,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index c84a3d900992..d561303296a5 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"新しいユーザーを作成できませんでした"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"新しいゲストを作成できませんでした"</string>
<string name="user_nickname" msgid="262624187455825083">"ニックネーム"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"ユーザーを追加"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ゲストを追加"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ゲストを削除"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"ゲストをリセット"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ゲストをリセットしますか?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ゲストを削除しますか?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"リセット"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"ゲストをリセットしています…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"写真を撮る"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"画像を選択"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"写真を選択"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"間違えた回数が上限を超えました。このデバイスのデータが削除されます。"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"間違えた回数が上限を超えました。このユーザーが削除されます。"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"間違えた回数が上限を超えました。この仕事用プロファイルと関連データが削除されます。"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"閉じる"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"デバイスのデフォルト"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"無効"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"有効"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 5400adc8776e..2f80db02d652 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"ახალი მომხმარებლის შექმნა ვერ მოხერხდა"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ახალი სტუმრის შექმნა ვერ მოხერხდა"</string>
<string name="user_nickname" msgid="262624187455825083">"მეტსახელი"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"მომხმარებლის დამატება"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"სტუმრის დამატება"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"სტუმრის ამოშლა"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"სტუმრის სესიის გადაყენება"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"გადაყენდეს სტუმარი?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"გსურთ სტუმრის ამოშლა?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"გადაყენება"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"მიმდინარეობს სტუმრის გადაყენება…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ფოტოს გადაღება"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"აირჩიეთ სურათი"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ფოტოს არჩევა"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"დაფიქსირდა ზედმეტად ბევრი არასწორი მცდელობა. შედეგად, ამ მოწყობილობის მონაცემები წაიშლება."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"დაფიქსირდა ზედმეტად ბევრი არასწორი მცდელობა. შედეგად, ეს მომხმარებელი წაიშლება."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"დაფიქსირდა ზედმეტად ბევრი არასწორი მცდელობა. შედეგად, სამსახურის ეს პროფილი და მისი მონაცემები წაიშლება."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"უარყოფა"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"მოწყობილობის ნაგულისხმევი"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"გათიშული"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ჩართული"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 8160f70ea994..e6670996b87f 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Жаңа пайдаланушы жасалмады."</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Жаңа қонақ профилі жасалмады."</string>
<string name="user_nickname" msgid="262624187455825083">"Лақап ат"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Пайдаланушы қосу"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Қонақ қосу"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты жою"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Қонақ сеансын әдепкі күйге қайтару"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Қонақ сеансы бастапқы күйге қайтарылсын ба?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Қонақты өшіру керек пе?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Бастапқы күйге қайтару"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Қонақ сеансы бастапқы күйге қайтарылуда…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Фотосурет таңдау"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Тым көп қате әрекет жасалды. Бұл құрылғының деректері жойылады."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Тым көп қате әрекет жасалды. Бұл пайдаланушы жойылады."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Тым көп қате әрекет жасалды. Бұл жұмыс профилі мен оның деректері жойылады."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Жабу"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Құрылғының әдепкі параметрлері"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Өшірулі"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Қосулы"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 0208265ade61..ddcb919fd05f 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"មិន​អាច​បង្កើត​អ្នកប្រើប្រាស់ថ្មី​បានទេ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"មិនអាចបង្កើតភ្ញៀវថ្មីបានទេ"</string>
<string name="user_nickname" msgid="262624187455825083">"ឈ្មោះ​ហៅក្រៅ"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"បញ្ចូល​អ្នក​ប្រើប្រាស់"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"បញ្ចូល​ភ្ញៀវ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ដកភ្ញៀវចេញ"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"កំណត់​ភ្ញៀវឡើង​វិញ"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"កំណត់​ភ្ញៀវឡើង​វិញឬ?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ដកភ្ញៀវចេញឬ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"កំណត់​ឡើងវិញ"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"កំពុងកំណត់​ភ្ញៀវឡើងវិញ…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ថតរូប"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ជ្រើសរើស​រូបភាព"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ជ្រើសរើស​​រូបថត"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ដោយសារ​មានការព្យាយាម​ដោះសោ​មិនត្រឹមត្រូវ​ច្រើនដងពេក ទិន្នន័យ​របស់​ឧបករណ៍នេះ​នឹងត្រូវបាន​លុប។"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ដោយសារមានការព្យាយាមដោះសោមិនត្រឹមត្រូវច្រើនដងពេក អ្នកប្រើប្រាស់នេះនឹងត្រូវបានលុប។"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"ដោយសារមានការព្យាយាមដោះសោមិនត្រឹមត្រូវច្រើនដងពេក កម្រងព័ត៌មានការងារនេះ និងទិន្នន័យរបស់វានឹងត្រូវបានលុប។"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"ច្រានចោល"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"លំនាំដើម​របស់ឧបករណ៍"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"បានបិទ"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"បានបើក"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 0284bc131b09..943770511d7e 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ಅತಿಥಿ ಬಳಕೆದಾರರನ್ನು ರೀಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಬೇಕೇ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ರೀಸೆಟ್ ಮಾಡಿ"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"ಅತಿಥಿ ಬಳಕೆದಾರರ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ಚಿತ್ರವನ್ನು ಆರಿಸಿ"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index c16902312712..3910faacd77a 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"새 사용자를 만들지 못함"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"새 게스트 생성 실패"</string>
<string name="user_nickname" msgid="262624187455825083">"닉네임"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"사용자 추가"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"게스트 추가"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"게스트 삭제"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"게스트 재설정"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"게스트를 재설정하시겠습니까?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"게스트를 삭제하시겠습니까?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"재설정"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"게스트 재설정 중…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"사진 찍기"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"이미지 선택"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"사진 선택"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"잘못된 시도 횟수가 너무 많습니다. 이 기기의 데이터가 삭제됩니다."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"잘못된 시도 횟수가 너무 많습니다. 이 사용자가 삭제됩니다."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"잘못된 시도 횟수가 너무 많습니다. 이 직장 프로필 및 관련 데이터가 삭제됩니다."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"닫기"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"기기 기본값"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"사용 중지됨"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"사용 설정됨"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 3f0844ca581b..ce12136bcdaf 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Жаңы колдонуучу түзүлбөй калды"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Жаңы конок түзүлгөн жок"</string>
<string name="user_nickname" msgid="262624187455825083">"Ылакап аты"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Колдонуучу кошуу"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Конок кошуу"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Конокту өчүрүү"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Конок сеансын баштапкы абалга келтирүү"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Конок сеансын баштапкы абалга келтиресизби?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Конокту өчүрөсүзбү?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Баштапкы абалга келтирүү"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Конок сеансы баштапкы абалга келтирилүүдө…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Сүрөткө тартуу"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Сүрөт тандаңыз"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Сүрөт тандаңыз"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Өтө көп жолу туура эмес аракет кылынды. Бул түзмөктүн дайындары жок кылынат."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Өтө көп жолу жаңылдыңыз. Бул колдонуучу өчүрүлөт."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Өтө көп жолу жаңылдыңыз. Бул жумуш профили жана андагы нерселер өчүрүлөт."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Жабуу"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Түзмөктүн демейки параметри"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Өчүк"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Күйүк"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index af682e0ed331..de3245b2f50d 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"ສ້າງຜູ້ໃຊ້ໃໝ່ບໍ່ສຳເລັດ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ສ້າງແຂກໃໝ່ບໍ່ສຳເລັດ"</string>
<string name="user_nickname" msgid="262624187455825083">"ຊື່ຫຼິ້ນ"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"ເພີ່ມຜູ້ໃຊ້"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ເພີ່ມແຂກ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ລຶບແຂກອອກ"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"ຣີເຊັດແຂກ"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ຣີເຊັດແຂກບໍ?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ລຶບແຂກອອກບໍ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ຣີເຊັດ"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"ກຳລັງຣີເຊັດແຂກ…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ຖ່າຍຮູບ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ເລືອກຮູບ"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ເລືອກຮູບ"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ພະຍາຍາມປົດລັອກບໍ່ສຳເລັດຫຼາຍເທື່ອເກີນໄປ. ຂໍ້ມູນຂອງອຸປະກອນນີ້ຈະຖືກລຶບອອກ."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ພະຍາຍາມປົດລັອກບໍ່ສຳເລັດຫຼາຍເທື່ອເກີນໄປ. ຜູ້ໃຊ້ນີ້ຈະຖືກລຶບຂໍ້ມູນອອກ."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"ພະຍາຍາມປົດລັອກບໍ່ສຳເລັດຫຼາຍເທື່ອເກີນໄປ. ໂປຣໄຟລ໌ບ່ອນເຣັດວຽກ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"ປິດໄວ້"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ຄ່າເລີ່ມຕົ້ນອຸປະກອນ"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ປິດການນຳໃຊ້ແລ້ວ"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ເປີດການນຳໃຊ້ແລ້ວ"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index b4f2e6ec847f..a5fa6f310676 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nepavyko sukurti naujo naudotojo"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Nepavyko sukurti naujo gesto"</string>
<string name="user_nickname" msgid="262624187455825083">"Slapyvardis"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Pridėti naudotoją"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridėti svečią"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Pašalinti svečią"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Iš naujo nustatyti svečią"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Nustatyti svečią iš naujo?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Pašalinti svečią?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nustatyti iš naujo"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Svečias nustatomas iš naujo…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografuoti"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pasirinkti vaizdą"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Pasirinkti nuotrauką"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Per daug netinkamų bandymų. Šio įrenginio duomenys bus ištrinti."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Per daug netinkamų bandymų. Šis naudotojas bus ištrintas."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Per daug netinkamų bandymų. Šis darbo profilis ir jo duomenys bus ištrinti."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Atsisakyti"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Numatyt. įrenginio nustatymas"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Išjungta"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Įgalinta"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ekrano įjungimas"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Leisti įjungti ekraną"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Leiskite programai įjungti ekraną. Jei suteiksite leidimą, programa galės įjungti ekraną bet kuriuo metu be nurodyto tikslo."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 9153b93c3bc8..f17566599751 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Neizdevās izveidot jaunu lietotāju"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Neizdevās izveidot jaunu viesa profilu"</string>
<string name="user_nickname" msgid="262624187455825083">"Segvārds"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Pievienot lietotāju"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pievienot viesi"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Noņemt viesi"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Atiestatīt viesa sesiju"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Vai atiestatīt viesa sesiju?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Vai noņemt viesi?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Atiestatīt"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Notiek viesa sesijas atiestatīšana…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Uzņemt fotoattēlu"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Izvēlēties attēlu"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Atlasīt fotoattēlu"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Pārāk daudz nesekmīgu mēģinājumu. Dati šajā ierīcē tiks dzēsti."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Pārāk daudz nesekmīgu mēģinājumu. Šis lietotājs tiks dzēsts."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Pārāk daudz nesekmīgu mēģinājumu. Šis darba profils un ar to saistītie dati tiks dzēsti."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Nerādīt"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Ierīces noklusējums"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Atspējots"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Iespējots"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ekrāna ieslēgšana"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Atļaut ieslēgt ekrānu"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Atļaujiet lietotnei ieslēgt ekrānu. Ja to atļausiet, lietotne varēs jebkurā laikā ieslēgt ekrānu bez tiešas jūsu piekrišanas."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 22d724ac869b..c5e27622506b 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Да се ресетира гостинот?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Да се отстрани гостинот?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетирај"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Се ресетира гостинот…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Фотографирајте"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Одберете слика"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index b8a0fc845222..e6b7540e11ee 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"അതിഥിയെ റീസെറ്റ് ചെയ്യണോ?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"അതിഥിയെ നീക്കം ചെയ്യണോ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"റീസെറ്റ് ചെയ്യുക"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"അതിഥിയെ റീസെറ്റ് ചെയ്യുന്നു…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 74556959ef70..09204094db46 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Зочныг шинэчлэх үү?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Зочныг хасах уу?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Шинэчлэх"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Зочныг шинэчилж байна…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Зураг авах"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Зураг сонгох"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 1f4334304ff0..173a62cff752 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"नवीन वापरकर्ता तयार करता आला नाही"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"नवीन अतिथी तयार करता आला नाही"</string>
<string name="user_nickname" msgid="262624187455825083">"टोपणनाव"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"वापरकर्ता जोडा"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"अतिथी सेशन रीसेट करा"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"अतिथीला रीसेट करायचे आहे का?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"अतिथीला काढून टाकायचे आहे का?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रीसेट करा"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"अतिथीला रीसेट करत आहे…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"फोटो काढा"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"इमेज निवडा"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"फोटो निवडा"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"बरेच चुकीचे प्रयत्‍न. या डिव्‍हाइसचा डेटा हटवला जाईल."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"बरेच चुकीचे प्रयत्‍न. हा वापरकर्ता हटवला जाईल."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"बरेच चुकीचे प्रयत्‍न. ही कार्य प्रोफाइल आणि त्यामधील डेटा हटवला जाईल."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"डिसमिस करा"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"डिव्हाइस डीफॉल्ट"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"बंद केले आहे"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सुरू केले आहे"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 49a8c209d854..695157b79098 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Tetapkan semula tetamu?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Alih keluar tetamu?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tetapkan semula"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Menetapkan semula tetamu…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih imej"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Hidupkan skrin"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Benarkan menghidupkan skrin"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Benarkan apl menghidupkan skrin. Jika dibenarkan, apl boleh menghidupkan skrin pada bila-bila masa tanpa niat eksplisit anda."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 010ec69f99b5..ea7d11c2edfe 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"အသုံးပြုသူအသစ် ပြုလုပ်၍မရပါ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ဧည့်သည်သစ် ပြုလုပ်၍မရပါ"</string>
<string name="user_nickname" msgid="262624187455825083">"နာမည်ပြောင်"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"အသုံးပြုသူ ထည့်ရန်"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ဧည့်သည့် ထည့်ရန်"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ဧည့်သည်ကို ဖယ်ထုတ်ရန်"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်ရန်"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်မလား။"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ဧည့်သည်ကို ဖယ်ရှားမလား။"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ပြင်ဆင်သတ်မှတ်ရန်"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်နေသည်…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ဓာတ်ပုံရွေးရန်"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"မှားယွင်းသည့် အကြိမ်ရေ အလွန်များနေပါပြီ။ ဤစက်၏ ဒေတာကို ဖျက်လိုက်ပါမည်။"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"မှားယွင်းသည့် အကြိမ်ရေ အလွန်များနေပါပြီ။ ဤအသုံးပြုသူကို ဖျက်လိုက်ပါမည်။"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"မှားယွင်းသည့် အကြိမ်ရေ အလွန်များနေပါပြီ။ ဤအလုပ်ပရိုဖိုင်နှင့် ၎င်း၏ဒေတာကို ဖျက်လိုက်ပါမည်။"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"ပယ်ရန်"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"စက်ပစ္စည်းမူရင်း"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ပိတ်ထားသည်"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ဖွင့်ထားသည်"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 7abf82b357b7..2bedf8afb246 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Kunne ikke opprette noen ny bruker"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Kunne ikke opprette en ny gjest"</string>
<string name="user_nickname" msgid="262624187455825083">"Kallenavn"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Legg til bruker"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Legg til en gjest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Tilbakestill gjest"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Vil du tilbakestille gjesten?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Vil du fjerne gjesten?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tilbakestill"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Tilbakestiller gjesten …"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ta et bilde"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Velg et bilde"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Velg et bilde"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"For mange mislykkede forsøk. Dataene på denne enheten blir slettet."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"For mange mislykkede forsøk. Denne brukeren blir slettet."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"For mange mislykkede forsøk. Denne jobbprofilen og tilknyttede data blir slettet."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Lukk"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Standard for enheten"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Slått av"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Slått på"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Slå på skjermen"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Tillat å slå på skjermen"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Tillat at en app slår på skjermen. Hvis tillatelsen gis, kan appen slå på skjermen når som helst uten din eksplisitte intensjon."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index f2e156b64a2a..d8dab07206cc 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"नयाँ प्रयोगकर्ता सिर्जना गर्न सकिएन"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"नयाँ अतिथि बनाउन सकिएन"</string>
<string name="user_nickname" msgid="262624187455825083">"उपनाम"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"प्रयोगकर्ता थप्नुहोस्"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथि थप्नुहोस्"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अतिथि हटाउनुहोस्"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"अतिथि सत्र रिसेट गर्नुहोस्"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"अतिथिका रूपमा ब्राउज गर्ने सेसन रिसेट गर्ने हो?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"यी अतिथि हटाउने हो?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रिसेट गर्नुहोस्"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"अतिथिका रूपमा ब्राउज गर्ने सेसन रिसेट गरिँदै छ…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"फोटो खिच्नुहोस्"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"कुनै फोटो छनौट गर्नुहोस्"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"फोटो चयन गर्नुहोस्"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"धेरै पटक गलत तरिकाले अनलक गर्ने प्रयास गरियो। यो डिभाइसमा भएको डेटा मेटाइने छ।"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"धेरै पटक गलत तरिकाले अनलक गर्ने प्रयास गरियो। यो प्रयोगकर्ता मेटाइने छ।"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"धेरै पटक गलत तरिकाले अनलक गर्ने प्रयास गरियो। यो कार्य प्रोफाइल र यसमा भएको डेटा मेटाइने छ।"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"हटाउनुहोस्"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"डिफल्ट डिभाइस"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"असक्षम पारिएको छ"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सक्षम पारिएको छ"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 72d574fb389c..913fc667e7f9 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Kan geen nieuwe gebruiker maken"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Kan geen nieuwe gast maken"</string>
<string name="user_nickname" msgid="262624187455825083">"Bijnaam"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Gebruiker toevoegen"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gast toevoegen"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Gast verwijderen"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Gastsessie resetten"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Gast resetten?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Gast verwijderen?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetten"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Gast resetten…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Foto maken"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Afbeelding kiezen"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Foto selecteren"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Te veel onjuiste pogingen. De gegevens van dit apparaat worden verwijderd."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Te veel onjuiste pogingen. Deze gebruiker wordt verwijderd."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Te veel onjuiste pogingen. Dit werkprofiel en de bijbehorende gegevens worden verwijderd."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Sluiten"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Apparaatstandaard"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Uitgezet"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aangezet"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Scherm aanzetten"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Scherm aanzetten toestaan"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Toestaan dat een app het scherm aanzet. Indien toegestaan, kan de app het scherm op elk moment aanzetten zonder jouw expliciete intentie."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 53777dfe6cf7..ea7b23c3d972 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବାକୁ ବିଫଳ ହେଲା"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ଜଣେ ନୂଆ ଅତିଥି ତିଆରି କରିବାରେ ବିଫଳ ହୋଇଛି"</string>
<string name="user_nickname" msgid="262624187455825083">"ଡାକନାମ"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"ଉପଯୋଗକର୍ତ୍ତା ଯୋଗ କରନ୍ତୁ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ଅତିଥି ଯୋଗ କରନ୍ତୁ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ଅତିଥିଙ୍କୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"ଅତିଥି ସେସନକୁ ରିସେଟ୍ କରନ୍ତୁ"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ଅତିଥି ସେସନକୁ ରିସେଟ୍ କରିବେ?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ଅତିଥିଙ୍କୁ କାଢ଼ିବେ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ରିସେଟ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"ଅତିଥି ସେସନକୁ ରିସେଟ୍ କରାଯାଉଛି…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ଏକ ଛବି ବାଛନ୍ତୁ"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ଫଟୋ ବାଛନ୍ତୁ"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପ୍ରଚେଷ୍ଟା। ଏହି ଡିଭାଇସର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପ୍ରଚେଷ୍ଟା। ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଡିଲିଟ କରିଦିଆଯିବ।"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପ୍ରଚେଷ୍ଟା। ଏହି ୱାର୍କ ପ୍ରୋଫାଇଲ ଏବଂ ଏହାର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ଡିଭାଇସ୍ ଡିଫଲ୍ଟ"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ସକ୍ଷମ କରାଯାଇଛି"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 07ef29c06c52..183aa6bfbe63 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ਨਵਾਂ ਮਹਿਮਾਨ ਪ੍ਰੋਫਾਈਲ ਬਣਾਉਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
<string name="user_nickname" msgid="262624187455825083">"ਉਪਨਾਮ"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"ਵਰਤੋਂਕਾਰ ਨੂੰ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ਮਹਿਮਾਨ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ਮਹਿਮਾਨ ਹਟਾਓ"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਨੂੰ ਰੀਸੈੱਟ ਕਰੋ"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ਕੀ ਮਹਿਮਾਨ ਨੂੰ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ਕੀ ਮਹਿਮਾਨ ਨੂੰ ਹਟਾਉਣਾ ਹੈ?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ਰੀਸੈੱਟ ਕਰੋ"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"ਮਹਿਮਾਨ ਨੂੰ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ਇੱਕ ਫ਼ੋਟੋ ਖਿੱਚੋ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ਕੋਈ ਚਿੱਤਰ ਚੁਣੋ"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ਫ਼ੋਟੋ ਚੁਣੋ"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ਬਹੁਤ ਸਾਰੀਆਂ ਗਲਤ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ਬਹੁਤ ਸਾਰੀਆਂ ਗਲਤ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"ਬਹੁਤ ਸਾਰੀਆਂ ਗਲਤ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਹ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਇਸਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"ਖਾਰਜ ਕਰੋ"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ਡੀਵਾਈਸ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index b2deca7b9a0a..2bd78a6e937f 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nie udało się utworzyć nowego użytkownika"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Nie udało się utworzyć nowego gościa"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Dodaj użytkownika"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gościa"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Usuń gościa"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesję gościa"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Zresetować sesję gościa?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Usunąć gościa?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Resetuję sesję gościa…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Wybierz zdjęcie"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Zbyt wiele nieudanych prób. Dane na urządzeniu zostaną usunięte."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Zbyt wiele nieudanych prób. Użytkownik zostanie usunięty."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Zbyt wiele nieudanych prób. Profil służbowy i powiązane z nim dane zostaną usunięte."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Zamknij"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Ustawienie domyślne urządzenia"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Wyłączono"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Włączono"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Włączanie ekranu"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Zezwalaj na włączanie ekranu"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Zezwalaj na włączanie ekranu przez aplikację. Gdy przyznasz te uprawnienia, aplikacja będzie mogła w dowolnym momencie włączyć ekran bez Twojego wyraźnego pozwolenia."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index b210f4bbf4aa..3e5b67c1f86c 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo usuário"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string>
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Adicionar usuário"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Redefinir sessão de visitante"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Redefinir visitante?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remover convidado?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Redefinir"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Redefinindo visitante…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Excesso de tentativas incorretas. Os dados deste dispositivo serão excluídos."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Excesso de tentativas incorretas. O usuário será excluído."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Excesso de tentativas incorretas. Este perfil de trabalho e os dados dele serão excluídos."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Dispensar"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Padrão do dispositivo"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desativado"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ligar tela"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permitir que a tela seja ligada"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permitir que um app ligue a tela. Se permitido, o app vai poder ligar a tela a qualquer momento sem uma intent explícita."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 73bba6709c63..df80951ff485 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo utilizador"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string>
<string name="user_nickname" msgid="262624187455825083">"Alcunha"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Adicionar utilizador"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Repor convidado"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Pretende repor o convidado?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remover o convidado?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Repor"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"A repor o convidado…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Demasiadas tentativas incorretas. Os dados deste dispositivo vão ser eliminados."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Demasiadas tentativas incorretas. Este utilizador vai ser eliminado."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Demasiadas tentativas incorretas. Este perfil de trabalho e os respetivos dados vão ser eliminados."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Ignorar"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Predefinição do dispositivo"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desativada"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativada"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ative o ecrã"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permitir a ativação do ecrã"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permita que uma app ative o ecrã. Se a autorização for concedida, a app pode ativar o ecrã em qualquer altura sem a sua intenção explícita."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index b210f4bbf4aa..3e5b67c1f86c 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo usuário"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string>
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Adicionar usuário"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Redefinir sessão de visitante"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Redefinir visitante?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remover convidado?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Redefinir"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Redefinindo visitante…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Excesso de tentativas incorretas. Os dados deste dispositivo serão excluídos."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Excesso de tentativas incorretas. O usuário será excluído."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Excesso de tentativas incorretas. Este perfil de trabalho e os dados dele serão excluídos."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Dispensar"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Padrão do dispositivo"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desativado"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ligar tela"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permitir que a tela seja ligada"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permitir que um app ligue a tela. Se permitido, o app vai poder ligar a tela a qualquer momento sem uma intent explícita."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index bb9176ec7dc8..d87b6f95edba 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Resetați invitatul?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Excludeți invitatul?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetați"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Se resetează invitatul…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Faceți o fotografie"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Alegeți o imagine"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Activați ecranul"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permiteți activarea ecranului"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permiteți unei aplicații să activeze ecranul. Dacă acordați permisiunea, aplicația poate să activeze oricând ecranul, fără intenția dvs. explicită."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 33f35445ac14..3703426757ee 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Не удалось создать пользователя"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Не удалось создать гостя."</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Добавить пользователя"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавить гостя"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Удалить аккаунт гостя"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Сбросить гостевой сеанс"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Сбросить гостевой сеанс?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Удалить гостя?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Сбросить"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Сброс гостевого сеанса…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Выбрать фотографию"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Слишком много неудачных попыток. С устройства будут удалены все данные."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Слишком много неудачных попыток. Этот пользователь будет удален."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Слишком много неудачных попыток. Этот рабочий профиль и его данные будут удалены."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Закрыть"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Вариант по умолчанию"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Отключено"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Включено"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index abedbb95de09..b74fee50e11f 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"නව පරිශීලකයෙකු තැනීමට අසමත් විය"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"නව අමුත්තකු තැනීම අසාර්ථක විය"</string>
<string name="user_nickname" msgid="262624187455825083">"අපනාමය"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"පරිශීලකයා එක් කරන්න"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"අමුත්තා එක් කරන්න"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"අමුත්තා ඉවත් කරන්න"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"ආගන්තුකයා යළි සකසන්න"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"අමුත්තා යළි සකසන්නද?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"අමුත්තා ඉවත් කරන්නද?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"යළි සකසන්න"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"අමුත්තා යළි සකසමින්…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ඡායාරූපයක් ගන්න"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"රූපයක් තෝරන්න"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"ඡායාරූපය තෝරන්න"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"වැරදි උත්සාහයන් ඉතා වැඩි ගණනකි. මෙම උපාංගයෙහි දත්ත මකනු ඇත."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"වැරදි උත්සාහයන් ඉතා වැඩි ගණනකි. මෙම පරිශීලකයා මකනු ඇත."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"වැරදි උත්සාහයන් ඉතා වැඩි ගණනකි. මෙම කාර්යාල පැතිකඩ සහ එහි දත්ත මකනු ඇත."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"ඉවත ලන්න"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"උපාංගයේ පෙරනිමිය"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"අබල කළා"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"සබලයි"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index c531a56576c4..51673d8bc42b 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nového použív. sa nepodarilo vytvoriť"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Nového hosťa sa nepodarilo vytvoriť"</string>
<string name="user_nickname" msgid="262624187455825083">"Prezývka"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Pridať používateľa"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridať hosťa"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Obnoviť reláciu hosťa"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Chcete resetovať reláciu hosťa?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Chcete odobrať hosťa?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetovať"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Relácia hosťa sa resetuje…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Vybrať fotku"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Príliš veľa chybných pokusov. Údaje tohto zariadenia budú odstránené."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Príliš veľa chybných pokusov. Tento používateľ bude odobraný."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Príliš veľa chybných pokusov. Tento pracovný profil a jeho údaje budú odstránené."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Zavrieť"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Predvol. nastavenie zariadenia"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Vypnuté"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuté"</string>
@@ -657,4 +653,10 @@
<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_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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index ad7256d237d2..01dd0b6cc7f6 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Ustvarjanje novega uporabnika ni uspelo."</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Ustvarjanje novega gosta ni uspelo."</string>
<string name="user_nickname" msgid="262624187455825083">"Vzdevek"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Dodaj uporabnika"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodajanje gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odstranitev gosta"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Ponastavi gosta"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Želite ponastaviti gosta?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Želite odstraniti gosta?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ponastavi"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Ponastavljanje gosta …"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Izbira fotografije"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Preveč napačnih poskusov. Podatki v napravi bodo izbrisani."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Preveč napačnih poskusov. Uporabnik bo izbrisan."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Preveč napačnih poskusov. Delovni profil in podatki v njem bodo izbrisani."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Opusti"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Privzeta nastavitev naprave"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Onemogočeno"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogočeno"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Vklop zaslona"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Dovoli vklop zaslona"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dovolite aplikaciji, da vklopi zaslon. Če ji to odobrite, lahko aplikacija kadar koli brez vašega eksplicitnega namena vklopi zaslon."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 51fda8cfabb6..1a55c5dcb5d5 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Krijimi i një përdoruesi të ri dështoi"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Profili i vizitorit të ri nuk u krijua"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudonimi"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Shto përdorues"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Shto të ftuar"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Hiq të ftuarin"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Rivendos vizitorin"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Të rivendoset vizitori?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Të hiqet vizitori?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Rivendos"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Vizitori po rivendoset…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Bëj një fotografi"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Zgjidh një imazh"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Zgjidh një fotografi"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Shumë tentativa të pasakta. Të dhënat e kësaj pajisjeje do të fshihen."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Shumë tentativa të pasakta. Ky përdorues do të fshihet."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Shumë tentativa të pasakta. Ky profil pune dhe të dhënat e tij do të fshihen."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Hiq"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Parazgjedhja e pajisjes"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Joaktiv"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ndiz ekranin"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Lejo ndezjen e ekranit"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Lejo një aplikacion që të ndezë ekranin. Nëse lejohet, aplikacioni mund ta ndezë ekranin në çdo kohë pa synimin tënd të shprehur."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 80092d0765de..65df95da2144 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Желите ли да ресетујете сесију госта?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Желите ли да уклоните госта?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетуј"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Сесија госта се ресетује…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index f0400251ca06..45f3750c18ed 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Det gick inte att skapa en ny användare"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Det gick inte att skapa en ny gäst"</string>
<string name="user_nickname" msgid="262624187455825083">"Smeknamn"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Lägg till användare"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lägg till gäst"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ta bort gäst"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Återställ gästsession"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Vill du återställa gästsessionen?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Vill du ta bort gästen?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Återställ"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Gästsessionen återställs …"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Välj foto"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"För många felaktiga försök. Enhetens data raderas."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"För många felaktiga försök. Den här användaren raderas."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"För många felaktiga försök. Den här jobbprofilen och dess data raderas."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Stäng"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Enhetens standardinställning"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inaktiverat"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiverat"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Aktivera skärmen"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Tillåt att skärmen aktiveras"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Tillåt att en app aktiverar skärmen. Om du ger tillåtelse kan appen aktivera skärmen när som helst utan din uttryckliga avsikt."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index fcc07c68e715..380dbf4e603e 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Imeshindwa kuweka mtumiaji mpya"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Imeshindwa kuunda wasifu mpya wa mgeni"</string>
<string name="user_nickname" msgid="262624187455825083">"Jina wakilishi"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Weka mtumiaji"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ongeza mgeni"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ondoa mgeni"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Badilisha kipindi cha mgeni"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Ungependa kubadilisha kipindi cha mgeni?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Ungependa kumwondoa mgeni?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Badilisha"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Inabadilisha kipindi cha mgeni…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Piga picha"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Chagua picha"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Chagua picha"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Umejaribu kufungua mara nyingi mno kwa njia isiyo sahihi. Data iliyo kwenye kifaa hiki itafutwa."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Umejaribu kufungua mara nyingi mno kwa njia isiyo sahihi. Maelezo ya mtumiaji huyu yatafutwa."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Umejaribu kufungua mara nyingi mno kwa njia isiyo sahihi. Wasifu huu wa kazini utafutwa pamoja na data yake."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Ondoa"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Hali chaguomsingi ya kifaa"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Imezimwa"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Imewashwa"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Washa skrini"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Ruhusu kuwasha skrini"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Ruhusu programu iwashe skrini. Ikiwa imepewa idhini, programu inaweza kuwasha skrini wakati wowote bila utaratibu wako dhahiri wa kuratibu."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 64682012c5cb..da22b7d2d415 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -598,6 +598,8 @@
<!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
<skip />
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"மீட்டமை"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"கெஸ்ட்டை மீட்டமைக்கிறது…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"படமெடுங்கள்"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"படத்தைத் தேர்வுசெய்யுங்கள்"</string>
@@ -657,4 +659,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index da2527a4b6ab..1d1143095484 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"గెస్ట్ సెషన్‌ను రీసెట్ చేయాలా?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"అతిథిని తీసివేయాలా?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"రీసెట్ చేయండి"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"గెస్ట్ సెషన్‌ను రీసెట్ చేస్తోంది…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ఒక ఫోటో తీయండి"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ఇమేజ్‌ను ఎంచుకోండి"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index c5bd8268be43..84dbd698a2c8 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"รีเซ็ตผู้เข้าร่วมไหม"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"นำผู้เข้าร่วมออกไหม"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"รีเซ็ต"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"กำลังรีเซ็ตผู้เข้าร่วม…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string>
@@ -651,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index e08ba325859f..6ecad888ae3c 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"I-reset ang session ng bisita?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Alisin ang bisita?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"I-reset"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Nire-reset ang bisita…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Kumuha ng larawan"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pumili ng larawan"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"I-on ang screen"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Payagan ang pag-on sa screen"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Nagpapahintulot sa app na i-on ang screen. Kung papayagan, puwedeng i-on ng app ang screen anumang oras nang wala ng iyong malinaw na intent."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index c6ea09808db7..ab2a094cab5e 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Yeni kullanıcı oluşturulamadı"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Yeni misafir oluşturulamadı"</string>
<string name="user_nickname" msgid="262624187455825083">"Takma ad"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Kullanıcı ekle"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Misafir ekle"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Misafir oturumunu kaldır"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Misafir oturumunu sıfırla"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Misafir oturumu sıfırlansın mı?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Konuk çıkarılsın mı?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Sıfırla"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Misafir oturumu sıfırlanıyor…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotoğraf çek"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Resim seç"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Fotoğraf seç"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Çok fazla sayıda hatalı deneme yapıldı. Bu cihazın verileri silinecek."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Çok fazla sayıda hatalı deneme yapıldı. Bu kullanıcı silinecek."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Çok fazla sayıda hatalı denemede yapıldı. İş profiliniz ve verileri silinecek."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Kapat"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Cihaz varsayılanı"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Devre dışı"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Etkin"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ekranı aç"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Ekranı açmaya izin ver"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Bir uygulamanın ekranı açmasına izin verin. İzin verildiğinde, uygulama sizin belirgin niyetiniz olmadan istediği zaman ekranı açabilir."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 28ac9fb75ca0..8897d711e2f2 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Не вдалося створити користувача"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Не вдалося створити гостя"</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдонім"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Додати користувача"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додати гостя"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Видалити гостя"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Скинути сеанс у режимі \"Гість\""</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Скинути сеанс у режимі \"Гість\"?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Вилучити гостя?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Скинути"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Скидання сеансу в режимі \"Гість\"…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Вибрати фотографію"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Забагато невдалих спроб. Дані на цьому пристрої буде видалено."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Забагато невдалих спроб. Цього користувача буде видалено."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Забагато невдалих спроб. Цей робочий профіль і його дані буде видалено."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Закрити"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"За умовчанням для пристрою"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Вимкнено"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Увімкнено"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 8e2a1a3e7715..ecddac246a56 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -598,6 +598,8 @@
<!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
<skip />
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ری سیٹ کریں"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"مہمان کو ری سیٹ کرنا…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ایک تصویر لیں"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ایک تصویر منتخب کریں"</string>
@@ -657,4 +659,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 5a9763278cd8..ca23c6ef8603 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Yangi foydalanuvchi yaratilmadi"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Yangi mehmon yaratilmadi"</string>
<string name="user_nickname" msgid="262624187455825083">"Nik"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Foydalanuvchi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Mehmon seansini tiklash"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Mehmon seansi tiklansinmi?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Mehmon olib tashlansinmi?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tiklash"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Mehmon seansi tiklanmoqda…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Suratga olish"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Rasm tanlash"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Surat tanlash"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Juda koʻp marta muvaffaqiyatsiz urinishlar amalga oshirildi. Bu qurilmadagi maʼlumotlar o‘chirib tashlanadi."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Juda koʻp marta muvaffaqiyatsiz urindingiz. Bu foydalanuvchi oʻchirib tashlanadi."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Juda koʻp marta muvaffaqiyatsiz urindingiz. Bu ish profili va undagi maʼlumotlar oʻchirib tashlanadi."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Yopish"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Qurilma standarti"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Yoqilmagan"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Yoniq"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ekranni yoqish"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Ekranni yoqishga ruxsat"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Ilovaga ekranni yoqishga ruxsat berish. Ruxsat berilsa, ilova istalgan vaqt ruxsatingizsiz ekranni yoqishi mumkin."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 710a02af7650..c8a1f1de940e 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"Không tạo được người dùng mới"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Không tạo được khách mới"</string>
<string name="user_nickname" msgid="262624187455825083">"Biệt hiệu"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"Thêm người dùng"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Thêm khách"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Xóa phiên khách"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Đặt lại phiên khách"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Đặt lại phiên khách?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Loại bỏ khách?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Đặt lại"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Đang đặt lại phiên khách…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Chụp ảnh"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Chọn một hình ảnh"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"Chọn ảnh"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Quá nhiều lần thử không chính xác. Dữ liệu trên thiết bị này sẽ bị xoá."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Quá nhiều lần thử không chính xác. Người dùng này sẽ bị xoá."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Quá nhiều lần thử không chính xác. Hồ sơ công việc này và dữ liệu của hồ sơ công việc sẽ bị xoá."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Đóng"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Theo giá trị mặc định của thiết bị"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Đã tắt"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Đã bật"</string>
@@ -657,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Bật màn hình"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Cho phép bật màn hình"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Cho phép ứng dụng bật màn hình. Nếu được phép, ứng dụng có thể bật màn hình bất kỳ lúc nào kể cả khi bạn không có ý định như vậy."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index ae579ab03cfb..3f45ec7de8dd 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"无法创建新用户"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"未能创建新的访客"</string>
<string name="user_nickname" msgid="262624187455825083">"昵称"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"添加用户"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"添加访客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除访客"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"重置访客会话"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"要重置访客会话吗?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"要移除访客吗?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重置"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"正在重置访客会话…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"拍摄照片"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"选择图片"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"选择照片"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"错误次数过多。系统将删除此设备上的数据。"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"错误次数过多。系统将删除此用户。"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"错误次数过多。系统将删除此工作资料和相关数据。"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"关闭"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"设备默认设置"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已启用"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 0579c3bf385e..d5ba27fc2a05 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"無法建立新使用者"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"無法建立新訪客"</string>
<string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"新增使用者"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"重設訪客"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"要重設訪客嗎?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"要移除訪客嗎?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重設"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"正在重設訪客…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"揀相"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"錯誤次數太多,系統將會刪除此裝置上的資料。"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"錯誤次數太多,系統將會刪除此使用者。"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"錯誤次數太多,系統將會刪除此工作設定檔和相關資料。"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"關閉"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"裝置預設設定"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 882190e91123..b51b113b40b4 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -589,27 +589,23 @@
<string name="add_user_failed" msgid="4809887794313944872">"無法建立新的使用者"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"無法建立新訪客"</string>
<string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
- <!-- no translation found for user_add_user (7876449291500212468) -->
- <skip />
+ <string name="user_add_user" msgid="7876449291500212468">"新增使用者"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"重設訪客"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"要重設訪客嗎?"</string>
- <!-- no translation found for guest_remove_guest_dialog_title (4548511006624088072) -->
- <skip />
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"要移除訪客嗎?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重設"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"正在重設訪客…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
<string name="user_image_photo_selector" msgid="433658323306627093">"選取相片"</string>
- <!-- no translation found for failed_attempts_now_wiping_device (4016329172216428897) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_user (469060411789668050) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_profile (7626589520888963129) -->
- <skip />
- <!-- no translation found for failed_attempts_now_wiping_dialog_dismiss (2749889771223578925) -->
- <skip />
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"錯誤次數過多,系統將刪除這部裝置中的資料。"</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"錯誤次數過多,系統將刪除這位使用者。"</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"錯誤次數過多,系統將刪除這個工作資料夾和當中的資料。"</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"關閉"</string>
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"裝置預設設定"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
@@ -657,4 +653,10 @@
<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>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index b24e9349e5c2..ee6851d92de8 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -596,6 +596,8 @@
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Setha kabusha isimenywa?"</string>
<string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Susa isihambeli?"</string>
<string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Setha kabusha"</string>
+ <!-- no translation found for guest_remove_guest_confirm_button (7858123434954143879) -->
+ <skip />
<string name="guest_resetting" msgid="7822120170191509566">"Ukusetha kabusha isimenywa…"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Thatha isithombe"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Khetha isithombe"</string>
@@ -651,4 +653,10 @@
<string name="turn_screen_on_title" msgid="3266937298097573424">"Vula isikrini"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Vumela ukuvula isikrini"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Vumela i-app ivule isikrini. Uma kuvunyiwe, i-app ingavula isikrini noma nini ngaphandle kwenhloso yakho esobala."</string>
+ <!-- no translation found for bt_le_audio_scan_qr_code (3521809854780392679) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_scan_qr_code_scanner (4679500020630341107) -->
+ <skip />
+ <!-- no translation found for bt_le_audio_qr_code_is_not_valid_format (6092191081849434734) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 3debd9a179da..7fbd10025d60 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -47,7 +47,7 @@ public class CachedBluetoothDeviceManager {
CsipDeviceManager mCsipDeviceManager;
BluetoothDevice mOngoingSetMemberPair;
- CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
+ public CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
mContext = context;
mBtManager = localBtManager;
mHearingAidDeviceManager = new HearingAidDeviceManager(localBtManager, mCachedDevices);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index bb47c5e10711..0c652f62f8e4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -16,29 +16,47 @@
package com.android.settingslib.bluetooth;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeAudioContentMetadata;
import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile.ServiceListener;
import android.content.Context;
+import android.os.Build;
import android.util.Log;
+import androidx.annotation.RequiresApi;
+
+import com.android.settingslib.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+
/**
* LocalBluetoothLeBroadcast provides an interface between the Settings app
* and the functionality of the local {@link BluetoothLeBroadcast}.
+ * Use the {@link BluetoothLeBroadcast.Callback} to get the result callback.
*/
-public class LocalBluetoothLeBroadcast implements BluetoothLeBroadcast.Callback {
-
+public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
private static final String TAG = "LocalBluetoothLeBroadcast";
private static final int UNKNOWN_VALUE_PLACEHOLDER = -1;
private static final boolean DEBUG = BluetoothUtils.D;
- private BluetoothLeBroadcast mBluetoothLeBroadcast;
- private LocalBluetoothProfileManager mProfileManager;
+ static final String NAME = "LE_AUDIO_BROADCAST";
+ // Order of this profile in device profiles list
+ private static final int ORDINAL = 1;
+
+ private BluetoothLeBroadcast mService;
private BluetoothLeAudioContentMetadata mBluetoothLeAudioContentMetadata;
private BluetoothLeBroadcastMetadata mBluetoothLeBroadcastMetadata;
private BluetoothLeAudioContentMetadata.Builder mBuilder;
@@ -48,29 +66,27 @@ public class LocalBluetoothLeBroadcast implements BluetoothLeBroadcast.Callback
private final ServiceListener mServiceListener = new ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- if (profile == BluetoothProfile.LE_AUDIO_BROADCAST) {
- if (DEBUG) {
- Log.d(TAG,"Bluetooth service connected");
- }
- mBluetoothLeBroadcast = (BluetoothLeBroadcast) proxy;
- mProfileManager.callServiceConnectedListeners();
- mIsProfileReady = true;
+ if (DEBUG) {
+ Log.d(TAG, "Bluetooth service connected");
}
+ mService = (BluetoothLeBroadcast) proxy;
+ mIsProfileReady = true;
}
@Override
public void onServiceDisconnected(int profile) {
- if (profile == BluetoothProfile.LE_AUDIO_BROADCAST) {
- if (DEBUG) {
- Log.d(TAG,"Bluetooth service disconnected");
- }
- mIsProfileReady = false;
+ if (profile != BluetoothProfile.LE_AUDIO_BROADCAST) {
+ Log.d(TAG, "The profile is not LE_AUDIO_BROADCAST");
+ return;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Bluetooth service disconnected");
}
+ mIsProfileReady = false;
}
};
- LocalBluetoothLeBroadcast(Context context, LocalBluetoothProfileManager profileManager) {
- mProfileManager = profileManager;
+ LocalBluetoothLeBroadcast(Context context) {
BluetoothAdapter.getDefaultAdapter().
getProfileProxy(context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST);
mBuilder = new BluetoothLeAudioContentMetadata.Builder();
@@ -78,39 +94,58 @@ public class LocalBluetoothLeBroadcast implements BluetoothLeBroadcast.Callback
public void startBroadcast(byte[] broadcastCode, String language,
String programInfo) {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcast is null when starting the broadcast.");
+ return;
+ }
if (DEBUG) {
- if (mBluetoothLeBroadcast == null) {
- Log.d(TAG, "The BluetoothLeBroadcast is null when starting the broadcast.");
- return;
- }
Log.d(TAG, "startBroadcast: language = " + language + " ,programInfo = " + programInfo);
}
buildContentMetadata(language, programInfo);
- mBluetoothLeBroadcast.startBroadcast(mBluetoothLeAudioContentMetadata, broadcastCode);
+ mService.startBroadcast(mBluetoothLeAudioContentMetadata, broadcastCode);
}
public void stopBroadcast() {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcast is null when stopping the broadcast.");
+ return;
+ }
if (DEBUG) {
- if (mBluetoothLeBroadcast == null) {
- Log.d(TAG, "The BluetoothLeBroadcast is null when stopping the broadcast.");
- return;
- }
Log.d(TAG, "stopBroadcast()");
}
- mBluetoothLeBroadcast.stopBroadcast(mBroadcastId);
+ mService.stopBroadcast(mBroadcastId);
}
public void updateBroadcast(String language, String programInfo) {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcast is null when updating the broadcast.");
+ return;
+ }
if (DEBUG) {
- if (mBluetoothLeBroadcast == null) {
- Log.d(TAG, "The BluetoothLeBroadcast is null when updating the broadcast.");
- return;
- }
Log.d(TAG,
"updateBroadcast: language = " + language + " ,programInfo = " + programInfo);
}
mBluetoothLeAudioContentMetadata = mBuilder.setProgramInfo(programInfo).build();
- mBluetoothLeBroadcast.updateBroadcast(mBroadcastId, mBluetoothLeAudioContentMetadata);
+ mService.updateBroadcast(mBroadcastId, mBluetoothLeAudioContentMetadata);
+ }
+
+ public void registerServiceCallBack(@NonNull @CallbackExecutor Executor executor,
+ @NonNull BluetoothLeBroadcast.Callback callback) {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcast is null.");
+ return;
+ }
+
+ mService.registerCallback(executor, callback);
+ }
+
+ public void unregisterServiceCallBack(@NonNull BluetoothLeBroadcast.Callback callback) {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcast is null.");
+ return;
+ }
+
+ mService.unregisterCallback(callback);
}
private void buildContentMetadata(String language, String programInfo) {
@@ -122,71 +157,112 @@ public class LocalBluetoothLeBroadcast implements BluetoothLeBroadcast.Callback
return new LocalBluetoothLeBroadcastMetadata(mBluetoothLeBroadcastMetadata);
}
- @Override
- public void onBroadcastStarted(int reason, int broadcastId) {
- if (DEBUG) {
- Log.d(TAG,
- "onBroadcastStarted(), reason = " + reason + ", broadcastId = " + broadcastId);
- }
+ public boolean isProfileReady() {
+ return mIsProfileReady;
}
@Override
- public void onBroadcastStartFailed(int reason) {
- if (DEBUG) {
- Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
- }
+ public int getProfileId() {
+ return BluetoothProfile.LE_AUDIO_BROADCAST;
}
- @Override
- public void onBroadcastMetadataChanged(int broadcastId,
- @NonNull BluetoothLeBroadcastMetadata metadata) {
- if (DEBUG) {
- Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = " + broadcastId);
- }
- mBluetoothLeBroadcastMetadata = metadata;
+ public boolean accessProfileEnabled() {
+ return false;
}
- @Override
- public void onBroadcastStopped(int reason, int broadcastId) {
- if (DEBUG) {
- Log.d(TAG,
- "onBroadcastStopped(), reason = " + reason + ", broadcastId = " + broadcastId);
+ public boolean isAutoConnectable() {
+ return true;
+ }
+
+ /**
+ * Not supported since LE Audio Broadcasts do not establish a connection.
+ */
+ public int getConnectionStatus(BluetoothDevice device) {
+ if (mService == null) {
+ return BluetoothProfile.STATE_DISCONNECTED;
}
+ // LE Audio Broadcasts are not connection-oriented.
+ return mService.getConnectionState(device);
}
- @Override
- public void onBroadcastStopFailed(int reason) {
- if (DEBUG) {
- Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason);
+ /**
+ * Not supported since LE Audio Broadcasts do not establish a connection.
+ */
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (mService == null) {
+ return new ArrayList<BluetoothDevice>(0);
}
+ // LE Audio Broadcasts are not connection-oriented.
+ return mService.getConnectedDevices();
}
- @Override
- public void onBroadcastUpdated(int reason, int broadcastId) {
- if (DEBUG) {
- Log.d(TAG,
- "onBroadcastUpdated(), reason = " + reason + ", broadcastId = " + broadcastId);
+ public @NonNull List<BluetoothLeBroadcastMetadata> getAllBroadcastMetadata() {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcast is null.");
+ return Collections.emptyList();
}
+
+ return mService.getAllBroadcastMetadata();
}
- @Override
- public void onBroadcastUpdateFailed(int reason, int broadcastId) {
- if (DEBUG) {
- Log.d(TAG,
- "onBroadcastUpdateFailed(), reason = " + reason + ", broadcastId = "
- + broadcastId);
+ public boolean isEnabled(BluetoothDevice device) {
+ if (mService == null) {
+ return false;
}
+
+ return !mService.getAllBroadcastMetadata().isEmpty();
}
- @Override
- public void onPlaybackStarted(int reason, int broadcastId) {
+ /**
+ * Service does not provide method to get/set policy.
+ */
+ public int getConnectionPolicy(BluetoothDevice device) {
+ return CONNECTION_POLICY_FORBIDDEN;
}
- @Override
- public void onPlaybackStopped(int reason, int broadcastId) {
+ /**
+ * Service does not provide "setEnabled" method. Please use {@link #startBroadcast},
+ * {@link #stopBroadcast()} or {@link #updateBroadcast(String, String)}
+ */
+ public boolean setEnabled(BluetoothDevice device, boolean enabled) {
+ return false;
}
- public boolean isProfileReady() {
- return mIsProfileReady;
+ public String toString() {
+ return NAME;
+ }
+
+ public int getOrdinal() {
+ return ORDINAL;
+ }
+
+ public int getNameResource(BluetoothDevice device) {
+ return R.string.summary_empty;
+ }
+
+ public int getSummaryResourceForDevice(BluetoothDevice device) {
+ int state = getConnectionStatus(device);
+ return BluetoothUtils.getConnectionStateSummary(state);
+ }
+
+ public int getDrawableResource(BluetoothClass btClass) {
+ return 0;
+ }
+
+ @RequiresApi(Build.VERSION_CODES.S)
+ protected void finalize() {
+ if (DEBUG) {
+ Log.d(TAG, "finalize()");
+ }
+ if (mService != null) {
+ try {
+ BluetoothAdapter.getDefaultAdapter().closeProfileProxy(
+ BluetoothProfile.LE_AUDIO_BROADCAST,
+ mService);
+ mService = null;
+ } catch (Throwable t) {
+ Log.w(TAG, "Error cleaning up LeAudio proxy", t);
+ }
+ }
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
index 60632b677d1b..c248fff09d6f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
@@ -16,32 +16,48 @@
package com.android.settingslib.bluetooth;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastAssistant;
import android.bluetooth.BluetoothLeBroadcastMetadata;
-import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile.ServiceListener;
import android.content.Context;
+import android.os.Build;
import android.util.Log;
+import androidx.annotation.RequiresApi;
+
+import com.android.settingslib.R;
+
+import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
+
/**
* LocalBluetoothLeBroadcastAssistant provides an interface between the Settings app
* and the functionality of the local {@link BluetoothLeBroadcastAssistant}.
+ * Use the {@link BluetoothLeBroadcastAssistant.Callback} to get the result callback.
*/
-public class LocalBluetoothLeBroadcastAssistant implements
- BluetoothLeBroadcastAssistant.Callback {
-
+public class LocalBluetoothLeBroadcastAssistant implements LocalBluetoothProfile {
private static final String TAG = "LocalBluetoothLeBroadcastAssistant";
private static final int UNKNOWN_VALUE_PLACEHOLDER = -1;
private static final boolean DEBUG = BluetoothUtils.D;
+ static final String NAME = "LE_AUDIO_BROADCAST_ASSISTANT";
+ // Order of this profile in device profiles list
+ private static final int ORDINAL = 1;
+
private LocalBluetoothProfileManager mProfileManager;
- private BluetoothLeBroadcastAssistant mBluetoothLeBroadcastAssistant;
+ private BluetoothLeBroadcastAssistant mService;
+ private final CachedBluetoothDeviceManager mDeviceManager;
private BluetoothLeBroadcastMetadata mBluetoothLeBroadcastMetadata;
private BluetoothLeBroadcastMetadata.Builder mBuilder;
private boolean mIsProfileReady;
@@ -49,30 +65,51 @@ public class LocalBluetoothLeBroadcastAssistant implements
private final ServiceListener mServiceListener = new ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- if (profile == BluetoothProfile.LE_AUDIO_BROADCAST) {
- if (DEBUG) {
- Log.d(TAG,"Bluetooth service connected");
+ if (DEBUG) {
+ Log.d(TAG, "Bluetooth service connected");
+ }
+ mService = (BluetoothLeBroadcastAssistant) proxy;
+ // We just bound to the service, so refresh the UI for any connected LeAudio devices.
+ List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+ while (!deviceList.isEmpty()) {
+ BluetoothDevice nextDevice = deviceList.remove(0);
+ CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
+ // we may add a new device here, but generally this should not happen
+ if (device == null) {
+ if (DEBUG) {
+ Log.d(TAG, "LocalBluetoothLeBroadcastAssistant found new device: "
+ + nextDevice);
+ }
+ device = mDeviceManager.addDevice(nextDevice);
}
- mBluetoothLeBroadcastAssistant = (BluetoothLeBroadcastAssistant) proxy;
- mProfileManager.callServiceConnectedListeners();
- mIsProfileReady = true;
+ device.onProfileStateChanged(LocalBluetoothLeBroadcastAssistant.this,
+ BluetoothProfile.STATE_CONNECTED);
+ device.refresh();
}
+
+ mProfileManager.callServiceConnectedListeners();
+ mIsProfileReady = true;
}
@Override
public void onServiceDisconnected(int profile) {
- if (profile == BluetoothProfile.LE_AUDIO_BROADCAST) {
- if (DEBUG) {
- Log.d(TAG,"Bluetooth service disconnected");
- }
- mIsProfileReady = false;
+ if (profile != BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) {
+ Log.d(TAG, "The profile is not LE_AUDIO_BROADCAST_ASSISTANT");
+ return;
}
+ if (DEBUG) {
+ Log.d(TAG, "Bluetooth service disconnected");
+ }
+ mProfileManager.callServiceDisconnectedListeners();
+ mIsProfileReady = false;
}
};
public LocalBluetoothLeBroadcastAssistant(Context context,
+ CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
mProfileManager = profileManager;
+ mDeviceManager = deviceManager;
BluetoothAdapter.getDefaultAdapter().
getProfileProxy(context, mServiceListener,
BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT);
@@ -90,7 +127,11 @@ public class LocalBluetoothLeBroadcastAssistant implements
*/
public void addSource(BluetoothDevice sink, BluetoothLeBroadcastMetadata metadata,
boolean isGroupOp) {
- mBluetoothLeBroadcastAssistant.addSource(sink, metadata, isGroupOp);
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcastAssistant is null");
+ return;
+ }
+ mService.addSource(sink, metadata, isGroupOp);
}
/**
@@ -120,13 +161,9 @@ public class LocalBluetoothLeBroadcastAssistant implements
if (DEBUG) {
Log.d(TAG, "addSource()");
}
- if (mBluetoothLeBroadcastAssistant == null) {
- Log.d(TAG, "The BluetoothLeBroadcastAssistant is null");
- return ;
- }
buildMetadata(sourceAddressType, presentationDelayMicros, sourceAdvertisingSid, broadcastId,
paSyncInterval, isEncrypted, broadcastCode, sourceDevice);
- mBluetoothLeBroadcastAssistant.addSource(sink, mBluetoothLeBroadcastMetadata, isGroupOp);
+ addSource(sink, mBluetoothLeBroadcastMetadata, isGroupOp);
}
private void buildMetadata(int sourceAddressType, int presentationDelayMicros,
@@ -147,101 +184,143 @@ public class LocalBluetoothLeBroadcastAssistant implements
if (DEBUG) {
Log.d(TAG, "removeSource()");
}
- if (mBluetoothLeBroadcastAssistant == null) {
+ if (mService == null) {
Log.d(TAG, "The BluetoothLeBroadcastAssistant is null");
- return ;
+ return;
}
- mBluetoothLeBroadcastAssistant.removeSource(sink, sourceId);
+ mService.removeSource(sink, sourceId);
}
public void startSearchingForSources(@NonNull List<android.bluetooth.le.ScanFilter> filters) {
if (DEBUG) {
Log.d(TAG, "startSearchingForSources()");
}
- if (mBluetoothLeBroadcastAssistant == null) {
+ if (mService == null) {
Log.d(TAG, "The BluetoothLeBroadcastAssistant is null");
- return ;
+ return;
}
- mBluetoothLeBroadcastAssistant.startSearchingForSources(filters);
+ mService.startSearchingForSources(filters);
}
- @Override
- public void onSourceAdded(@NonNull BluetoothDevice sink, int sourceId, int reason) {
- if (DEBUG) {
- Log.d(TAG, "onSourceAdded(), reason = " + reason + " , sourceId = " + sourceId);
+ public void registerServiceCallBack(@NonNull @CallbackExecutor Executor executor,
+ @NonNull BluetoothLeBroadcastAssistant.Callback callback) {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcast is null.");
+ return;
}
+ mService.registerCallback(executor, callback);
}
- @Override
- public void onSourceAddFailed(@NonNull BluetoothDevice sink,
- @NonNull BluetoothLeBroadcastMetadata source, int reason) {
- if (DEBUG) {
- Log.d(TAG, "onSourceAddFailed(), reason = " + reason);
+ public void unregisterServiceCallBack(
+ @NonNull BluetoothLeBroadcastAssistant.Callback callback) {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcast is null.");
+ return;
}
+
+ mService.unregisterCallback(callback);
}
- @Override
- public void onSourceRemoved(@NonNull BluetoothDevice sink, int sourceId, int reason) {
- if (DEBUG) {
- Log.d(TAG, "onSourceRemoved(), reason = " + reason + " , sourceId = " + sourceId);
- }
+ public boolean isProfileReady() {
+ return mIsProfileReady;
}
- @Override
- public void onSourceRemoveFailed(@NonNull BluetoothDevice sink, int sourceId, int reason) {
- if (DEBUG) {
- Log.d(TAG, "onSourceRemoveFailed(), reason = " + reason + " , sourceId = " + sourceId);
+ public int getProfileId() {
+ return BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT;
+ }
+
+ public boolean accessProfileEnabled() {
+ return false;
+ }
+
+ public boolean isAutoConnectable() {
+ return true;
+ }
+
+ public int getConnectionStatus(BluetoothDevice device) {
+ if (mService == null) {
+ return BluetoothProfile.STATE_DISCONNECTED;
}
+ // LE Audio Broadcasts are not connection-oriented.
+ return mService.getConnectionState(device);
}
- @Override
- public void onSearchStarted(int reason) {
- if (DEBUG) {
- Log.d(TAG, "onSearchStarted(), reason = " + reason);
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (mService == null) {
+ return new ArrayList<BluetoothDevice>(0);
}
+ return mService.getDevicesMatchingConnectionStates(
+ new int[]{BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.STATE_CONNECTING,
+ BluetoothProfile.STATE_DISCONNECTING});
}
- @Override
- public void onSearchStartFailed(int reason) {
- if (DEBUG) {
- Log.d(TAG, "onSearchStartFailed(), reason = " + reason);
+ public boolean isEnabled(BluetoothDevice device) {
+ if (mService == null || device == null) {
+ return false;
}
+ return mService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN;
}
- @Override
- public void onSearchStopped(int reason) {
- if (DEBUG) {
- Log.d(TAG, "onSearchStopped(), reason = " + reason);
+ public int getConnectionPolicy(BluetoothDevice device) {
+ if (mService == null || device == null) {
+ return CONNECTION_POLICY_FORBIDDEN;
}
+ return mService.getConnectionPolicy(device);
}
- @Override
- public void onSearchStopFailed(int reason) {
- if (DEBUG) {
- Log.d(TAG, "onSearchStopFailed(), reason = " + reason);
+ public boolean setEnabled(BluetoothDevice device, boolean enabled) {
+ boolean isEnabled = false;
+ if (mService == null || device == null) {
+ return false;
}
+ if (enabled) {
+ if (mService.getConnectionPolicy(device) < CONNECTION_POLICY_ALLOWED) {
+ isEnabled = mService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
+ }
+ } else {
+ isEnabled = mService.setConnectionPolicy(device, CONNECTION_POLICY_FORBIDDEN);
+ }
+
+ return isEnabled;
}
- @Override
- public void onSourceFound(@NonNull BluetoothLeBroadcastMetadata source) {
+ public String toString() {
+ return NAME;
}
- @Override
- public void onSourceModified(@NonNull BluetoothDevice sink, int sourceId, int reason) {
+ public int getOrdinal() {
+ return ORDINAL;
}
- @Override
- public void onSourceModifyFailed(@NonNull BluetoothDevice sink, int sourceId, int reason) {
+ public int getNameResource(BluetoothDevice device) {
+ return R.string.summary_empty;
}
- @Override
- public void onReceiveStateChanged(@NonNull BluetoothDevice sink, int sourceId,
- @NonNull BluetoothLeBroadcastReceiveState state) {
+ public int getSummaryResourceForDevice(BluetoothDevice device) {
+ int state = getConnectionStatus(device);
+ return BluetoothUtils.getConnectionStateSummary(state);
}
- public boolean isProfileReady() {
- return mIsProfileReady;
+ public int getDrawableResource(BluetoothClass btClass) {
+ return 0;
}
+ @RequiresApi(Build.VERSION_CODES.S)
+ protected void finalize() {
+ if (DEBUG) {
+ Log.d(TAG, "finalize()");
+ }
+ if (mService != null) {
+ try {
+ BluetoothAdapter.getDefaultAdapter().closeProfileProxy(
+ BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT,
+ mService);
+ mService = null;
+ } catch (Throwable t) {
+ Log.w(TAG, "Error cleaning up LeAudio proxy", t);
+ }
+ }
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 7573177565a4..0619986d21f6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -27,6 +27,7 @@ import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothHidDevice;
import android.bluetooth.BluetoothHidHost;
import android.bluetooth.BluetoothLeAudio;
+import android.bluetooth.BluetoothLeBroadcastAssistant;
import android.bluetooth.BluetoothMap;
import android.bluetooth.BluetoothMapClient;
import android.bluetooth.BluetoothPan;
@@ -104,6 +105,8 @@ public class LocalBluetoothProfileManager {
private HearingAidProfile mHearingAidProfile;
private CsipSetCoordinatorProfile mCsipSetCoordinatorProfile;
private LeAudioProfile mLeAudioProfile;
+ private LocalBluetoothLeBroadcast mLeAudioBroadcast;
+ private LocalBluetoothLeBroadcastAssistant mLeAudioBroadcastAssistant;
private SapProfile mSapProfile;
private VolumeControlProfile mVolumeControlProfile;
@@ -238,7 +241,26 @@ public class LocalBluetoothProfileManager {
}
mLeAudioProfile = new LeAudioProfile(mContext, mDeviceManager, this);
addProfile(mLeAudioProfile, LeAudioProfile.NAME,
- BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
+ BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
+ }
+ if (mLeAudioBroadcast == null
+ && supportedList.contains(BluetoothProfile.LE_AUDIO_BROADCAST)) {
+ if (DEBUG) {
+ Log.d(TAG, "Adding local LE_AUDIO_BROADCAST profile");
+ }
+ mLeAudioBroadcast = new LocalBluetoothLeBroadcast(mContext);
+ // no event handler for the LE boradcast.
+ mProfileNameMap.put(LocalBluetoothLeBroadcast.NAME, mLeAudioBroadcast);
+ }
+ if (mLeAudioBroadcastAssistant == null
+ && supportedList.contains(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)) {
+ if (DEBUG) {
+ Log.d(TAG, "Adding local LE_AUDIO_BROADCAST_ASSISTANT profile");
+ }
+ mLeAudioBroadcastAssistant = new LocalBluetoothLeBroadcastAssistant(mContext,
+ mDeviceManager, this);
+ addProfile(mLeAudioBroadcastAssistant, LocalBluetoothLeBroadcast.NAME,
+ BluetoothLeBroadcastAssistant.ACTION_CONNECTION_STATE_CHANGED);
}
if (mCsipSetCoordinatorProfile == null
&& supportedList.contains(BluetoothProfile.CSIP_SET_COORDINATOR)) {
@@ -499,6 +521,13 @@ public class LocalBluetoothProfileManager {
return mLeAudioProfile;
}
+ public LocalBluetoothLeBroadcast getLeAudioBroadcastProfile() {
+ return mLeAudioBroadcast;
+ }
+ public LocalBluetoothLeBroadcastAssistant getLeAudioBroadcastAssistantProfile() {
+ return mLeAudioBroadcastAssistant;
+ }
+
SapProfile getSapProfile() {
return mSapProfile;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeActivity.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeActivity.java
new file mode 100644
index 000000000000..9021fcbc3f99
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeActivity.java
@@ -0,0 +1,109 @@
+/*
+ * 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.qrcode;
+
+import static com.android.settingslib.bluetooth.BluetoothBroadcastUtils.EXTRA_BLUETOOTH_DEVICE_SINK;
+import static com.android.settingslib.bluetooth.BluetoothBroadcastUtils.EXTRA_BLUETOOTH_SINK_IS_GROUP;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.fragment.app.FragmentTransaction;
+
+import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
+import com.android.settingslib.R;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+
+public class QrCodeScanModeActivity extends QrCodeScanModeBaseActivity {
+ private static final boolean DEBUG = BluetoothUtils.D;
+ private static final String TAG = "QrCodeScanModeActivity";
+
+ private boolean mIsGroupOp;
+ private BluetoothDevice mSink;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void handleIntent(Intent intent) {
+ String action = intent != null ? intent.getAction() : null;
+ if (DEBUG) {
+ Log.d(TAG, "handleIntent(), action = " + action);
+ }
+
+ if (action == null) {
+ finish();
+ return;
+ }
+
+ switch (action) {
+ case BluetoothBroadcastUtils.ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER:
+ showQrCodeScannerFragment(intent);
+ break;
+ default:
+ if (DEBUG) {
+ Log.e(TAG, "Launch with an invalid action");
+ }
+ finish();
+ }
+ }
+
+ protected void showQrCodeScannerFragment(Intent intent) {
+ if (DEBUG) {
+ Log.d(TAG, "showQrCodeScannerFragment");
+ }
+
+ if (intent != null) {
+ mSink = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE_SINK);
+ mIsGroupOp = intent.getBooleanExtra(EXTRA_BLUETOOTH_SINK_IS_GROUP, false);
+ if (DEBUG) {
+ Log.d(TAG, "get extra from intent");
+ }
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "intent is null, can not get bluetooth information from intent.");
+ }
+ }
+
+ QrCodeScanModeFragment fragment =
+ (QrCodeScanModeFragment) mFragmentManager.findFragmentByTag(
+ BluetoothBroadcastUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
+
+ if (fragment == null) {
+ fragment = new QrCodeScanModeFragment(mIsGroupOp, mSink);
+ } else {
+ if (fragment.isVisible()) {
+ return;
+ }
+
+ // When the fragment in back stack but not on top of the stack, we can simply pop
+ // stack because current fragment transactions are arranged in an order
+ mFragmentManager.popBackStackImmediate();
+ return;
+ }
+ final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+
+ fragmentTransaction.replace(R.id.fragment_container, fragment,
+ BluetoothBroadcastUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
+ fragmentTransaction.commit();
+ }
+}
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeBaseActivity.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeBaseActivity.java
new file mode 100644
index 000000000000..9aaec41e721a
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeBaseActivity.java
@@ -0,0 +1,46 @@
+/*
+ * 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.qrcode;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+import androidx.fragment.app.FragmentManager;
+
+import com.android.settingslib.core.lifecycle.ObservableActivity;
+import com.android.settingslib.R;
+
+public abstract class QrCodeScanModeBaseActivity extends ObservableActivity {
+
+ protected FragmentManager mFragmentManager;
+
+ protected abstract void handleIntent(Intent intent);
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setTheme(R.style.SudThemeGlifV3_DayNight);
+
+ setContentView(R.layout.qrcode_scan_mode_activity);
+ mFragmentManager = getSupportFragmentManager();
+
+ if (savedInstanceState == null) {
+ handleIntent(getIntent());
+ }
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeController.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeController.java
new file mode 100644
index 000000000000..d7640bb1b564
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeController.java
@@ -0,0 +1,82 @@
+/*
+ * 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.qrcode;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+public class QrCodeScanModeController {
+
+ private static final boolean DEBUG = BluetoothUtils.D;
+ private static final String TAG = "QrCodeScanModeController";
+
+ private LocalBluetoothLeBroadcastMetadata mLocalBroadcastMetadata;
+ private LocalBluetoothLeBroadcastAssistant mLocalBroadcastAssistant;
+ private LocalBluetoothManager mLocalBluetoothManager;
+ private LocalBluetoothProfileManager mProfileManager;
+
+ private LocalBluetoothManager.BluetoothManagerCallback
+ mOnInitCallback = new LocalBluetoothManager.BluetoothManagerCallback() {
+ @Override
+ public void onBluetoothManagerInitialized(Context appContext,
+ LocalBluetoothManager bluetoothManager) {
+ BluetoothUtils.setErrorListener(mErrorListener);
+ }
+ };
+
+ private BluetoothUtils.ErrorListener
+ mErrorListener = new BluetoothUtils.ErrorListener() {
+ @Override
+ public void onShowError(Context context, String name, int messageResId) {
+ if (DEBUG) {
+ Log.d(TAG, "Get error when initializing BluetoothManager. ");
+ }
+ }
+ };
+
+ public QrCodeScanModeController(Context context) {
+ if (DEBUG) {
+ Log.d(TAG, "QrCodeScanModeController constructor.");
+ }
+ mLocalBluetoothManager = LocalBluetoothManager.getInstance(context, mOnInitCallback);
+ mProfileManager = mLocalBluetoothManager.getProfileManager();
+ mLocalBroadcastMetadata = new LocalBluetoothLeBroadcastMetadata();
+ CachedBluetoothDeviceManager cachedDeviceManager = new CachedBluetoothDeviceManager(context,
+ mLocalBluetoothManager);
+ mLocalBroadcastAssistant = new LocalBluetoothLeBroadcastAssistant(context,
+ cachedDeviceManager, mProfileManager);
+ }
+
+ private BluetoothLeBroadcastMetadata convertToBroadcastMetadata(String qrCodeString) {
+ return mLocalBroadcastMetadata.convertToBroadcastMetadata(qrCodeString);
+ }
+
+ public void addSource(BluetoothDevice sink, String sourceMetadata,
+ boolean isGroupOp) {
+ mLocalBroadcastAssistant.addSource(sink,
+ convertToBroadcastMetadata(sourceMetadata), isGroupOp);
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeFragment.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeFragment.java
new file mode 100644
index 000000000000..81165aa3330c
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeFragment.java
@@ -0,0 +1,235 @@
+/*
+ * 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.qrcode;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Outline;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.util.Size;
+import android.view.LayoutInflater;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.TextView;
+
+import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.R;
+import com.android.settingslib.core.lifecycle.ObservableFragment;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+
+public class QrCodeScanModeFragment extends ObservableFragment implements
+ TextureView.SurfaceTextureListener,
+ QrCamera.ScannerCallback {
+ private static final boolean DEBUG = BluetoothUtils.D;
+ private static final String TAG = "QrCodeScanModeFragment";
+
+ /** Message sent to hide error message */
+ private static final int MESSAGE_HIDE_ERROR_MESSAGE = 1;
+ /** Message sent to show error message */
+ private static final int MESSAGE_SHOW_ERROR_MESSAGE = 2;
+ /** Message sent to broadcast QR code */
+ private static final int MESSAGE_SCAN_BROADCAST_SUCCESS = 3;
+
+ private static final long SHOW_ERROR_MESSAGE_INTERVAL = 10000;
+ private static final long SHOW_SUCCESS_SQUARE_INTERVAL = 1000;
+
+ private boolean mIsGroupOp;
+ private int mCornerRadius;
+ private BluetoothDevice mSink;
+ private String mBroadcastMetadata;
+ private Context mContext;
+ private QrCamera mCamera;
+ private QrCodeScanModeController mController;
+ private TextureView mTextureView;
+ private TextView mSummary;
+ private TextView mErrorMessage;
+
+ public QrCodeScanModeFragment(boolean isGroupOp, BluetoothDevice sink) {
+ mIsGroupOp = isGroupOp;
+ mSink = sink;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getContext();
+ mController = new QrCodeScanModeController(mContext);
+ }
+
+ @Override
+ public final View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.qrcode_scanner_fragment, container,
+ /* attachToRoot */ false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ mTextureView = view.findViewById(R.id.preview_view);
+ mCornerRadius = mContext.getResources().getDimensionPixelSize(
+ R.dimen.qrcode_preview_radius);
+ mTextureView.setSurfaceTextureListener(this);
+ mTextureView.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(0,0, view.getWidth(), view.getHeight(), mCornerRadius);
+ }
+ });
+ mTextureView.setClipToOutline(true);
+ mErrorMessage = view.findViewById(R.id.error_message);
+ }
+
+ private void initCamera(SurfaceTexture surface) {
+ // Check if the camera has already created.
+ if (mCamera == null) {
+ mCamera = new QrCamera(mContext, this);
+ mCamera.start(surface);
+ }
+ }
+
+ private void destroyCamera() {
+ if (mCamera != null) {
+ mCamera.stop();
+ mCamera = null;
+ }
+ }
+
+ @Override
+ public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
+ initCamera(surface);
+ }
+
+ @Override
+ public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width,
+ int height) {
+ }
+
+ @Override
+ public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
+ destroyCamera();
+ return true;
+ }
+
+ @Override
+ public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
+ }
+
+ @Override
+ public void handleSuccessfulResult(String qrCode) {
+ if (DEBUG) {
+ Log.d(TAG, "handleSuccessfulResult(), get the qr code string.");
+ }
+ mBroadcastMetadata = qrCode;
+ handleBtLeAudioScanner();
+ }
+
+ @Override
+ public void handleCameraFailure() {
+ destroyCamera();
+ }
+
+ @Override
+ public Size getViewSize() {
+ return new Size(mTextureView.getWidth(), mTextureView.getHeight());
+ }
+
+ @Override
+ public Rect getFramePosition(Size previewSize, int cameraOrientation) {
+ return new Rect(0, 0, previewSize.getHeight(), previewSize.getHeight());
+ }
+
+ @Override
+ public void setTransform(Matrix transform) {
+ mTextureView.setTransform(transform);
+ }
+
+ @Override
+ public boolean isValid(String qrCode) {
+ if (qrCode.startsWith(BluetoothBroadcastUtils.SCHEME_BT_BROADCAST_METADATA)) {
+ return true;
+ } else {
+ showErrorMessage(R.string.bt_le_audio_qr_code_is_not_valid_format);
+ return false;
+ }
+ }
+
+ protected boolean isDecodeTaskAlive() {
+ return mCamera != null && mCamera.isDecodeTaskAlive();
+ }
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_HIDE_ERROR_MESSAGE:
+ mErrorMessage.setVisibility(View.INVISIBLE);
+ break;
+
+ case MESSAGE_SHOW_ERROR_MESSAGE:
+ final String errorMessage = (String) msg.obj;
+
+ mErrorMessage.setVisibility(View.VISIBLE);
+ mErrorMessage.setText(errorMessage);
+ mErrorMessage.sendAccessibilityEvent(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+
+ // Cancel any pending messages to hide error view and requeue the message so
+ // user has time to see error
+ removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
+ sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
+ SHOW_ERROR_MESSAGE_INTERVAL);
+ break;
+
+ case MESSAGE_SCAN_BROADCAST_SUCCESS:
+ mController.addSource(mSink, mBroadcastMetadata, mIsGroupOp);
+ updateSummary();
+ mSummary.sendAccessibilityEvent(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ break;
+ default:
+ }
+ }
+ };
+
+ private void showErrorMessage(@StringRes int messageResId) {
+ final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
+ getString(messageResId));
+ message.sendToTarget();
+ }
+
+ private void handleBtLeAudioScanner() {
+ Message message = mHandler.obtainMessage(MESSAGE_SCAN_BROADCAST_SUCCESS);
+ mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL);
+ }
+
+ private void updateSummary() {
+ mSummary.setText(getString(R.string.bt_le_audio_scan_qr_code_scanner,
+ null /* broadcast_name*/));;
+ }
+}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index a10ca9e75355..a28c4cf6b0d4 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -575,6 +575,9 @@
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
<uses-permission android:name="android.permission.TRUST_LISTENER" />
+ <!-- Permission required for CTS test - CtsTaskFpsCallbackTestCases -->
+ <uses-permission android:name="android.permission.ACCESS_FPS_COUNTER" />
+
<!-- Permission required for CTS test - CtsGameManagerTestCases -->
<uses-permission android:name="android.permission.MANAGE_GAME_MODE" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index 75d95e6d85e3..f78046d38168 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -15,7 +15,6 @@
package com.android.systemui.plugins.qs;
import android.view.View;
-import android.view.View.OnClickListener;
import com.android.systemui.plugins.FragmentBase;
import com.android.systemui.plugins.annotations.DependsOn;
@@ -34,7 +33,7 @@ public interface QS extends FragmentBase {
String ACTION = "com.android.systemui.action.PLUGIN_QS";
- int VERSION = 13;
+ int VERSION = 14;
String TAG = "QS";
@@ -68,7 +67,12 @@ public interface QS extends FragmentBase {
void setHeaderListening(boolean listening);
void notifyCustomizeChanged();
void setContainerController(QSContainerController controller);
- void setExpandClickListener(OnClickListener onClickListener);
+
+ /**
+ * Provide an action to collapse if expanded or expand if collapsed.
+ * @param action
+ */
+ void setCollapseExpandAction(Runnable action);
/**
* Returns the height difference between the QSPanel container and the QuickQSPanel container
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java
index 9a9683dbfb5c..a8999ff31f8a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java
@@ -26,7 +26,7 @@ import com.android.systemui.plugins.qs.QSTile.State;
@DependsOn(target = QSIconView.class)
@DependsOn(target = QSTile.class)
public abstract class QSTileView extends LinearLayout {
- public static final int VERSION = 2;
+ public static final int VERSION = 3;
public QSTileView(Context context) {
super(context);
@@ -71,4 +71,7 @@ public abstract class QSTileView extends LinearLayout {
public View getSecondaryLabel() {
return null;
}
+
+ /** Sets the index of this tile in its layout */
+ public abstract void setPosition(int position);
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
index 9829918a0302..9ed3bac57e66 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
@@ -94,6 +94,12 @@ public interface StatusBarStateController {
}
/**
+ * Callback to be notified about upcoming state changes. Typically, is immediately followed
+ * by #onStateChanged, unless there was an intentional delay in updating the state changed.
+ */
+ default void onUpcomingStateChanged(int upcomingState) {}
+
+ /**
* Callback to be notified when Dozing changes. Dozing is stored separately from state.
*/
default void onDozingChanged(boolean isDozing) {}
diff --git a/packages/SystemUI/res-keyguard/layout/fgs_footer.xml b/packages/SystemUI/res-keyguard/layout/fgs_footer.xml
index 9d801d2a0ecf..9ffafbc8cc09 100644
--- a/packages/SystemUI/res-keyguard/layout/fgs_footer.xml
+++ b/packages/SystemUI/res-keyguard/layout/fgs_footer.xml
@@ -16,8 +16,9 @@
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:layout_height="@dimen/qs_security_footer_single_line_height"
+ android:layout_weight="1"
android:gravity="center"
android:clickable="true"
android:visibility="gone">
@@ -26,7 +27,7 @@
android:id="@+id/fgs_text_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginEnd="@dimen/new_qs_footer_action_inset"
+ android:layout_marginEnd="@dimen/qs_footer_action_inset"
android:background="@drawable/qs_security_footer_background"
android:layout_gravity="end"
android:gravity="center"
@@ -86,7 +87,7 @@
android:layout_height="12dp"
android:scaleType="fitCenter"
android:layout_gravity="bottom|end"
- android:src="@drawable/new_fgs_dot"
+ android:src="@drawable/fgs_dot"
android:contentDescription="@string/fgs_dot_content_description"
/>
</FrameLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/footer_actions.xml b/packages/SystemUI/res-keyguard/layout/footer_actions.xml
index fb401ee1d918..6a1d62d5c611 100644
--- a/packages/SystemUI/res-keyguard/layout/footer_actions.xml
+++ b/packages/SystemUI/res-keyguard/layout/footer_actions.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-** Copyright 2021, The Android Open Source Project
+** Copyright 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.
@@ -18,65 +18,80 @@
<!-- Action buttons for footer in QS/QQS, containing settings button, power off button etc -->
<com.android.systemui.qs.FooterActionsView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="match_parent"
- android:layout_height="@dimen/qs_footer_height"
+ android:layout_height="@dimen/footer_actions_height"
+ android:elevation="@dimen/qs_panel_elevation"
+ android:paddingTop="8dp"
+ android:paddingBottom="4dp"
+ android:background="@drawable/qs_footer_actions_background"
android:gravity="center_vertical"
android:layout_gravity="bottom"
>
- <com.android.systemui.statusbar.phone.MultiUserSwitch
- android:id="@+id/multi_user_switch"
- android:layout_width="0dp"
+ <LinearLayout
+ android:id="@+id/security_footers_container"
+ android:orientation="horizontal"
android:layout_height="@dimen/qs_footer_action_button_size"
- android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
+ android:layout_width="0dp"
android:layout_weight="1"
- android:background="@drawable/qs_footer_action_chip_background"
- android:focusable="true">
+ />
- <ImageView
- android:id="@+id/multi_user_avatar"
- android:layout_width="@dimen/multi_user_avatar_expanded_size"
- android:layout_height="@dimen/multi_user_avatar_expanded_size"
- android:layout_gravity="center"
- android:scaleType="centerInside" />
- </com.android.systemui.statusbar.phone.MultiUserSwitch>
+ <!-- Negative margin equal to -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_marginEnd="@dimen/qs_footer_action_inset_negative"
+ >
- <com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/pm_lite"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_footer_action_button_size"
- android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
- android:layout_weight="1"
- android:background="@drawable/qs_footer_action_chip_background"
- android:clickable="true"
- android:clipToPadding="false"
- android:focusable="true"
- android:padding="@dimen/qs_footer_icon_padding"
- android:src="@*android:drawable/ic_lock_power_off"
- android:contentDescription="@string/accessibility_quick_settings_power_menu"
- android:tint="?android:attr/textColorPrimary" />
+ <com.android.systemui.statusbar.phone.MultiUserSwitch
+ android:id="@+id/multi_user_switch"
+ android:layout_width="@dimen/qs_footer_action_button_size"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:background="@drawable/qs_footer_action_circle"
+ android:focusable="true">
- <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
- android:id="@+id/settings_button_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_footer_action_button_size"
- android:background="@drawable/qs_footer_action_chip_background"
- android:layout_weight="1"
- android:clipChildren="false"
- android:clipToPadding="false">
+ <ImageView
+ android:id="@+id/multi_user_avatar"
+ android:layout_width="@dimen/qs_footer_icon_size"
+ android:layout_height="@dimen/qs_footer_icon_size"
+ android:layout_gravity="center"
+ android:scaleType="centerInside" />
+ </com.android.systemui.statusbar.phone.MultiUserSwitch>
- <com.android.systemui.statusbar.phone.SettingsButton
- android:id="@+id/settings_button"
- android:layout_width="match_parent"
+ <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
+ android:id="@+id/settings_button_container"
+ android:layout_width="@dimen/qs_footer_action_button_size"
android:layout_height="@dimen/qs_footer_action_button_size"
- android:layout_gravity="center"
- android:contentDescription="@string/accessibility_quick_settings_settings"
- android:background="@drawable/qs_footer_action_chip_background_borderless"
- android:padding="@dimen/qs_footer_icon_padding"
- android:scaleType="centerInside"
- android:src="@drawable/ic_settings"
- android:tint="?android:attr/textColorPrimary" />
+ android:background="@drawable/qs_footer_action_circle"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ <com.android.systemui.statusbar.phone.SettingsButton
+ android:id="@+id/settings_button"
+ android:layout_width="@dimen/qs_footer_icon_size"
+ android:layout_height="@dimen/qs_footer_icon_size"
+ android:layout_gravity="center"
+ android:background="@android:color/transparent"
+ android:contentDescription="@string/accessibility_quick_settings_settings"
+ android:scaleType="centerInside"
+ android:src="@drawable/ic_settings"
+ android:tint="?android:attr/textColorPrimary" />
- </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
+ </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/pm_lite"
+ android:layout_width="@dimen/qs_footer_action_button_size"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:background="@drawable/qs_footer_action_circle_color"
+ android:clickable="true"
+ android:clipToPadding="false"
+ android:focusable="true"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:src="@*android:drawable/ic_lock_power_off"
+ android:contentDescription="@string/accessibility_quick_settings_power_menu"
+ android:tint="?androidprv:attr/textColorOnAccent" />
+ </LinearLayout>
</com.android.systemui.qs.FooterActionsView> \ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
index b765f497f9c4..dae2e564dd32 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
@@ -59,16 +59,17 @@
android:layout_height="wrap_content"
android:paddingBottom="4dp"
>
+
<com.android.keyguard.PasswordTextView
- android:id="@+id/simPinEntry"
- android:layout_width="@dimen/keyguard_security_width"
- android:layout_height="@dimen/keyguard_password_height"
- android:gravity="center"
- android:layout_centerHorizontal="true"
- android:layout_marginRight="72dp"
- androidprv:scaledTextSize="@integer/scaled_password_text_size"
- android:contentDescription="@string/keyguard_accessibility_sim_pin_area"
- />
+ android:id="@+id/simPinEntry"
+ style="@style/Widget.TextView.Password"
+ android:layout_width="@dimen/keyguard_security_width"
+ android:layout_height="@dimen/keyguard_password_height"
+ android:layout_centerHorizontal="true"
+ android:layout_marginRight="72dp"
+ android:contentDescription="@string/keyguard_accessibility_sim_pin_area"
+ android:gravity="center"
+ androidprv:scaledTextSize="@integer/scaled_password_text_size" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
index 917ea6b6c518..74f78201e677 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
@@ -60,16 +60,17 @@
android:layout_height="wrap_content"
android:paddingBottom="4dp"
>
+
<com.android.keyguard.PasswordTextView
- android:id="@+id/pukEntry"
- android:layout_width="@dimen/keyguard_security_width"
- android:layout_height="@dimen/keyguard_password_height"
- android:gravity="center"
- android:layout_centerHorizontal="true"
- android:layout_marginRight="72dp"
- androidprv:scaledTextSize="@integer/scaled_password_text_size"
- android:contentDescription="@string/keyguard_accessibility_sim_puk_area"
- />
+ android:id="@+id/pukEntry"
+ style="@style/Widget.TextView.Password"
+ android:layout_width="@dimen/keyguard_security_width"
+ android:layout_height="@dimen/keyguard_password_height"
+ android:layout_centerHorizontal="true"
+ android:layout_marginRight="72dp"
+ android:contentDescription="@string/keyguard_accessibility_sim_puk_area"
+ android:gravity="center"
+ androidprv:scaledTextSize="@integer/scaled_password_text_size" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml b/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml
deleted file mode 100644
index 59712c088f7a..000000000000
--- a/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-** Copyright 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.
--->
-
-<!-- Action buttons for footer in QS/QQS, containing settings button, power off button etc -->
-<com.android.systemui.qs.FooterActionsView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/new_footer_height"
- android:elevation="@dimen/qs_panel_elevation"
- android:paddingTop="8dp"
- android:paddingBottom="4dp"
- android:background="@drawable/qs_footer_actions_background"
- android:gravity="center_vertical"
- android:layout_gravity="bottom"
->
-
- <LinearLayout
- android:id="@+id/security_footers_container"
- android:orientation="horizontal"
- android:layout_height="@dimen/qs_footer_action_button_size"
- android:layout_width="0dp"
- android:layout_weight="1"
- />
-
- <!-- Negative margin equal to -->
- <LinearLayout
- android:layout_height="match_parent"
- android:layout_width="wrap_content"
- android:layout_marginEnd="@dimen/new_qs_footer_action_inset_negative"
- >
-
- <com.android.systemui.statusbar.phone.MultiUserSwitch
- android:id="@+id/multi_user_switch"
- android:layout_width="@dimen/qs_footer_action_button_size"
- android:layout_height="@dimen/qs_footer_action_button_size"
- android:background="@drawable/qs_footer_action_circle"
- android:focusable="true">
-
- <ImageView
- android:id="@+id/multi_user_avatar"
- android:layout_width="@dimen/qs_footer_icon_size"
- android:layout_height="@dimen/qs_footer_icon_size"
- android:layout_gravity="center"
- android:scaleType="centerInside" />
- </com.android.systemui.statusbar.phone.MultiUserSwitch>
-
- <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
- android:id="@+id/settings_button_container"
- android:layout_width="@dimen/qs_footer_action_button_size"
- android:layout_height="@dimen/qs_footer_action_button_size"
- android:background="@drawable/qs_footer_action_circle"
- android:clipChildren="false"
- android:clipToPadding="false">
-
- <com.android.systemui.statusbar.phone.SettingsButton
- android:id="@+id/settings_button"
- android:layout_width="@dimen/qs_footer_icon_size"
- android:layout_height="@dimen/qs_footer_icon_size"
- android:layout_gravity="center"
- android:background="@android:color/transparent"
- android:contentDescription="@string/accessibility_quick_settings_settings"
- android:scaleType="centerInside"
- android:src="@drawable/ic_settings"
- android:tint="?android:attr/textColorPrimary" />
-
- </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
-
- <com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/pm_lite"
- android:layout_width="@dimen/qs_footer_action_button_size"
- android:layout_height="@dimen/qs_footer_action_button_size"
- android:background="@drawable/qs_footer_action_circle_color"
- android:clickable="true"
- android:clipToPadding="false"
- android:focusable="true"
- android:padding="@dimen/qs_footer_icon_padding"
- android:src="@*android:drawable/ic_lock_power_off"
- android:contentDescription="@string/accessibility_quick_settings_power_menu"
- android:tint="?androidprv:attr/textColorOnAccent" />
-
- </LinearLayout>
-</com.android.systemui.qs.FooterActionsView> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/new_fgs_dot.xml b/packages/SystemUI/res/drawable/fgs_dot.xml
index 3669e1d3c374..3669e1d3c374 100644
--- a/packages/SystemUI/res/drawable/new_fgs_dot.xml
+++ b/packages/SystemUI/res/drawable/fgs_dot.xml
diff --git a/packages/SystemUI/res/drawable/overlay_cancel.xml b/packages/SystemUI/res/drawable/overlay_cancel.xml
index 65b43541cf3f..f9786e22b2d4 100644
--- a/packages/SystemUI/res/drawable/overlay_cancel.xml
+++ b/packages/SystemUI/res/drawable/overlay_cancel.xml
@@ -21,7 +21,7 @@
android:viewportWidth="32.0"
android:viewportHeight="32.0">
<path
- android:fillColor="?androidprv:attr/colorAccentSecondary"
+ android:fillColor="?androidprv:attr/colorAccentTertiary"
android:pathData="M16,16m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"/>
<path
android:fillColor="?android:attr/textColorPrimary"
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml b/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
deleted file mode 100644
index 9076da795e71..000000000000
--- a/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2021 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetTop="@dimen/qs_footer_action_inset"
- android:insetBottom="@dimen/qs_footer_action_inset">
- <ripple
- android:color="?android:attr/colorControlHighlight"
- android:height="44dp">
- <item android:id="@android:id/mask">
- <shape android:shape="rectangle">
- <solid android:color="@android:color/white"/>
- <corners android:radius="@dimen/qs_footer_action_corner_radius"/>
- </shape>
- </item>
- <item>
- <shape android:shape="rectangle">
- <solid android:color="?attr/underSurfaceColor"/>
- <corners android:radius="@dimen/qs_footer_action_corner_radius"/>
- </shape>
- </item>
- <item>
- <shape android:shape="rectangle">
- <stroke android:width="1dp" android:color="?android:attr/colorBackground"/>
- <corners android:radius="@dimen/qs_footer_action_corner_radius"/>
- </shape>
- </item>
- </ripple>
-</inset> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml b/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml
deleted file mode 100644
index bbcfb15d9226..000000000000
--- a/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2021 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetTop="@dimen/qs_footer_action_inset"
- android:insetBottom="@dimen/qs_footer_action_inset">
- <ripple
- android:color="?android:attr/colorControlHighlight">
- <item android:id="@android:id/mask">
- <shape android:shape="rectangle">
- <solid android:color="@android:color/white"/>
- <corners android:radius="@dimen/qs_footer_action_corner_radius"/>
- </shape>
- </item>
- <item>
- <shape android:shape="rectangle">
- <solid android:color="@android:color/transparent"/>
- <corners android:radius="@dimen/qs_footer_action_corner_radius"/>
- </shape>
- </item>
- </ripple>
-</inset> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_circle.xml b/packages/SystemUI/res/drawable/qs_footer_action_circle.xml
index 31a8c3bc2397..c8c36b0081c0 100644
--- a/packages/SystemUI/res/drawable/qs_footer_action_circle.xml
+++ b/packages/SystemUI/res/drawable/qs_footer_action_circle.xml
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:inset="@dimen/new_qs_footer_action_inset">
+ android:inset="@dimen/qs_footer_action_inset">
<ripple
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask">
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_circle_color.xml b/packages/SystemUI/res/drawable/qs_footer_action_circle_color.xml
index 021a85f6a244..6a365000a21c 100644
--- a/packages/SystemUI/res/drawable/qs_footer_action_circle_color.xml
+++ b/packages/SystemUI/res/drawable/qs_footer_action_circle_color.xml
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:inset="@dimen/new_qs_footer_action_inset">
+ android:inset="@dimen/qs_footer_action_inset">
<ripple
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask">
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index c0436b272d64..ccfd3a3d79f0 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -136,6 +136,7 @@
android:layout_height="@dimen/overlay_dismiss_button_tappable_size"
android:elevation="@dimen/overlay_dismiss_button_elevation"
android:visibility="gone"
+ android:alpha="0"
app:layout_constraintStart_toEndOf="@id/clipboard_preview"
app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
app:layout_constraintTop_toTopOf="@id/clipboard_preview"
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 836f59dc8fb2..1efb4796b5b7 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -82,6 +82,7 @@
android:id="@+id/device_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_weight="1"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index e1f3eca3fd63..23d7211867ca 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -21,8 +21,8 @@
android:id="@+id/qs_media_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
+ android:clipChildren="true"
+ android:clipToPadding="true"
android:gravity="center_horizontal|fill_vertical"
android:forceHasOverlappingRendering="false"
android:background="@drawable/qs_media_background"
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index b6e34998a7cd..b1d3ed05333b 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -29,11 +29,6 @@
android:clipChildren="false"
android:clipToPadding="false">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/qs_footer_height"
@@ -80,14 +75,4 @@
</LinearLayout>
- <ViewStub
- android:id="@+id/footer_stub"
- android:inflatedId="@+id/qs_footer_actions"
- android:layout="@layout/footer_actions"
- android:layout_height="@dimen/qs_footer_height"
- android:layout_width="match_parent"
- />
-
- </LinearLayout>
-
</com.android.systemui.qs.QSFooterView>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 20400510a31a..1eb05bfd602d 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -47,11 +47,10 @@
<include layout="@layout/quick_status_bar_expanded_header" />
- <ViewStub
- android:id="@+id/container_stub"
- android:inflatedId="@+id/qs_footer_actions"
- android:layout="@layout/new_footer_actions"
- android:layout_height="@dimen/new_footer_height"
+ <include
+ layout="@layout/footer_actions"
+ android:id="@+id/qs_footer_actions"
+ android:layout_height="@dimen/footer_actions_height"
android:layout_width="match_parent"
android:layout_gravity="bottom"
/>
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 02c58e468c30..77523ec9229f 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -24,6 +24,8 @@
android:orientation="vertical"
android:layout_marginStart="@dimen/qs_label_container_margin"
android:layout_marginEnd="0dp"
+ android:focusable="false"
+ android:importantForAccessibility="no"
android:layout_gravity="center_vertical | start">
<com.android.systemui.util.SafeMarqueeTextView
@@ -35,6 +37,8 @@
android:ellipsize="marquee"
android:marqueeRepeatLimit="1"
android:singleLine="true"
+ android:focusable="false"
+ android:importantForAccessibility="no"
android:textAppearance="@style/TextAppearance.QS.TileLabel"/>
<com.android.systemui.util.SafeMarqueeTextView
@@ -47,6 +51,8 @@
android:marqueeRepeatLimit="1"
android:singleLine="true"
android:visibility="gone"
+ android:focusable="false"
+ android:importantForAccessibility="no"
android:textAppearance="@style/TextAppearance.QS.TileLabel.Secondary"
android:textColor="?android:attr/textColorSecondary"/>
diff --git a/packages/SystemUI/res/layout/quick_settings_security_footer.xml b/packages/SystemUI/res/layout/quick_settings_security_footer.xml
index 08bd71c12eb1..1b11816465ac 100644
--- a/packages/SystemUI/res/layout/quick_settings_security_footer.xml
+++ b/packages/SystemUI/res/layout/quick_settings_security_footer.xml
@@ -14,19 +14,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.systemui.util.DualHeightHorizontalLinearLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="@dimen/qs_security_footer_height"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_security_footer_single_line_height"
+ android:layout_weight="1"
android:clickable="true"
- android:padding="@dimen/qs_footer_padding"
+ android:orientation="horizontal"
+ android:paddingHorizontal="@dimen/qs_footer_padding"
android:gravity="center_vertical"
android:layout_gravity="center_vertical|center_horizontal"
- android:layout_marginBottom="@dimen/qs_footers_margin_bottom"
+ android:layout_marginEnd="@dimen/qs_footer_action_inset"
android:background="@drawable/qs_security_footer_background"
- systemui:singleLineHeight="@dimen/qs_security_footer_single_line_height"
- systemui:textViewId="@id/footer_text"
>
<ImageView
@@ -43,7 +42,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:maxLines="@integer/qs_security_footer_maxLines"
+ android:singleLine="true"
android:ellipsize="end"
android:textAppearance="@style/TextAppearance.QS.SecurityFooter"
android:textColor="?android:attr/textColorSecondary"/>
@@ -58,4 +57,4 @@
android:autoMirrored="true"
android:tint="?android:attr/textColorSecondary" />
-</com.android.systemui.util.DualHeightHorizontalLinearLayout>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml b/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml
index b1e8c386fe21..60bc3732cde0 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml
@@ -52,7 +52,6 @@
<!-- We want this to be centered (to align with notches). In order to do that, the following
has to hold (in portrait):
* date_container and privacy_container must have the same width and weight
- * header_text_container must be gone
-->
<android.widget.Space
android:id="@+id/space"
@@ -61,17 +60,6 @@
android:layout_gravity="center_vertical|center_horizontal"
android:visibility="gone" />
- <!-- Will hold security footer in landscape with media -->
- <FrameLayout
- android:id="@+id/header_text_container"
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:gravity="center"
- />
-
<FrameLayout
android:id="@+id/privacy_container"
android:layout_width="0dp"
diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml
index 8de80844d784..c60609b06d38 100644
--- a/packages/SystemUI/res/layout/screenshot_static.xml
+++ b/packages/SystemUI/res/layout/screenshot_static.xml
@@ -98,6 +98,7 @@
android:scaleType="fitEnd"
android:background="@drawable/overlay_preview_background"
android:adjustViewBounds="true"
+ android:clickable="true"
app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border"
app:layout_constraintStart_toStartOf="@id/screenshot_preview_border"
app:layout_constraintEnd_toEndOf="@id/screenshot_preview_border"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_shelf.xml b/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
index 87a1bbb2aa5c..58c545036b27 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
@@ -17,6 +17,7 @@
<!-- Extends FrameLayout -->
<com.android.systemui.statusbar.NotificationShelf
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/notificationShelf"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_shelf_height"
android:focusable="true"
diff --git a/packages/SystemUI/res/layout/udfps_view.xml b/packages/SystemUI/res/layout/udfps_view.xml
index 0fcbfa161ddf..257d238f5c54 100644
--- a/packages/SystemUI/res/layout/udfps_view.xml
+++ b/packages/SystemUI/res/layout/udfps_view.xml
@@ -28,10 +28,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- <com.android.systemui.biometrics.UdfpsSurfaceView
- android:id="@+id/hbm_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible"/>
-
</com.android.systemui.biometrics.UdfpsView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 5123f70c62b9..1feeede180d3 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Outodraai skerm"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Laat <xliff:g id="APPLICATION">%1$s</xliff:g> toe om by <xliff:g id="USB_DEVICE">%2$s</xliff:g> in te gaan?\nOpneemtoestemming is nie aan hierdie program verleen nie, maar dit kan oudio deur hierdie USB-toestel vasvang."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Maak <xliff:g id="APPLICATION">%1$s</xliff:g> oop om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te hanteer?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Opneemtoestemming is nie aan hierdie program verleen nie, maar dit kan oudio deur hierdie USB-toestel opneem. As jy <xliff:g id="APPLICATION">%1$s</xliff:g> met hierdie toestel gebruik, kan dit verhinder dat jy oproepe, kennisgewings en wekkers hoor."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"As jy <xliff:g id="APPLICATION">%1$s</xliff:g> met hierdie toestel gebruik, kan dit verhinder dat jy oproepe, kennisgewings en wekkers hoor."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Maak <xliff:g id="APPLICATION">%1$s</xliff:g> oop om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te hanteer?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Maak <xliff:g id="APPLICATION">%1$s</xliff:g> oop om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te hanteer?\nOpneemtoestemming is nie aan hierdie program verleen nie, maar dit kan oudio deur hierdie USB-toestel vasvang."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Ontsluit met jou gesig. Druk om voort te gaan."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Gestaaf"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gebruik PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gebruik patroon"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Dit deblokkeer toegang vir alle programme en dienste wat toegelaat word om jou mikrofoon te gebruik."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Dit deblokkeer toegang vir alle programme en dienste wat toegelaat word om jou kamera te gebruik."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Dit deblokkeer toegang vir alle programme en dienste wat toegelaat word om jou kamera of mikrofoon te gebruik."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Ander toestel"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Wissel oorsig"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Jy sal nie deur geluide en vibrasies gepla word nie, behalwe deur wekkers, herinneringe, geleenthede en bellers wat jy spesifiseer. Jy sal steeds enigiets hoor wat jy kies om te speel, insluitend musiek, video\'s en speletjies."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laaidok • Vol oor <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwyder"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gas!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Wiil jy jou sessie voortsit?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Begin van voor af"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Voeg by"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Voorgestel deur <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Toestel is gesluit"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN bevat letters of simbole"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifieer <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Verkeerde PIN"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die program oop om hierdie sessie uit te saai."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende program"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hou op uitsaai"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
<string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiewe programme"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Gestop"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopieer"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Gekopieer"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Van <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Maak kopieer-UI toe"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 6793e1032dcf..66bb3a3fb4b6 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ማያ በራስ ሰር አሽከርክር"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲደርስበት ይፈቀድለት?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲደርስ ይፈቀድለት?\nይህ መተግበሪያ የመቅዳት ፈቃድ አልተሰጠውም፣ ነገር ግን በዩኤስቢ መሣሪያ በኩል ኦዲዮን መቅዳት ይችላል።"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲደርስበት ይፈቀድለት?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲይዘው <xliff:g id="APPLICATION">%1$s</xliff:g> ይክፈት?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ይህ መተግበሪያ የመቅረጽ ፈቃድ አልተሰጠውም፣ ነገር ግን በዚህ ዩኤስቢ መሣሪያ በኩል ኦዲዮን መቅረጽ ይችላል። <xliff:g id="APPLICATION">%1$s</xliff:g>ን ከዚህ መሣሪያ ጋር መጠቀም ጥሪዎችን፣ ማሳወቂያዎችን እና ማንቂያዎችን ከመስማት ሊከለክል ይችላል።"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g>ን ከዚህ መሣሪያ ጋር መጠቀም ጥሪዎችን፣ ማሳወቂያዎችን እና ማንቂያዎችን ከመስማት ሊከለክል ይችላል።"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ን እንዲደርስበት ይፈቀድለት?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲይዘው <xliff:g id="APPLICATION">%1$s</xliff:g> ይክፈት?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> ን <xliff:g id="USB_DEVICE">%2$s</xliff:g> ለማስተናገድ ይከፈት?\nይህ መተግበሪያ የቅጂ ፈቃድ አልተሰጠውም ሆኖም ግን በዩኤስቢ መሣሪያ በኩል ኦዲዮን መቅዳት ይችላል።"</string>
@@ -131,7 +135,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="1597899891472340950">"በፊትዎ የተከፈተ። ለመቀጠል ይጫኑ።"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"የተረጋገጠ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ፒን ይጠቀሙ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ሥርዓተ ጥለትን ተጠቀም"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ይህ የእርስዎን ማይክሮፎን እንዲጠቀሙ የተፈቀደላቸው የሁሉም መተግበሪያዎች እና አገልግሎቶች መዳረሻ እገዳን ያነሳል።"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ይህ ካሜራዎን እንዲጠቀሙ ለተፈቀደላቸው ሁሉም መተግበሪያዎች እና አገልግሎቶች መዳረሻን እገዳ ያነሳል።"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ይህ የእርስዎን ካሜራ ወይም ማይክሮፎን እንዲጠቀሙ የተፈቀደላቸው የሁሉም መተግበሪያዎች እና አገልግሎቶች መዳረሻ እገዳን ያነሳል።"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"ሌላ መሣሪያ"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"አጠቃላይ እይታን ቀያይር"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"እርስዎ ከወሰንዋቸው ማንቂያዎች፣ አስታዋሾች፣ ክስተቶች እና ደዋዮች በስተቀር፣ በድምጾች እና ንዝረቶች አይረበሹም። ሙዚቃ፣ ቪዲዮዎች እና ጨዋታዎች ጨምሮ ለመጫወት የሚመርጡትን ማንኛውም ነገር አሁንም ይሰማሉ።"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • የባትሪ ኃይል መሙያ መትከያ • በ<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ውስጥ ይሞላል"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"አስወግድ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"እንኳን በደህና ተመለሱ እንግዳ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ክፍለ-ጊዜዎን መቀጠል ይፈልጋሉ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"እንደገና ጀምር"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"አክል"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"በ<xliff:g id="APP">%s</xliff:g> የተጠቆመ"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"መሣሪያ ተቆልፏል"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ይህን ክፍለ ጊዜ cast ለማድረግ፣ እባክዎ መተግበሪያውን ይክፈቱ።"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"የማይታወቅ መተግበሪያ"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Cast ማድረግ አቁም"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
<string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ገቢር መተግበሪያዎች"</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_copy" msgid="770856373439969178">"ቅዳ"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ተቀድቷል"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"ከ<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ዩአይ ቅዳን አሰናብት"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index abc686a62a5e..63195118cdfb 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"التدوير التلقائي للشاشة"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"هل تريد السماح لتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"‏هل تريد السماح لتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟\nلم يتم منح هذا التطبيق إذن تسجيل، ولكن يمكنه تسجيل الصوت من خلال جهاز USB هذا."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"هل تريد السماح لتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالوصول إلى <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"هل تريد فتح تطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> لإدارة <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"‏لم يتم منح هذا التطبيق إذن تسجيل، ولكن يمكنه تسجيل الصوت من خلال جهاز USB هذا. قد يحول استخدام التطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> على هذا الجهاز دون سماع المكالمات والإشعارات والمنبّهات."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"قد يحول استخدام التطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> على هذا الجهاز دون سماع المكالمات والإشعارات والمنبّهات."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"هل تريد السماح لتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>؟"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"هل تريد فتح <xliff:g id="APPLICATION">%1$s</xliff:g> للتعامل مع <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"‏هل تريد فتح تطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> للتعامل مع <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟\nلم يتم منح هذا التطبيق إذن تسجيل، ولكن يمكنه تسجيل الصوت من خلال جهاز USB هذا."</string>
@@ -131,7 +135,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="1597899891472340950">"تم فتح قفل الجهاز بالتعرف على وجهك. اضغط للمتابعة."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"مصادقة"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"استخدام رقم تعريف شخصي"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"استخدام نقش"</string>
@@ -295,6 +300,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"يؤدي هذا الخيار إلى إزالة حظر الوصول بالنسبة إلى كل التطبيقات والخدمات المسموح لها باستخدام الميكروفون."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"يؤدي هذا الخيار إلى إزالة حظر الوصول بالنسبة إلى كل التطبيقات والخدمات المسموح لها باستخدام الكاميرا."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"يؤدي هذا الخيار إلى إزالة حظر الوصول بالنسبة إلى كل التطبيقات والخدمات المسموح لها باستخدام الكاميرا أو الميكروفون."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"جهاز آخر"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"تبديل \"النظرة العامة\""</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"لن يتم إزعاجك بالأصوات والاهتزاز، باستثناء المُنبِّهات والتذكيرات والأحداث والمتصلين الذين تحددهم. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى والفيديوهات والألعاب."</string>
@@ -328,7 +351,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • جارٍ الشحن على وحدة الإرساء • ستمتلئ البطارية خلال <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تبديل المستخدم"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"إزالة"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"مرحبًا بك مجددًا في جلسة الضيف"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"هل تريد متابعة جلستك؟"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string>
@@ -790,6 +812,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"إضافة"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"اقتراح من <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"الجهاز مُقفل."</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -799,8 +833,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مرّر سريعًا لرؤية المزيد."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"جارٍ تحميل الاقتراحات"</string>
<string name="controls_media_title" msgid="1746947284862928133">"الوسائط"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"هل تريد إخفاء عنصر التحكم في الوسائط هذا للتطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"لا يمكن إخفاء جلسة الوسائط الحالية."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"إخفاء"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"استئناف التشغيل"</string>
@@ -840,6 +873,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"لبث هذه الجلسة، يُرجى فتح التطبيق"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"تطبيق غير معروف"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"إيقاف البث"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
<string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
@@ -920,7 +967,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"التطبيقات النشطة"</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_copy" msgid="770856373439969178">"نسخ"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"تم النسخ."</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"من <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"إغلاق واجهة مستخدم النسخ"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index e3cb119c0579..0b5892e74a92 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ত প্ৰৱেশ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক অনুমতি দিবনে?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>ক <xliff:g id="USB_DEVICE">%2$s</xliff:g> এক্সেছ কৰিবলৈ অনুমতি দিবনে?\nএই এপ্‌টোক ৰেকর্ড কৰাৰ অনুমতি দিয়া হোৱা নাই কিন্তু ই এই ইউএছবি ডিভাইচটোৰ জৰিয়তে অডিঅ\' ৰেকর্ড কৰিব পাৰে।"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g>ক <xliff:g id="USB_DEVICE">%2$s</xliff:g>ত প্ৰৱেশ কৰিবলৈ অনুমতি দিবনে?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ক ব্যৱহাৰ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক খুলিবনে?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"এই এপ্‌টোক ৰেকর্ড কৰাৰ অনুমতি দিয়া হোৱা নাই কিন্তু ই এই ইউএছবি ডিভাইচটোৰ জৰিয়তে অডিঅ\' ৰেকর্ড কৰিব পাৰে। এইটো ডিভাইচৰ সৈতে <xliff:g id="APPLICATION">%1$s</xliff:g> ব্যৱহাৰ কৰিলে কল, জাননী আৰু এলাৰ্ম শুনাটো অৱৰুদ্ধ হ’ব পাৰে।"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"এইটো ডিভাইচৰ সৈতে <xliff:g id="APPLICATION">%1$s</xliff:g> ব্যৱহাৰ কৰিলে কল, জাননী আৰু এলাৰ্ম শুনাটো অৱৰুদ্ধ হ’ব পাৰে।"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g>ক <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ত প্ৰৱেশ কৰিবলৈ অনুমতি দিবনে?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ক ব্যৱহাৰ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক খোলেনে?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ব্যৱহাৰ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক খুলিবনে?\nএই এপ্‌টোক ৰেকর্ড কৰাৰ অনুমতি দিয়া হোৱা নাই কিন্তু ই এই ইউএছবি ডিভাইচটোৰ জৰিয়তে অডিঅ\' ৰেকর্ড কৰিব পাৰে।"</string>
@@ -131,7 +135,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="1597899891472340950">"আপোনাৰ মুখাৱয়বৰ দ্বাৰা আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ দবাওক।"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যৱহাৰ কৰক"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"আৰ্হি ব্যৱহাৰ কৰক"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"এইটোৱে আপোনাৰ মাইক্ৰ\'ফ\'ন ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়া আটাইবোৰ এপ্ আৰু সেৱাৰ বাবে এক্সেছ অৱৰোধৰ পৰা আঁতৰায়।"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"এইটোৱে আপোনাৰ কেমেৰা ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়া আটাইবোৰ এপ্ আৰু সেৱাৰ বাবে এক্সেছ অৱৰোধৰ পৰা আঁতৰায়।"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"এইটোৱে আপোনাৰ কেমেৰা অথবা মাইক্ৰ\'ফ\'ন ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়া আটাইবোৰ এপ্ আৰু সেৱাৰ বাবে এক্সেছ অৱৰোধৰ পৰা আঁতৰায়।"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"অন্য ডিভাইচ"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"অৱলোকন ট’গল কৰক"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"আপুনি নিৰ্দিষ্ট কৰা এলাৰ্ম, ৰিমাইণ্ডাৰ, ইভেন্ট আৰু কল কৰোঁতাৰ বাহিৰে আন কোনো শব্দৰ পৰা আপুনি অসুবিধা নাপাব। কিন্তু, সংগীত, ভিডিঅ\' আৰু খেলসমূহকে ধৰি আপুনি প্লে কৰিব খোজা যিকোনো বস্তু তথাপি শুনিব পাৰিব।"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • চাৰ্জিং ডক • সম্পূৰ্ণ হ’বলৈ <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> লাগিব"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"আঁতৰাওক"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপোনাক পুনৰ স্বাগতম!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"আপুনি আপোনাৰ ছেশ্বন অব্যাহত ৰাখিব বিচাৰেনে?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আকৌ আৰম্ভ কৰক"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"যোগ দিয়ক"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g>এ পৰামৰ্শ হিচাপে আগবঢ়োৱা"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"ডিভাইচ লক হৈ আছে"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"লক স্ক্ৰীনৰ পৰা ডিভাইচসমূহ লক আৰু নিয়ন্ত্ৰণ কৰিবনে?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"আপুনি লক স্ক্ৰীনত আপোনাৰ বাহ্যিক ডিভাইচৰ বাবে নিয়ন্ত্ৰণ যোগ দিব পাৰে।\n\nআপোনাৰ ডিভাইচ এপে আপোনাক আপোনাৰ ফ’ন অথবা টেবলেট আনলক নকৰাকৈ কিছুমান ডিভাইচ নিয়ন্ত্ৰণ কৰাৰ অনুমতি দিব পাৰে। \n\nআপুনি যিকোনো সময়তে ছেটিঙত সালসলনি কৰিব পাৰে।"</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"লক স্ক্ৰীনৰ পৰা ডিভাইচসমূহ নিয়ন্ত্ৰণ কৰিবনে?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"আপুনি আপোনাৰ ফ’ন অথবা টেবলেট আনলক নকৰাকৈ কিছুমান ডিভাইচ নিয়ন্ত্ৰণ কৰিব পাৰে।\n\nএইধৰণে কোনবোৰ ডিভাইচ নিয়ন্ত্ৰণ কৰিব পাৰি সেয়া আপোনাৰ ডিভাইচ এপে নিৰ্ধাৰণ কৰে।"</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"নালাগে, ধন্যবাদ"</string>
+ <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>
@@ -815,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই ছেশ্বনটো কাষ্ট কৰিবলৈ, অনুগ্ৰহ কৰি এপ্‌টো খোলক"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজ্ঞাত এপ্"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাষ্ট বন্ধ কৰক"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
<string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string>
@@ -891,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"সক্ৰিয় এপ্‌"</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_copy" msgid="770856373439969178">"প্ৰতিলিপি কৰক"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"হ’ল"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"প্ৰতিলিপি কৰা হ’ল"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>ৰ পৰা"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"প্ৰতিলিপি কৰা UI অগ্ৰাহ্য কৰক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 81fb71aa38fe..bd65b2140371 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ekranın avtomatik dönməsi"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş icazəsi verilsin?\nBu tətbiqə qeydə almaq icazəsi verilməyib lakin, bu USB vasitəsilə səs yaza bilər."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Bu tətbiqə yazmaq icazəsi verilməyib, lakin, bu USB vasitəsilə səs yaza bilər. <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqindən bu cihazla istifadə etsəniz zənglər, bildirişlər və siqnallar eşidilməyə bilər."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqindən bu cihazla istifadə etsəniz zənglər, bildirişlər və siqnallar eşidilməyə bilər."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?\nBu tətbiqə yazmaq icazəsi verilməyib, lakin, bu USB vasitəsilə səs yaza bilər."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Üzünüzlə kiliddən çıxarılıb. Davam etmək üçün basın."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Doğrulandı"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN istifadə edin"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Model istifadə edin"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Kamera və mikrofon istifadə edən bütün tətbiq və xidmətlərə giriş verir."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Kamera və mikrofon istifadə edən bütün tətbiq və xidmətlərə giriş verir."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Kamera və mikrofon istifadə edən bütün tətbiq və xidmətlərə giriş verir."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Digər cihaz"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"İcmala Keçin"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Seçdiyiniz siqnal, xatırladıcı, tədbir və zənglər istisna olmaqla səslər və vibrasiyalar Sizi narahat etməyəcək. Musiqi, video və oyunlar da daxil olmaqla oxutmaq istədiyiniz hər şeyi eşidəcəksiniz."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Şarj Doku • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> sonra dolacaq"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Yığışdır"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Xoş gəlmisiniz!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Sessiya davam etsin?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Yenidən başlayın"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Əlavə edin"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> tərəfindən təklif edilib"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Cihaz kilidlənib"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN hərflər və ya simvollar ehtiva edir"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> cihazını doğrulayın"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Yanlış PIN"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu sessiyanı yayımlamaq üçün tətbiqi açın."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Naməlum tətbiq"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayımı dayandırın"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
<string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiv tətbiqlər"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Dayandırın"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dayandırılıb"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopyalayın"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopyalandı"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Mənbə: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI kopyalanmasını qapadın"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index befc982559bc..f65f6da5746f 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatsko rotiranje ekrana"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOva aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili uređaj <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ova aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja. Ako koristite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> sa ovim uređajem, možda nećete čuti pozive, obaveštenja i alarme."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ako koristite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> sa ovim uređajem, možda nećete čuti pozive, obaveštenja i alarme."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili uređaj <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> radi rukovanja uređajem <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOva aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Otključali ste licem. Pritisnite da biste nastavili."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite šablon"</string>
@@ -289,6 +294,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje mikrofona."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje kamere."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje kamere ili mikrofona."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Drugi uređaj"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Uključi/isključi pregled"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Neće vas uznemiravati zvukovi i vibracije osim za alarme, podsetnike, događaje i pozivaoce koje navedete. I dalje ćete čuti sve što odaberete da pustite, uključujući muziku, video snimke i igre."</string>
@@ -322,7 +345,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Bazna stanica za punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli nazad, goste!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string>
@@ -772,6 +794,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Predlaže <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifikujte: <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Pogrešan PIN"</string>
@@ -781,8 +815,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da biste videli još"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavaju se preporuke"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li da sakrijete ovu kontrolu za medije za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Aktuelna sesija medija ne može da bude sakrivena."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
@@ -822,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste prebacivali ovu sesiju, otvorite aplikaciju."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi prebacivanje"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
@@ -899,7 +946,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiraj"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano je"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Iz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Odbaci kopiranje korisničkog interfejsa"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index bbbbdeedd17c..f7c2580d80d3 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аўтаматычны паварот экрана"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Дазволіць праграме <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Даць праграме \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ да прылады \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?\nУ гэтай праграмы няма дазволу на запіс, аднак яна зможа запісваць аўдыя праз гэту прыладу USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Дазволіць праграме \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ да прылады \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Адкрыць праграму \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" для працы з прыладай \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"У гэтай праграмы няма дазволу на запіс, аднак яна зможа запісваць аўдыя праз гэту USB-прыладу. Выкарыстоўваючы праграму \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" з гэтай прыладай, вы можаце не пачуць гукі выклікаў, апавяшчэнняў і будзільнікаў."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Выкарыстоўваючы праграму \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" з гэтай прыладай, вы можаце не пачуць гукі выклікаў, апавяшчэнняў і будзільнікаў."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Дазволіць праграме <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Адкрыць праграму <xliff:g id="APPLICATION">%1$s</xliff:g> для працы з прыладай <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Адкрыць праграму \"<xliff:g id="APPLICATION">%1$s</xliff:g>\", каб выкарыстоўваць прыладу \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?\nУ гэтай праграмы няма дазволу на запіс, аднак яна зможа запісваць аўдыя праз гэту USB-прыладу."</string>
@@ -131,7 +135,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="1597899891472340950">"Разблакіравана распазнаваннем твару. Націсніце для працягу."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Распазнана"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Увесці PIN-код"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Выкарыстаць узор разблакіроўкі"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Доступ адкрыецца для ўсіх праграм і сэрвісаў, якім дазволена выкарыстоўваць мікрафон."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Доступ адкрыецца для ўсіх праграм і сэрвісаў, якім дазволена выкарыстоўваць камеру."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Доступ адкрыецца для ўсіх праграм і сэрвісаў, якім дазволена выкарыстоўваць камеру ці мікрафон."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Іншая прылада"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Уключыць/выключыць агляд"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Вас не будуць турбаваць гукі і вібрацыя, за выключэннем будзільнікаў, напамінаў, падзей і выбраных вамі абанентаў. Вы будзеце чуць усё, што ўключыце, у тым ліку музыку, відэа і гульні."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ідзе зарадка праз док-станцыю • Поўнасцю зарадзіцца праз <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Выдаліць"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"З вяртаннем, госць!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Хочаце працягнуць сеанс?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Пачаць зноў"</string>
@@ -778,6 +800,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Дадаць"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Прапанавана праграмай \"<xliff:g id="APP">%s</xliff:g>\""</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Прылада блакіравана"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код складаецца з літар або знакаў"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Спраўдзіце прыладу \"<xliff:g id="DEVICE">%s</xliff:g>\""</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Няправільны PIN-код"</string>
@@ -787,8 +821,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Правядзіце пальцам, каб убачыць больш інфармацыі"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загружаюцца рэкамендацыі"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мультымедыя"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Схаваць гэту панэль мультымедыя для праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Не ўдалося схаваць бягучы сеанс мультымедыя."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Схаваць"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Узнавіць"</string>
@@ -828,6 +861,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Для трансляцыі гэтага сеанса адкрыйце праграму."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невядомая праграма"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спыніць трансляцыю"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
<string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string>
@@ -906,7 +953,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Актыўныя праграмы"</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_copy" msgid="770856373439969178">"Капіраваць"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скапіравана"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"З праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрыць інтэрфейс капіравання"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 73a239169b76..9e9350d4f3e3 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Авт. завъртане на екрана"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Да се разреши ли на <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Наистина ли искате да разрешите на <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nНа приложението не е предоставено разрешение за записване, но е възможно да запише звук чрез това USB устройство."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Да се разреши ли на <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Да се използва ли <xliff:g id="APPLICATION">%1$s</xliff:g> за работата с(ъс) <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Приложението няма разрешение за записване, но може да записва звук чрез това USB устройство. Ако използвате <xliff:g id="APPLICATION">%1$s</xliff:g> с това устройство, е възможно да не чувате обажданията, известията и будилниците."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ако използвате <xliff:g id="APPLICATION">%1$s</xliff:g> с това устройство, е възможно да не чувате обажданията, известията и будилниците."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Да се разреши ли на <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Да се използва ли <xliff:g id="APPLICATION">%1$s</xliff:g> за работата с/ъс <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Искате ли да използвате <xliff:g id="APPLICATION">%1$s</xliff:g> за работа с(ъс) <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nПриложението няма разрешение за записване, но може да записва звук чрез това USB устройство."</string>
@@ -131,7 +135,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="1597899891472340950">"Отключено чрез лицето ви. Натиснете, за да продължите."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Удостоверено"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Използване на ПИН"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Използване на фигура"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Това действие отблокира достъпа за всички приложения и услуги, които имат разрешение да използват микрофона ви."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Това действие отблокира достъпа за всички приложения и услуги, които имат разрешение да използват камерата ви."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Това действие отблокира достъпа за всички приложения и услуги, които имат разрешение да използват камерата или микрофона ви."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Друго устройство"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Превключване на общия преглед"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Няма да бъдете обезпокоявани от звуци и вибрирания освен от будилници, напомняния, събития и обаждания от посочени от вас контакти. Пак ще чувате всичко, което изберете да се пусне, включително музика, видеоклипове и игри."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Докинг станция за зареждане • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до пълно зареждане"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Превключване между потребителите"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Премахване"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Добре дошли отново в сесията като гост!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Искате ли да продължите сесията си?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Започване отначало"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Добавяне"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Предложено от <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"У-вото е заключено"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Прекарайте пръст, за да видите повече"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Препоръките се зареждат"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мултимедия"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Да се скрие ли за <xliff:g id="APP_NAME">%1$s</xliff:g> тази контрола за мултимедията?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Текущата сесия за мултимедия не бе скрита."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриване"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да предавате тази сесия, моля, отворете приложението."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестно приложение"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спиране на предаването"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
<string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни приложения"</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_copy" msgid="770856373439969178">"Копиране"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"От <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Отхвърляне на ПИ за копиране"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index a967a5c3399b..7b8a75e678fa 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"অটো-রোটেট স্ক্রিন"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> কে <xliff:g id="USB_DEVICE">%2$s</xliff:g> অ্যাক্সেস করতে দেবেন?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> অ্যাক্সেস করতে <xliff:g id="APPLICATION">%1$s</xliff:g>-কে কি অনুমতি দেবেন?\nএই অ্যাপকে রেকর্ড করার অনুমতি দেওয়া হয়নি কিন্তু USB ডিভাইসের মাধ্যমে সেটি অডিও রেকর্ড করতে পারে।"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> অ্যাক্সেস করতে <xliff:g id="APPLICATION">%1$s</xliff:g> অ্যাপকে অনুমতি দিতে চান?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ব্যবহার করার জন্য <xliff:g id="APPLICATION">%1$s</xliff:g> চালু করতে চান?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"এই অ্যাপকে রেকর্ড করার অনুমতি দেওয়া হয়নি কিন্তু USB ডিভাইসের সাহায্যে সেটি অডিও রেকর্ড করতে পারে। <xliff:g id="APPLICATION">%1$s</xliff:g> অ্যাপের ব্যবহার এই ডিভাইসের সাথে করার ফলে হতে পারে কল, বিজ্ঞপ্তি এবং অ্যালার্মের আওয়াজ শোনা যাবে না।"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> অ্যাপের ব্যবহার এই ডিভাইসের সাথে করার ফলে হতে পারে কল, বিজ্ঞপ্তি এবং অ্যালার্মের আওয়াজ শোনা যাবে না।"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> কে <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> অ্যাক্সেস করতে দেবেন?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ব্যবহার করার জন্য <xliff:g id="APPLICATION">%1$s</xliff:g> চালু করবেন?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> অ্যাক্সেস করার জন্য <xliff:g id="APPLICATION">%1$s</xliff:g> খুলবেন?\nএই অ্যাপকে রেকর্ড করার অনুমতি দেওয়া হয়নি কিন্তু USB ডিভাইসের মাধ্যমে সেটি অডিও রেকর্ড করতে পারে।"</string>
@@ -131,7 +135,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="1597899891472340950">"আপনার মুখ মাধ্যমে আনলক করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"প্রমাণীকৃত"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যবহার করুন"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"প্যাটার্ন ব্যবহার করুন"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"এটার জন্য মাইক্রোফোনের অ্যাক্সেস সেই সব অ্যাপ এবং পরিষেবার জন্য আনব্লক হয়ে যাবে, যাতে আপনার মাইক্রোফোন ব্যবহার করার অনুমতি দেওয়া হয়েছে।"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"এটার জন্য ক্যামেরার অ্যাক্সেস সেই সব অ্যাপ এবং পরিষেবার জন্য আনব্লক হয়ে যাবে, যাতে আপনার ক্যামেরা ব্যবহারের অনুমতি দেওয়া হয়েছে।"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"এটার জন্য ক্যামেরা অথবা মাইক্রোফোনের অ্যাক্সেস সেই সব অ্যাপ এবং পরিষেবার জন্য আনব্লক হয়ে যাবে, যাতে আপনার ক্যামেরা অথবা মাইক্রোফোন ব্যবহারের অনুমতি দেওয়া হয়েছে।"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"অন্য ডিভাইস"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"\'এক নজরে\' বৈশিষ্ট্যটি চালু বা বন্ধ করুন"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"অ্যালার্ম, রিমাইন্ডার, ইভেন্ট, এবং আপনার নির্দিষ্ট করে দেওয়া ব্যক্তিদের কল ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেম সহ আপনি যা কিছু চালাবেন তার আওয়াজ শুনতে পাবেন।"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • চার্জিং ডক • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-এর মধ্যে সম্পূর্ণ হয়ে যাবে"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যবহারকারী পাল্টে দিন"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"সরান"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপনি ফিরে আসায় আপনাকে স্বাগত!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি চালিয়ে যেতে চান?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আবার শুরু করুন"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"যোগ করুন"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> সাজেস্ট করেছে"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"ডিভাইস লক করা আছে"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"আরও দেখতে সোয়াইপ করুন"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"সাজেশন লোড করা হচ্ছে"</string>
<string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর মিডিয়া কন্ট্রোল লুকিয়ে রাখতে চান?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"বর্তমান মিডিয়া সেশন লুকিয়ে রাখা যাবে না।"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকান"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই সেশন কাস্ট করার জন্য, অ্যাপ খুলুন।"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজানা অ্যাপ"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাস্ট করা বন্ধ করুন"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
<string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"অ্যাক্টিভ অ্যাপ"</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_copy" msgid="770856373439969178">"কপি করুন"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"কপি করা হয়েছে"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> থেকে"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"কপি করা UI বাতিল করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index c84ffc37c740..bc9a97de4e5a 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatsko rotiranje ekrana"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOvoj aplikaciji nije dato odobrenje za snimanje, ali može snimati zvuk putem ovog USB uređaja."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup dodatku: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Otvoriti aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje dodatkom: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ovoj aplikaciji nije dato odobrenje za snimanje, ali može snimati zvuk putem ovog USB uređaja. Korištenje aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g> s ovim uređajem može vas spriječiti da čujete pozive, obavještenja i alarme."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Korištenje aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g> s ovim uređajem može vas spriječiti da čujete pozive, obavještenja i alarme."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup dodatku: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Otvoriti aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje uređajem: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Želite li upravljati uređajem <xliff:g id="USB_DEVICE">%2$s</xliff:g> putem aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g>?\nOvoj aplikaciji nije dato odobrenje za snimanje, ali može snimati zvuk putem ovog USB uređaja."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Otključano vašim licem. Pritisnite da nastavite."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificirano"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristi PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristi uzorak"</string>
@@ -289,6 +294,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ovim se deblokira pristup za sve aplikacije i usluge kojima je dozvoljeno da koriste vaš mikrofon."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ovim se deblokira pristup za sve aplikacije i usluge kojima je dozvoljeno da koriste vašu kameru."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ovim se deblokira pristup za sve aplikacije i usluge kojima je dozvoljeno da koriste vašu kameru ili mikrofon."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Drugi uređaj"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Pregled uključivanja/isključivanja"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Neće vas ometati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivalaca koje odredite. I dalje ćete čuti sve što ste odabrali za reprodukciju, uključujući muziku, videozapise i igre."</string>
@@ -322,7 +345,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Priključna stanica za punjenje • Potpuna napunjenost za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Zdravo! Lijepo je opet vidjeti goste."</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
@@ -772,6 +794,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Predlaže <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Potvrdite uređaj <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Pogrešan PIN"</string>
@@ -781,7 +815,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da vidite više"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
- <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li sakriti kontroler medija za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Sakriti kontrolu medijskog sadržaja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Trenutna sesija medija se ne može sakriti."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
@@ -821,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da emitirate ovu sesiju, otvorite aplikaciju."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi emitiranje"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -898,7 +946,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiraj"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Iz aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Odbaci kopirani korisnički interfejs"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index c8c8816efb5e..6efb930bdd34 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Gira la pantalla automàticament"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAquesta aplicació no té permís de gravació, però pot capturar àudio a través d\'aquest dispositiu USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Vols obrir <xliff:g id="APPLICATION">%1$s</xliff:g> per gestionar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Aquesta aplicació no té permís de gravació, però pot capturar àudio a través d\'aquest dispositiu USB. Si utilitzes <xliff:g id="APPLICATION">%1$s</xliff:g> amb aquest dispositiu, és possible que no s\'escoltin les trucades, les notificacions ni les alarmes."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Si utilitzes <xliff:g id="APPLICATION">%1$s</xliff:g> amb aquest dispositiu, és possible que no s\'escoltin les trucades, les notificacions ni les alarmes."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Vols obrir <xliff:g id="APPLICATION">%1$s</xliff:g> per gestionar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAquesta aplicació no té permís de gravació, però pot capturar àudio a través d\'aquest dispositiu USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"S\'ha desbloquejat amb la cara. Prem per continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticat"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilitza el PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilitza el patró"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Aquesta opció desbloqueja l\'accés de tots els serveis i aplicacions que tenen permís per utilitzar el micròfon."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Aquesta opció desbloqueja l\'accés de tots els serveis i aplicacions que tenen permís per utilitzar la càmera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Aquesta opció desbloqueja l\'accés de tots els serveis i aplicacions que tenen permís per utilitzar la càmera o el micròfon."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Un altre dispositiu"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activa o desactiva Aplicacions recents"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Base de càrrega • Es completarà d\'aquí a <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Suprimeix"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvingut de nou, convidat."</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vols continuar amb la sessió?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Torna a començar"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Afegeix"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggerit per <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Dispositiu bloquejat"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN conté lletres o símbols"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifica <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorrecte"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Llisca per veure\'n més"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregant les recomanacions"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimèdia"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Vols amagar aquest control multimèdia per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"La sessió multimèdia actual no es pot amagar."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Amaga"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per emetre aquesta sessió, obre l\'aplicació."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicació desconeguda"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Atura l\'emissió"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacions actives"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Atura"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Aturada"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copia"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"S\'ha copiat"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"De: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignora la IU de còpia"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index db8939298c67..35be86a2b64e 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatické otočení obrazovky"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTato aplikace nemá oprávnění k nahrávání, ale může zaznamenávat zvuk prostřednictvím tohoto zařízení USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Otevřít aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> ke správě zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Tato aplikace nemá oprávnění k nahrávání, ale může zaznamenávat zvuk prostřednictvím tohoto zařízení USB. Při používání aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> s tímto zařízením nemusíte slyšet volání, oznámení a budíky."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Při používání aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> s tímto zařízením nemusíte slyšet volání, oznámení a budíky."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Otevřít aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> ke správě zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Otevřít aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> ke správě zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTato aplikace nemá oprávnění k nahrávání, ale může zaznamenávat zvuk prostřednictvím tohoto zařízení USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Odemyká se obličejem. Pokračujte stisknutím."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ověřeno"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použít kód PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použít gesto"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Tímto odblokujete přístup všem aplikacím a službám, které mají povoleno používat váš mikrofon."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Tímto odblokujete přístup všem aplikacím a službám, které mají povoleno používat váš fotoaparát."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Tímto odblokujete přístup všem aplikacím a službám, které mají povoleno používat váš fotoaparát či mikrofon."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Další zařízení"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Přepnout přehled"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Nebudou vás rušit zvuky ani vibrace s výjimkou budíků, upozornění, událostí a volajících, které zadáte. Nadále uslyšíte veškerý obsah, který si sami pustíte (např. hudba, videa nebo hry)."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíjecí dok • Plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Přepnout uživatele"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstranit"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Vítejte zpět v relaci hosta!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relaci pokračovat?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začít znovu"</string>
@@ -778,6 +800,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Přidat"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Návrh z aplikace <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Zařízení uzamčeno"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Zobrazovat a ovládat zařízení z obrazovky uzamčení?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na obrazovku uzamčení můžete přidat ovládací prvky pro svá externí zařízení.\n\nAplikace zařízení vám může umožnit ovládat některá zařízení bez odemykání telefonu nebo tabletu.\n\nZměny můžete kdykoli provést v Nastavení."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Ovládat zařízení z obrazovky uzamčení?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Některá zařízení můžete ovládat bez odemykání telefonu nebo tabletu.\n\nAplikace zařízení určuje, která zařízení lze tímto způsobem ovládat."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, díky"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ano"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kód PIN obsahuje písmena nebo symboly"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Ověření zařízení <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Chybný PIN"</string>
@@ -787,8 +815,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Přejetím prstem zobrazíte další položky"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítání doporučení"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Média"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Skrýt toto ovládání médií aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Aktuální mediální relaci nelze skrýt."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrýt"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovat"</string>
@@ -828,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pokud chcete odesílat relaci, otevřete aplikaci."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznámá aplikace"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastavit odesílání"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
<string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string>
@@ -906,7 +947,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivní aplikace"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Konec"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zastaveno"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopírovat"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Hotovo"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Zkopírováno"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Z aplikace <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Zavřít uživatelské rozhraní kopírování"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index c82e3bddba86..cd3998d1d23a 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Roter skærm automatisk"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vil du give <xliff:g id="APPLICATION">%1$s</xliff:g> adgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vil du give <xliff:g id="APPLICATION">%1$s</xliff:g> adgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDenne app har ikke fået tilladelse til at optage, men optager muligvis lyd via denne USB-enhed."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Vil du give <xliff:g id="APPLICATION">%1$s</xliff:g> adgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Vil du åbne <xliff:g id="APPLICATION">%1$s</xliff:g> til håndtering af <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Denne app har ikke fået tilladelse til at optage, men optager muligvis lyd via denne USB-enhed. Hvis du bruger <xliff:g id="APPLICATION">%1$s</xliff:g> med denne enhed, kan du muligvis ikke høre opkald, notifikationer og alarmer."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Hvis du bruger <xliff:g id="APPLICATION">%1$s</xliff:g> med denne enhed, kan du muligvis ikke høre opkald, notifikationer og alarmer."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Vil du give <xliff:g id="APPLICATION">%1$s</xliff:g> adgang til <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Vil du åbne <xliff:g id="APPLICATION">%1$s</xliff:g> til håndtering af <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Vil du åbne <xliff:g id="APPLICATION">%1$s</xliff:g> for at håndtere <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDenne app har ikke fået tilladelse til at optage, men optager muligvis lyd via denne USB-enhed."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Låst op med ansigtsgenkendelse. Tryk for at fortsætte."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Godkendt"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Brug pinkode"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Brug mønster"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Dette fjerner adgangsblokeringen for alle apps og tjenester, der har tilladelse til at bruge din mikrofon."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Dette fjerner adgangsblokeringen for alle apps og tjenester, der har tilladelse til at bruge dit kamera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Dette fjerner adgangsblokeringen for alle apps og tjenester, der har tilladelse til at bruge dit kamera eller din mikrofon."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Anden enhed"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Slå Oversigt til/fra"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Du bliver ikke forstyrret af lyde eller vibrationer, undtagen fra alarmer, påmindelser, begivenheder og opkald fra udvalgte personer, du selv angiver. Du kan stadig høre alt, du vælger at afspille, f.eks. musik, videoer og spil."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oplader i dockingstation • Fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skift bruger"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbage, gæst!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsætte din session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start forfra"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Tilføj"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Foreslået af <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Enheden er låst"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pinkoden indeholder bogstaver eller symboler"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Bekræft <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Forkert pinkode"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Åbn appen for at caste denne session."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukendt app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop med at caste"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
<string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stoppet"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiér"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopieret"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Fra <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Luk brugerfladen for kopi"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 761490413b76..08262c346ed1 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Bildschirm automatisch drehen"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> den Zugriff auf <xliff:g id="USB_DEVICE">%2$s</xliff:g> gewähren?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> den Zugriff auf <xliff:g id="USB_DEVICE">%2$s</xliff:g> gewähren?\nDiese App hat noch nicht die Berechtigung zum Aufnehmen erhalten, könnte jedoch Audio über dieses USB-Gerät aufnehmen."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> den Zugriff auf <xliff:g id="USB_DEVICE">%2$s</xliff:g> gewähren?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> für <xliff:g id="USB_DEVICE">%2$s</xliff:g> öffnen?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Diese App hat noch keine Berechtigung zum Aufnehmen erhalten, könnte aber Audioaufnahmen über dieses USB-Gerät machen. Wenn du <xliff:g id="APPLICATION">%1$s</xliff:g> mit diesem Gerät verwendest, hörst du möglicherweise keine Anrufe, Benachrichtigungen und Wecker mehr."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Wenn du <xliff:g id="APPLICATION">%1$s</xliff:g> mit diesem Gerät verwendest, hörst du möglicherweise keine Anrufe, Benachrichtigungen und Wecker mehr."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> den Zugriff auf <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> gewähren?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Für <xliff:g id="USB_DEVICE">%2$s</xliff:g> <xliff:g id="APPLICATION">%1$s</xliff:g> öffnen?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> öffnen, um <xliff:g id="USB_DEVICE">%2$s</xliff:g> zu bedienen?\nDiese App hat noch keine Berechtigung zum Aufnehmen erhalten, könnte aber Audioaufnahmen über dieses USB-Gerät machen."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Mit dem Gesicht entsperrt. Drücken, um fortzufahren."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifiziert"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN verwenden"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Muster verwenden"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Dadurch wird die Blockierung des Zugriffs für alle Apps und Dienste aufgehoben, die dein Mikrofon verwenden dürfen."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Dadurch wird die Blockierung des Zugriffs für alle Apps und Dienste aufgehoben, die deine Kamera verwenden dürfen."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Dadurch wird die Blockierung des Zugriffs für alle Apps und Dienste aufgehoben, die deine Kamera oder dein Mikrofon verwenden dürfen."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Sonstiges Gerät"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Übersicht ein-/ausblenden"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen. Du hörst jedoch weiterhin Sound, wenn du dir Musik anhörst, Videos ansiehst oder Spiele spielst."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ladestation • Voll in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Entfernen"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Willkommen zurück im Gastmodus"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Möchtest du deine Sitzung fortsetzen?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Neu starten"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Hinzufügen"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Vorgeschlagen von <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Gerät gesperrt"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Die PIN enthält Buchstaben oder Symbole"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> bestätigen"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Falsche PIN"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Wischen, um weitere zu sehen"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Empfehlungen werden geladen"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medien"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Dieses Mediensteuerelement für <xliff:g id="APP_NAME">%1$s</xliff:g> ausblenden?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Die Mediensitzung kann nicht ausgeblendet werden."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ausblenden"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öffne zum Streamen dieser Sitzung die App."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unbekannte App"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Streaming beenden"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
<string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive Apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Beenden"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Beendet"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopieren"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiert"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Von <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopieren-Benutzeroberfläche schließen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index bbc2ee357ec2..89f4c7546fed 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Αυτόματη περιστροφή οθόνης"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Να επιτρέπεται η πρόσβαση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> να έχει πρόσβαση στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;\nΔεν έχει εκχωρηθεί άδεια εγγραφής σε αυτήν την εφαρμογή, αλλά μέσω αυτής της συσκευής USB θα μπορεί να εγγράφει ήχο."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Άνοιγμα της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> για τη διαχείριση της συσκευής <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Δεν έχει εκχωρηθεί άδεια εγγραφής σε αυτήν την εφαρμογή, αλλά μέσω αυτής της συσκευής USB θα μπορεί να εγγράφει ήχο. Η χρήση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> με αυτήν τη συσκευή μπορεί να σας εμποδίσει να ακούσετε κλήσεις, ειδοποιήσεις και ξυπνητήρια."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Η χρήση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> με αυτήν τη συσκευή μπορεί να σας εμποδίσει να ακούσετε κλήσεις, ειδοποιήσεις και ξυπνητήρια."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Να επιτρέπεται η πρόσβαση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> στο αξεσουάρ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>;"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Να ανοίγει η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> για τη διαχείριση της συσκευής <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Άνοιγμα της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> για τον χειρισμό της συσκευής <xliff:g id="USB_DEVICE">%2$s</xliff:g>;\nΔεν έχει εκχωρηθεί άδεια εγγραφής σε αυτήν την εφαρμογή, αλλά μέσω αυτής της συσκευής USB θα μπορεί να εγγράφει ήχο."</string>
@@ -131,7 +135,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="1597899891472340950">"Ξεκλειδώθηκε με το πρόσωπό σας. Πατήστε για συνέχεια."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ολοκληρώθηκε ο έλεγχος ταυτότητας"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Χρήση PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Χρήση μοτίβου"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Με αυτόν τον τρόπο καταργείται ο αποκλεισμός της πρόσβασης για όλες τις εφαρμογές και υπηρεσίες που επιτρέπεται να χρησιμοποιούν το μικρόφωνό σας."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Με αυτόν τον τρόπο καταργείται ο αποκλεισμός της πρόσβασης για όλες τις εφαρμογές και υπηρεσίες που επιτρέπεται να χρησιμοποιούν την κάμερά σας."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Με αυτόν τον τρόπο καταργείται ο αποκλεισμός της πρόσβασης για όλες τις εφαρμογές και υπηρεσίες που επιτρέπεται να χρησιμοποιούν την κάμερα ή το μικρόφωνό σας."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Άλλη συσκευή"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Εναλλαγή επισκόπησης"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Δεν θα ενοχλείστε από ήχους και δονήσεις, παρά μόνο από ξυπνητήρια, υπενθυμίσεις, συμβάντα και καλούντες που έχετε καθορίσει. Θα εξακολουθείτε να ακούτε όλο το περιεχόμενο που επιλέγετε να αναπαραγάγετε, συμπεριλαμβανομένης της μουσικής, των βίντεο και των παιχνιδιών."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Βάση φόρτισης • Πλήρης φόρτιση σε <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Εναλλαγή χρήστη"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Κατάργηση"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Kαλώς ορίσατε ξανά!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Θέλετε να συνεχίσετε την περίοδο σύνδεσής σας;"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Έναρξη από την αρχή"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Προσθήκη"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Προτείνεται από <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Η συσκευή κλειδώθηκε"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Εμφάνιση και έλεγχος συσκευών από την οθόνη κλειδώματος;"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Μπορείτε να προσθέσετε στοιχεία ελέγχου για τις εξωτερικές συσκευές σας στην οθόνη κλειδώματος.\n\nΗ εφαρμογή της συσκευής σας μπορεί να σας παρέχει τη δυνατότητα ελέγχου ορισμένων συσκευών χωρίς να ξεκλειδώσετε το τηλέφωνο ή το tablet.\n\nΜπορείτε να κάνετε αλλαγές στις Ρυθμίσεις ανά πάσα στιγμή."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Έλεγχος συσκευών από την οθόνη κλειδώματος;"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Μπορείτε να ελέγχετε ορισμένες συσκευές χωρίς να ξεκλειδώσετε το τηλέφωνο ή το tablet σας.\n\nΗ εφαρμογή της συσκευής σας καθορίζει ποιες συσκευές μπορούν να ελέγχονται με αυτόν τον τρόπο."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Όχι, ευχαριστώ"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ναι"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Το PIN περιέχει γράμματα ή σύμβολα"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Επαλήθευση <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Λάθος PIN"</string>
@@ -775,8 +803,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Σύρετε για να δείτε περισσότερα."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Φόρτωση προτάσεων"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Μέσα"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Απόκρυψη στοιχείων ελέγχου μέσων για την εφαρμ. <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Αδυναμία απόκρ. τρέχουσας περιόδ. λειτουργ. μέσου."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Απόκρυψη"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string>
@@ -816,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Για μετάδοση της περιόδου σύνδεσης, ανοίξτε την εφαρμογή."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Άγνωστη εφαρμογή"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Διακοπή μετάδοσης"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
<string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
@@ -892,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ενεργές εφαρμογές"</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_copy" msgid="770856373439969178">"Αντιγραφή"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Τέλος"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Αντιγράφηκε"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Από <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Παράβλεψη διεπαφής χρήστη αντιγραφής"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 64e5501da01f..d995f5145d5f 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"This app has not been granted record permission but could capture audio through this USB device. Using <xliff:g id="APPLICATION">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Using <xliff:g id="APPLICATION">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Unlocked by your face. Press to continue."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -287,6 +292,15 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"This unblocks access for all apps and services allowed to use your microphone."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"This unblocks access for all apps and services allowed to use your camera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"This unblocks access for all apps and services allowed to use your camera or microphone."</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Microphone is blocked"</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Camera is blocked"</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"The mic &amp; camera are blocked"</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"To unblock, move the privacy switch on your device to the microphone on position to allow microphone access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"To unblock, move the privacy switch on your device to the camera on position to allow camera access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"To unblock them, move the privacy switch on your device to the unblocked position to allow access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Microphone available"</string>
+ <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Camera available"</string>
+ <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Microphone and camera available"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Other device"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers you specify. You\'ll still hear anything you choose to play including music, videos and games."</string>
@@ -320,7 +334,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
@@ -766,6 +779,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from the lock screen?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string>
@@ -815,6 +834,13 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
+ <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
+ <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
+ <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
+ <string name="media_output_broadcasting_message" msgid="4150299923404886073">"To listen to your broadcast, people nearby with compatible Bluetooth devices can scan your QR code or use your broadcast name and password"</string>
+ <string name="media_output_broadcast_name" msgid="8786127091542624618">"Broadcast name"</string>
+ <string name="media_output_broadcast_code" msgid="870795639644728542">"Password"</string>
+ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -891,7 +917,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copy"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Done"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copied"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"From <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dismiss copy UI"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 259a16f16812..d98088dce129 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"This app has not been granted record permission but could capture audio through this USB device. Using <xliff:g id="APPLICATION">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Using <xliff:g id="APPLICATION">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Unlocked by your face. Press to continue."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -287,6 +292,15 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"This unblocks access for all apps and services allowed to use your microphone."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"This unblocks access for all apps and services allowed to use your camera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"This unblocks access for all apps and services allowed to use your camera or microphone."</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Microphone is blocked"</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Camera is blocked"</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"The mic &amp; camera are blocked"</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"To unblock, move the privacy switch on your device to the microphone on position to allow microphone access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"To unblock, move the privacy switch on your device to the camera on position to allow camera access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"To unblock them, move the privacy switch on your device to the unblocked position to allow access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Microphone available"</string>
+ <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Camera available"</string>
+ <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Microphone and camera available"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Other device"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers you specify. You\'ll still hear anything you choose to play including music, videos and games."</string>
@@ -320,7 +334,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
@@ -766,6 +779,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from the lock screen?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string>
@@ -815,6 +834,13 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
+ <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
+ <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
+ <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
+ <string name="media_output_broadcasting_message" msgid="4150299923404886073">"To listen to your broadcast, people nearby with compatible Bluetooth devices can scan your QR code or use your broadcast name and password"</string>
+ <string name="media_output_broadcast_name" msgid="8786127091542624618">"Broadcast name"</string>
+ <string name="media_output_broadcast_code" msgid="870795639644728542">"Password"</string>
+ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -891,7 +917,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copy"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Done"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copied"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"From <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dismiss copy UI"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 64e5501da01f..d995f5145d5f 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"This app has not been granted record permission but could capture audio through this USB device. Using <xliff:g id="APPLICATION">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Using <xliff:g id="APPLICATION">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Unlocked by your face. Press to continue."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -287,6 +292,15 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"This unblocks access for all apps and services allowed to use your microphone."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"This unblocks access for all apps and services allowed to use your camera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"This unblocks access for all apps and services allowed to use your camera or microphone."</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Microphone is blocked"</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Camera is blocked"</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"The mic &amp; camera are blocked"</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"To unblock, move the privacy switch on your device to the microphone on position to allow microphone access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"To unblock, move the privacy switch on your device to the camera on position to allow camera access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"To unblock them, move the privacy switch on your device to the unblocked position to allow access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Microphone available"</string>
+ <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Camera available"</string>
+ <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Microphone and camera available"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Other device"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers you specify. You\'ll still hear anything you choose to play including music, videos and games."</string>
@@ -320,7 +334,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
@@ -766,6 +779,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from the lock screen?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string>
@@ -815,6 +834,13 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
+ <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
+ <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
+ <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
+ <string name="media_output_broadcasting_message" msgid="4150299923404886073">"To listen to your broadcast, people nearby with compatible Bluetooth devices can scan your QR code or use your broadcast name and password"</string>
+ <string name="media_output_broadcast_name" msgid="8786127091542624618">"Broadcast name"</string>
+ <string name="media_output_broadcast_code" msgid="870795639644728542">"Password"</string>
+ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -891,7 +917,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copy"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Done"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copied"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"From <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dismiss copy UI"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 64e5501da01f..d995f5145d5f 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"This app has not been granted record permission but could capture audio through this USB device. Using <xliff:g id="APPLICATION">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Using <xliff:g id="APPLICATION">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Unlocked by your face. Press to continue."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -287,6 +292,15 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"This unblocks access for all apps and services allowed to use your microphone."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"This unblocks access for all apps and services allowed to use your camera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"This unblocks access for all apps and services allowed to use your camera or microphone."</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Microphone is blocked"</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Camera is blocked"</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"The mic &amp; camera are blocked"</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"To unblock, move the privacy switch on your device to the microphone on position to allow microphone access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"To unblock, move the privacy switch on your device to the camera on position to allow camera access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"To unblock them, move the privacy switch on your device to the unblocked position to allow access. Refer to the device manual to locate the privacy switch on your device."</string>
+ <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Microphone available"</string>
+ <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Camera available"</string>
+ <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Microphone and camera available"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Other device"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers you specify. You\'ll still hear anything you choose to play including music, videos and games."</string>
@@ -320,7 +334,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
@@ -766,6 +779,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from the lock screen?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string>
@@ -815,6 +834,13 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
+ <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
+ <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
+ <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
+ <string name="media_output_broadcasting_message" msgid="4150299923404886073">"To listen to your broadcast, people nearby with compatible Bluetooth devices can scan your QR code or use your broadcast name and password"</string>
+ <string name="media_output_broadcast_name" msgid="8786127091542624618">"Broadcast name"</string>
+ <string name="media_output_broadcast_code" msgid="870795639644728542">"Password"</string>
+ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -891,7 +917,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copy"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Done"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copied"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"From <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dismiss copy UI"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index aef122a2ebc6..1ee103508aab 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎Auto-rotate screen‎‏‎‎‏‎"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎Allow ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to access ‎‏‎‎‏‏‎<xliff:g id="USB_DEVICE">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‎‎Allow ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to access ‎‏‎‎‏‏‎<xliff:g id="USB_DEVICE">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎This app has not been granted record permission but could capture audio through this USB device.‎‏‎‎‏‎"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to access ‎‏‎‎‏‏‎<xliff:g id="USB_DEVICE">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎Open ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to handle ‎‏‎‎‏‏‎<xliff:g id="USB_DEVICE">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎This app has not been granted record permission but could capture audio through this USB device. Using ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ with this device might prevent hearing calls, notifications and alarms.‎‏‎‎‏‎"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎Using ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ with this device might prevent hearing calls, notifications and alarms.‎‏‎‎‏‎"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to access ‎‏‎‎‏‏‎<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‏‎Open ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to handle ‎‏‎‎‏‏‎<xliff:g id="USB_DEVICE">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎Open ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to handle ‎‏‎‎‏‏‎<xliff:g id="USB_DEVICE">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎This app has not been granted record permission but could capture audio through this USB device.‎‏‎‎‏‎"</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎Unlocked by your face. Press to continue.‎‏‎‎‏‎"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎Authenticated‎‏‎‎‏‎"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎Use PIN‎‏‎‎‏‎"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎Use pattern‎‏‎‎‏‎"</string>
@@ -287,6 +292,15 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎This unblocks access for all apps and services allowed to use your microphone.‎‏‎‎‏‎"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎This unblocks access for all apps and services allowed to use your camera.‎‏‎‎‏‎"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎This unblocks access for all apps and services allowed to use your camera or microphone.‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎Microphone is blocked‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎Camera is blocked‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎The mic &amp; camera are blocked‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎To unblock, move the privacy switch on your device to the microphone on position to allow microphone access. Refer to the device manual to locate the privacy switch on your device.‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎To unblock, move the privacy switch on your device to the camera on position to allow camera access. Refer to the device manual to locate the privacy switch on your device.‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎To unblock them, move the privacy switch on your device to the unblocked position to allow access. Refer to the device manual to locate the privacy switch on your device.‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‎Microphone available‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎Camera available‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎Microphone and camera available‎‏‎‎‏‎"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎Other device‎‏‎‎‏‎"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎Toggle Overview‎‏‎‎‏‎"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify. You\'ll still hear anything you choose to play including music, videos, and games.‎‏‎‎‏‎"</string>
@@ -320,7 +334,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ • Charging Dock • Full in ‎‏‎‎‏‏‎<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎Switch user‎‏‎‎‏‎"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎All apps and data in this session will be deleted.‎‏‎‎‏‎"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎Remove‎‏‎‎‏‎"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎Welcome back, guest!‎‏‎‎‏‎"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎Do you want to continue your session?‎‏‎‎‏‎"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎Start over‎‏‎‎‏‎"</string>
@@ -766,6 +779,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎Add‎‏‎‎‏‎"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‎Suggested by ‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎Device locked‎‏‎‎‏‎"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎Show and control devices from lock screen?‎‏‎‎‏‎"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‏‎You can add controls for your external devices to the lock screen.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your device app may allow you to control some devices without unlocking your phone or tablet.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎You can make changes any time in Settings.‎‏‎‎‏‎"</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎Control devices from lock screen?‎‏‎‎‏‎"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎You can control some devices without unlocking your phone or tablet.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your device app determines which devices can be controlled in this way.‎‏‎‎‏‎"</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‎No thanks‎‏‎‎‏‎"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎Yes‎‏‎‎‏‎"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎PIN contains letters or symbols‎‏‎‎‏‎"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎Verify ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎Wrong PIN‎‏‎‎‏‎"</string>
@@ -815,6 +834,13 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎To cast this session, please open the app.‎‏‎‎‏‎"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎Unknown app‎‏‎‎‏‎"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎Stop casting‎‏‎‎‏‎"</string>
+ <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎How broadcasting works‎‏‎‎‏‎"</string>
+ <string name="media_output_broadcast" msgid="3555580945878071543">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎Broadcast‎‏‎‎‏‎"</string>
+ <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting‎‏‎‎‏‎"</string>
+ <string name="media_output_broadcasting_message" msgid="4150299923404886073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‎‏‎To listen to your broadcast, people nearby with compatible Bluetooth devices can scan your QR code or use your broadcast name and password‎‏‎‎‏‎"</string>
+ <string name="media_output_broadcast_name" msgid="8786127091542624618">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎Broadcast Name‎‏‎‎‏‎"</string>
+ <string name="media_output_broadcast_code" msgid="870795639644728542">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‏‏‎‎Password‎‏‎‎‏‎"</string>
+ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎Save‎‏‎‎‏‎"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎Build number‎‏‎‎‏‎"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎Build number copied to clipboard.‎‏‎‎‏‎"</string>
<string name="basic_status" msgid="2315371112182658176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎Open conversation‎‏‎‎‏‎"</string>
@@ -891,7 +917,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎Active apps‎‏‎‎‏‎"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎Stop‎‏‎‎‏‎"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎Stopped‎‏‎‎‏‎"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎Copy‎‏‎‎‏‎"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎Done‎‏‎‎‏‎"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‏‎Copied‎‏‎‎‏‎"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎From ‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎Dismiss copy UI‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 1976ab458204..4ad0b88c10c0 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Girar la pantalla automáticamente"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"¿Deseas permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"¿Quieres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nLa app no tiene permiso para grabar, pero podría capturar audio mediante este dispositivo USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"¿Deseas permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"¿Deseas abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para usar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Aunque no se le otorgó permiso de grabación a esta app, puede capturar audio con este dispositivo USB. Es posible que el uso de <xliff:g id="APPLICATION">%1$s</xliff:g> en este dispositivo impida escuchar llamadas, notificaciones y alarmas."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Es posible que el uso de <xliff:g id="APPLICATION">%1$s</xliff:g> en este dispositivo impida escuchar llamadas, notificaciones y alarmas."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"¿Deseas permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"¿Deseas abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para usar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"¿Quieres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para administrar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nLa app no tiene permiso para grabar, pero puede capturar audio mediante este dispositivo USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Disp. desbloqueado con rostro. Presiona para continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Esta acción desbloquea el acceso para todos los servicios y las apps que tengan permitido usar el micrófono."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Esta acción desbloquea el acceso para todos los servicios y las apps que tengan permitido usar la cámara."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Esta acción permite que todas las aplicaciones y servicios que tengan permiso puedan usar la cámara o el micrófono."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Otro dispositivo"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Ocultar o mostrar Recientes"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas de los emisores que especifiques. Podrás escuchar el contenido que reproduzcas, como música, videos y juegos."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Conectado y cargando • Carga completa en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"¡Hola de nuevo, invitado!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Agregar"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Dispos. bloqueado"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN contiene letras o símbolos"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verificar <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorrecto"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sesión, abre la app"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconocida"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Detener transmisión"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps activas"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Detener"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detenida"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copiar"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Se copió"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Descartar la copia de la IU"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index a45d85ee571a..11982f558d32 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Girar pantalla automáticamente"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"¿Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"¿Quieres que <xliff:g id="APPLICATION">%1$s</xliff:g> pueda acceder a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta aplicación no tiene permisos para grabar, pero podría captar audio a través de este dispositivo USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"¿Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"¿Abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para gestionar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Esta aplicación no tiene permiso para grabar, pero podría registrar audio con este dispositivo USB. Si usas <xliff:g id="APPLICATION">%1$s</xliff:g> en este dispositivo, puede que no oigas llamadas, notificaciones ni alarmas."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Si usas <xliff:g id="APPLICATION">%1$s</xliff:g> en este dispositivo, puede que no oigas llamadas, notificaciones ni alarmas."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"¿Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"¿Quieres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"¿Quieres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para gestionar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta aplicación no tiene permisos para grabar, pero puede capturar audio mediante este dispositivo USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Desbloqueada con la cara. Pulsa para continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Se ha autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Si lo haces, todas las aplicaciones y servicios que tengan permiso podrán usar tu micrófono."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Si lo haces, todas las aplicaciones y servicios que tengan permiso podrán usar tu cámara."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Si lo haces, todas las aplicaciones y servicios que tengan permiso podrán usar tu cámara o tu micrófono."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Otro dispositivo"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Mostrar u ocultar aplicaciones recientes"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas que especifiques. Seguirás escuchando el contenido que quieras reproducir, como música, vídeos y juegos."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Base de carga • En <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> terminará de cargar"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Hola de nuevo, invitado"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con la sesión?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Añadir"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloqueado"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN contiene letras o símbolos"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifica <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorrecto"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para enviar esta sesión, abre la aplicación."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación desconocida"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dejar de enviar contenido"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicaciones activas"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Detener"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detenida"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copiar"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Cerrar la interfaz de copia"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 0b39a2c31de0..875e8f35ef01 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -34,10 +34,14 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Kuva automaatne pööramine"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Kas lubada rakendusele <xliff:g id="APPLICATION">%1$s</xliff:g> juurdepääs seadmele <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Kas lubada rakendusel <xliff:g id="APPLICATION">%1$s</xliff:g> seadmele <xliff:g id="USB_DEVICE">%2$s</xliff:g> juurde pääseda?\nSellele rakendusele pole antud salvestamise luba, kuid see saab heli jäädvustada selle USB-seadme kaudu."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Kas lubada rakendusele <xliff:g id="APPLICATION">%1$s</xliff:g> juurdepääs seadmele <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Kas avada <xliff:g id="APPLICATION">%1$s</xliff:g> seadme <xliff:g id="USB_DEVICE">%2$s</xliff:g> kasutamiseks?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Sellele rakendusele pole antud salvestamise luba, kuid see saab heli jäädvustada selle USB-seadme kaudu. Rakenduse <xliff:g id="APPLICATION">%1$s</xliff:g> kasutamine selle seadmega võib takistada kõnede, märguannete ja äratuste kuulmist."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Rakenduse <xliff:g id="APPLICATION">%1$s</xliff:g> kasutamine selle seadmega võib takistada kõnede, märguannete ja äratuste kuulmist."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Kas lubada rakendusele <xliff:g id="APPLICATION">%1$s</xliff:g> juurdepääs seadmele <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
- <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Kas avada rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> seadme <xliff:g id="USB_DEVICE">%2$s</xliff:g> kasutamiseks?"</string>
+ <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Kas avada <xliff:g id="APPLICATION">%1$s</xliff:g> seadme <xliff:g id="USB_DEVICE">%2$s</xliff:g> kasutamiseks?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Kas avada <xliff:g id="APPLICATION">%1$s</xliff:g>, et käsitseda seadet <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nSellele rakendusele pole antud salvestamise luba, kuid see saab heli jäädvustada selle USB-seadme kaudu."</string>
- <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"Kas avada rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> seadme <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> kasutamiseks?"</string>
+ <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"Kas avada <xliff:g id="APPLICATION">%1$s</xliff:g> seadme <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> kasutamiseks?"</string>
<string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Inst. rak. ei tööta selle USB-seadmega. Lisateavet lisaseadme kohta vt siit: <xliff:g id="URL">%1$s</xliff:g>"</string>
<string name="title_usb_accessory" msgid="1236358027511638648">"USB-lisaseade"</string>
<string name="label_view" msgid="6815442985276363364">"Kuva"</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Avati teie näoga. Vajutage jätkamiseks."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenditud"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Kasuta PIN-koodi"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Kasuta mustrit"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Sellega tühistatakse juurdepääsu blokeerimine kõikide rakenduste ja teenuste puhul, millel on lubatud mikrofoni kasutada."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Sellega tühistatakse juurdepääsu blokeerimine kõikide rakenduste ja teenuste puhul, millel on lubatud kaamerat kasutada."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Sellega tühistatakse juurdepääsu blokeerimine kõikide rakenduste ja teenuste puhul, millel on lubatud kaamerat või mikrofoni kasutada."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Muu seade"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Lehe Ülevaade sisse- ja väljalülitamine"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Helid ja värinad ei sega teid. Kuulete siiski enda määratud äratusi, meeldetuletusi, sündmusi ja helistajaid. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laadimisdokk • Täis <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> pärast"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kasutaja vahetamine"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eemalda"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Tere tulemast tagasi, külaline!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Kas soovite seansiga jätkata?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Alusta uuesti"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Lisa"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Soovitas <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Seade on lukustatud"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-kood sisaldab tähti või sümboleid"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Kinnitage <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Vale PIN-kood"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pühkige sõrmega, et näha rohkem"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Soovituste laadimine"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Meedia"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Kas peita rakenduses <xliff:g id="APP_NAME">%1$s</xliff:g> see meedia juhtnupp?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Praegust meediaseanssi ei saa peita."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Peida"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Selle seansi ülekandmiseks avage rakendus."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tundmatu rakendus"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lõpeta ülekanne"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
<string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiivsed rakendused"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Peata"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Peatatud"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopeeri"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopeeritud"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Rakendusest <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Koopiast loobumise kasutajaliides"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 95bd08facfaa..c286dccd98f6 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Biratu pantaila automatikoki"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> atzitzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> erabiltzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?\nAplikazioak ez du grabatzeko baimenik, baina baliteke USB bidezko gailu horren bidez audioa grabatzea."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> atzitzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_DEVICE">%2$s</xliff:g> kudeatzeko?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Aplikazioak ez du grabatzeko baimenik, baina baliteke USB bidezko gailu honen bidez audioa grabatzea. <xliff:g id="APPLICATION">%1$s</xliff:g> gailu honekin erabiliz gero, baliteke deiak, jakinarazpenak eta alarmak ez entzutea."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> gailu honekin erabiliz gero, baliteke deiak, jakinarazpenak eta alarmak ez entzutea."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> atzitzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_DEVICE">%2$s</xliff:g> kudeatzeko?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_DEVICE">%2$s</xliff:g> erabiltzeko?\nAplikazioak ez du grabatzeko baimenik, baina baliteke audioa grabatzea USB bidezko gailu horren bidez."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Aurpegiaren bidez desblokeatu da. Sakatu aurrera egiteko."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikatuta"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Erabili PINa"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Erabili eredua"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Mikrofonoa atzitzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dute."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Kamera atzitzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dute."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Kamera edo mikrofonoa atzitzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dituzte."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Beste gailu bat"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Aldatu ikuspegi orokorra"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Gailuak ez du egingo ez soinurik ez dardararik, baina alarmak, gertaera eta abisuen tonuak, eta aukeratzen dituzun deitzaileen dei-tonuak joko ditu. Bestalde, zuk erreproduzitutako guztia entzungo duzu, besteak beste, musika, bideoak eta jokoak."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oinarrian kargatzen • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> guztiz kargatu arte"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Aldatu erabiltzailea"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kendu"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Ongi etorri berriro, gonbidatu hori!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Saioarekin jarraitu nahi duzu?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Hasi berriro"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Gehitu"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> aplikazioak iradoki du"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Gailua blokeatuta"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN kodeak hizkiak edo ikurrak ditu"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Egiaztatu <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN okerra"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasatu hatza aukera gehiago ikusteko"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Gomendioak kargatzen"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimedia-edukia"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren multimedia-edukiaren kontrolagailu hau ezkutatu?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Ezin da ezkutatu multimedia-saioa."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ezkutatu"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Saioa ireki nahi baduzu, ireki aplikazioa."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikazio ezezaguna"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Utzi igortzeari"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
<string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktibo dauden aplikazioak"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Gelditu"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Geldituta"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiatu"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiatu da"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Jatorria: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopiatutako UIa baztertzeko botoia"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index dd6a6cbe173a..45d661a17661 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"چرخش خودکار صفحه"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"به <xliff:g id="APPLICATION">%1$s</xliff:g> برای دسترسی به <xliff:g id="USB_DEVICE">%2$s</xliff:g> اجازه داده شود؟"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"‏به <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه می‌دهید به <xliff:g id="USB_DEVICE">%2$s</xliff:g>دسترسی داشته باشد؟\nمجوز ضبط به این برنامه داده نشده است اما می‌تواند صدا را ازطریق این دستگاه USB ضبط کند."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"به <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه دسترسی به <xliff:g id="USB_DEVICE">%2$s</xliff:g> داده شود؟"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> برای استفاده از <xliff:g id="USB_DEVICE">%2$s</xliff:g> باز شود؟"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"‏اجازه ضبط به این برنامه داده نشده است اما می‌تواند صدا را ازطریق این دستگاه USB ضبط کند. استفاده از <xliff:g id="APPLICATION">%1$s</xliff:g> با این دستگاه می‌تواند مانع از شنیدن تماس‌ها، اعلان‌ها، و زنگ‌های ساعت شود."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"استفاده از <xliff:g id="APPLICATION">%1$s</xliff:g> با این دستگاه می‌تواند مانع از شنیدن تماس‌ها، اعلان‌ها، و زنگ‌های ساعت شود."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"به <xliff:g id="APPLICATION">%1$s</xliff:g> برای دسترسی به <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> اجازه داده شود؟"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"برای استفاده از <xliff:g id="USB_DEVICE">%2$s</xliff:g>، <xliff:g id="APPLICATION">%1$s</xliff:g> باز شود؟"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"‏<xliff:g id="APPLICATION">%1$s</xliff:g> برای رسیدگی به <xliff:g id="USB_DEVICE">%2$s</xliff:g> باز شود؟\nمجوز ضبط به این برنامه داده نشده است اما می‌تواند صدا را ازطریق این دستگاه USB ضبط کند."</string>
@@ -131,7 +135,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="1597899891472340950">"قفل با چهره‌تان باز شد. برای ادامه دادن، فشار دهید."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"راستی‌آزمایی‌شده"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"استفاده از پین"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"استفاده از الگو"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"با این کار دسترسی برای همه برنامه‌ها و سرویس‌هایی که مجاز هستند از میکروفونتان استفاده کنند لغو انسداد می‌شود."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"با این کار دسترسی برای همه برنامه‌ها و سرویس‌هایی که مجاز هستند از دوربینتان استفاده کنند لغو انسداد می‌شود."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"با این کار دسترسی برای همه برنامه‌ها و دستگاه‌هایی که مجاز هستند از دوربین یا میکروفونتان استفاده کنند لغو انسداد می‌شود."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"دستگاه دیگر"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"تغییر وضعیت نمای کلی"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"به‌جز هشدارها، یادآوری‌ها، رویدادها و تماس‌گیرندگانی که خودتان مشخص می‌کنید، هیچ صدا و لرزشی نخواهید داشت. همچنان صدای مواردی را که پخش می‌کنید می‌شنوید (ازجمله صدای موسیقی، ویدیو و بازی)."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • پایه شارژ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> تا شارژ کامل"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تغییر کاربر"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامه‌ها و داده‌های این جلسه حذف خواهد شد."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"حذف"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"مهمان گرامی، بازگشتتان را خوش آمد می‌گوییم!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"آیا می‌خواهید جلسه‌تان را ادامه دهید؟"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"شروع مجدد"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"افزودن"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"پیشنهاد <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"دستگاه قفل است"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"برای دیدن موارد بیشتر، تند بکشید"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"درحال بار کردن توصیه‌ها"</string>
<string name="controls_media_title" msgid="1746947284862928133">"رسانه"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"این کنترل رسانه برای <xliff:g id="APP_NAME">%1$s</xliff:g> پنهان شود؟"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"جلسه رسانه کنونی نمی‌تواند پنهان شود."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"پنهان کردن"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ازسرگیری"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"برای ارسال محتوای این جلسه، لطفاً برنامه را باز کنید."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"برنامه ناشناس"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"توقف ارسال محتوا"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
<string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"برنامه‌های فعال"</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_copy" msgid="770856373439969178">"کپی کردن"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"کپی شد"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"از <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"رد کردن رابط کاربری کپی کردن"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 85623e04313f..28e430579871 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Näytön automaattinen kääntö"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Saako <xliff:g id="APPLICATION">%1$s</xliff:g> käyttöoikeuden (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Saako <xliff:g id="APPLICATION">%1$s</xliff:g> tämän pääsyoikeuden: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nSovellus ei ole saanut tallennuslupaa, mutta voi tallentaa ääntä tämän USB-laitteen avulla."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Saako <xliff:g id="APPLICATION">%1$s</xliff:g> pääsyn (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Avataanko <xliff:g id="APPLICATION">%1$s</xliff:g>, jotta <xliff:g id="USB_DEVICE">%2$s</xliff:g> voidaan ottaa käyttöön?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Sovellus ei ole saanut tallennuslupaa mutta voi tallentaa audiota tämän USB-laitteen avulla. Jos <xliff:g id="APPLICATION">%1$s</xliff:g> on käytössä laitteella, puheluita, ilmoituksia ja herätyksiä ei välttämättä kuulu."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Jos <xliff:g id="APPLICATION">%1$s</xliff:g> on käytössä laitteella, puheluita, ilmoituksia ja herätyksiä ei välttämättä kuulu."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Saako <xliff:g id="APPLICATION">%1$s</xliff:g> käyttöoikeuden (<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>)?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Avataanko <xliff:g id="APPLICATION">%1$s</xliff:g>, jotta <xliff:g id="USB_DEVICE">%2$s</xliff:g> voidaan ottaa käyttöön?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Avataanko <xliff:g id="APPLICATION">%1$s</xliff:g>, jotta <xliff:g id="USB_DEVICE">%2$s</xliff:g> voidaan ottaa käyttöön?\nSovellus ei ole saanut tallennuslupaa, mutta voi tallentaa ääntä tämän USB-laitteen avulla."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Lukitus avattu kasvojen avulla. Jatka painamalla."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Todennettu"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Käytä PIN-koodia"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Käytä kuviota"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Tämä kumoaa kaikkien sellaisten sovellusten ja palveluiden eston, joilla on lupa käyttää mikrofoniasi."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Tämä kumoaa kaikkien sellaisten sovellusten ja palveluiden eston, joilla on lupa käyttää kameraasi."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Tämä kumoaa eston kaikkien sellaisten sovellusten ja palveluiden osalta, joilla on lupa käyttää kameraasi tai mikrofoniasi."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Muu laite"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Näytä/piilota viimeisimmät"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Äänet ja värinät eivät häiritse sinua, paitsi jos ne ovat hälytyksiä, muistutuksia, tapahtumia tai määrittämiäsi soittajia. Kuulet edelleen kaiken valitsemasi sisällön, kuten musiikin, videot ja pelit."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ladataan telineellä • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> kunnes täynnä"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Poista"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Tervetuloa takaisin!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Haluatko jatkaa istuntoa?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Aloita alusta"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Lisää"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Ehdottaja: <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Laite lukittu"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-koodi sisältää kirjaimia tai symboleja"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Vahvista <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Väärä PIN-koodi"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pyyhkäise nähdäksesi lisää"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ladataan suosituksia"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Piilotetaanko mediaohjain (<xliff:g id="APP_NAME">%1$s</xliff:g>)?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Tätä median käyttökertaa ei voi piilottaa."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Piilota"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jatka"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jos haluat striimata tämän käyttökerran, avaa sovellus."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tuntematon sovellus"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lopeta striimaus"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
<string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiiviset sovellukset"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Lopeta"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Pysäytetty"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopioi"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopioitu"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Lähde: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Hylkää kopioitu UI"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index f39a6394cd78..f908590f6020 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation auto de l\'écran"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Autorisé <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Cette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB. L\'utilisation de <xliff:g id="APPLICATION">%1$s</xliff:g> avec cet appareil peut empêcher d\'entendre les appels, les notifications et les alarmes."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"L\'utilisation de <xliff:g id="APPLICATION">%1$s</xliff:g> avec cet appareil peut empêcher d\'entendre les appels, les notifications et les alarmes."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour gérer <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Déverrouillé par votre visage. Appuyez pour continuer."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un NIP"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Cette action débloque l\'accès pour toutes les applications et tous les services autorisés à utiliser le microphone."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Cette action débloque l\'accès pour toutes les applications et pour tous les services autorisés à utiliser l\'appareil photo."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès pour toutes les applications et tous les services autorisés à utiliser l\'appareil photo ou le microphone."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Autre appareil"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Basculer l\'aperçu"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Vous ne serez pas dérangé par les sons et les vibrations, sauf pour les alarmes, les rappels, les événements et les appelants que vous sélectionnez. Vous entendrez tout ce que vous choisissez d\'écouter, y compris la musique, les vidéos et les jeux."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Station de recharge • Recharge terminée dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ajouter"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggestion de <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Appareil verrouillé"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Le NIP contient des lettres ou des symboles"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Vérifier <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"NIP incorrect"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Balayez l\'écran pour en afficher davantage"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Commandes multimédias"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Masquer ce contrôleur de contenu multimédia pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Impossible de masquer la session multimédia actuelle"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour diffuser cette session, veuillez ouvrir l\'application."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Application inconnue"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
<string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applications actives"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Arrêter"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Arrêtée"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copier"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copié"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"À partir de <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorer la copie de l\'IU"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 9b0b68fcdf98..22f547c084d0 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation automatique de l\'écran"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio via ce périphérique USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder au <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour gérer le <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Cette appli n\'a pas été autorisée à enregistrer de contenus audio, mais elle peut le faire via ce périphérique USB. En utilisant <xliff:g id="APPLICATION">%1$s</xliff:g> avec ce périphérique, vous risquez de ne pas entendre les appels, notifications et alarmes."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Vous risquez de ne pas entendre les appels, notifications et alarmes si vous utilisez <xliff:g id="APPLICATION">%1$s</xliff:g> avec ce périphérique."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour gérer <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?\nCette application n\'a pas reçu l\'autorisation d\'enregistrer des contenus audio, mais peut le faire via ce périphérique USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Déverrouillé par votre visage. Appuyez pour continuer."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un code PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Cette action débloque l\'accès à tous les services et applis autorisés à utiliser votre micro."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Cette action débloque l\'accès à tous les services et applis autorisés à utiliser votre appareil photo."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès pour tous les services et applis autorisés à utiliser votre appareil photo ou votre micro."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Autre appareil"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activer/Désactiver l\'aperçu"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Vous ne serez dérangé par aucun son ni aucune vibration, hormis ceux des alarmes, des rappels, des événements et des appels des contacts de votre choix. Le son continuera de fonctionner notamment pour la musique, les vidéos et les jeux."</string>
@@ -314,13 +337,12 @@
<string name="interruption_level_priority_twoline" msgid="8523482736582498083">"Priorité\nuniquement"</string>
<string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"Alarmes\nuniquement"</string>
<string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge sans fil • Chargé dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
- <string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge • Chargé dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
+ <string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • En charge • Chargé dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge rapide • Chargé dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge lente • Chargé dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Station de charge • Chargé dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la dernière session ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Non, nouvelle session"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ajouter"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggérée par <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Appareil verrouillé"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Le code contient des lettres ou des symboles"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Valider <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Code incorrect"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Balayer l\'écran pour voir plus d\'annonces"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Masquer cette commande multimédia pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Session multimédia en cours impossible à masquer."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour caster cette session, veuillez ouvrir l\'appli."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Appli inconnue"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applis actives"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Arrêter"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Arrêtée"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copier"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copié"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Désactiver l\'interface de copie"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 915aef1085f9..41b7cef85607 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Xirar pantalla automaticamente"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Queres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Queres permitir que a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda ao dispositivo (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?\nEsta aplicación non está autorizada para realizar gravacións, pero pode capturar audio a través deste dispositivo USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Queres permitir que a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Queres abrir a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Esta aplicación non está autorizada a realizar gravacións, pero pode capturar audio a través deste dispositivo USB. Ao usar a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> con este dispositivo, é posible que non se escoiten chamadas, notificacións nin alarmas."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ao usar a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> con este dispositivo, é posible que non se escoiten chamadas, notificacións nin alarmas."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Queres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Queres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Queres abrir a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> para xestionar o dispositivo (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?\nEsta aplicación non está autorizada a realizar gravacións, pero pode capturar audio a través deste dispositivo USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Desbloqueouse coa túa cara. Preme para continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrón"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Con esta acción desbloquearase o acceso ao micrófono para todas as aplicacións e servizos que teñan permiso para utilizalo."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Con esta acción desbloquearase o acceso á cámara para todas as aplicacións e servizos que teñan permiso para utilizala."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Con esta acción desbloquearase o acceso á cámara ou ao micrófono para todas as aplicacións e servizos que teñan permiso para utilizalos."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Outro dispositivo"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activar/desactivar Visión xeral"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas, recordatorios, eventos e os emisores de chamada especificados. Seguirás escoitando todo aquilo que decidas reproducir, mesmo a música, os vídeos e os xogos."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Base de carga • Carga completa dentro de <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvido de novo, convidado"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Engadir"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Control suxerido por <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Disposit. bloqueado"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contén letras ou símbolos"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verificar <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"O PIN é incorrecto"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasar o dedo para ver máis"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendacións"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Contido multimedia"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Queres ocultar este control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Non se pode ocultar esta sesión multimedia."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para emitir esta sesión, abre a aplicación."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación descoñecida"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Deter emisión"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacións activas"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Deter"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detida"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copiar"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiouse"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorar interface de copia"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index ce43d8a103f7..619a03db13fa 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ઑટો રોટેટ સ્ક્રીન"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ના ઍક્સેસ માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને મંજૂરી આપીએ?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>ને <xliff:g id="USB_DEVICE">%2$s</xliff:g> ઍક્સેસ કરવાની મંજૂરી આપીએ?\nઆ ઍપને રેકૉર્ડ કરવાની પરવાનગી આપવામાં આવી નથી પરંતુ તે આ USB ડિવાઇસ મારફત ઑડિયો કૅપ્ચર કરી શકે છે."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ના ઍક્સેસ માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને મંજૂરી આપીએ?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ને હૅન્ડલ કરવા માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને ખોલીએ?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"આ ઍપને રેકોર્ડ કરવાની પરવાનગી આપવામાં આવી નથી પરંતુ તે આ USB ડિવાઇસ મારફતે ઑડિયો કૅપ્ચર કરી શકે છે. આ ડિવાઇસ સાથે <xliff:g id="APPLICATION">%1$s</xliff:g>નો ઉપયોગ કરવાથી કૉલ, નોટિફિકેશન અને અલાર્મ ન સંભળાય તેમ બની શકે."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"આ ડિવાઇસ સાથે <xliff:g id="APPLICATION">%1$s</xliff:g>નો ઉપયોગ કરવાથી કૉલ, નોટિફિકેશન અને અલાર્મ ન સંભળાય તેમ બની શકે."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ના ઍક્સેસ માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને મંજૂરી આપીએ?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ને હૅન્ડલ કરવા માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને ખોલીએ?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ને હેન્ડલ કરવા માટે <xliff:g id="APPLICATION">%1$s</xliff:g> ખોલીએ?\nઆ ઍપને રેકૉર્ડ કરવાની પરવાનગી આપવામાં આવી નથી પરંતુ તે આ USB ડિવાઇસ મારફત ઑડિયો કૅપ્ચર કરી શકે છે."</string>
@@ -131,7 +135,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="1597899891472340950">"તમારા ચહેરા વડે અનલૉક કર્યું. આગળ વધવા માટે ટૅપ કરો."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"પ્રમાણિત"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"પિનનો ઉપયોગ કરો"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"પૅટર્નનો ઉપયોગ કરો"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"આ તમારા માઇક્રોફોનનો ઉપયોગ કરવાની મંજૂરી ધરાવતી તમામ ઍપ અને સેવાઓ માટે ઍક્સેસને અનબ્લૉક કરે છે."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"આ તમારા કૅમેરાનો ઉપયોગ કરવાની મંજૂરી ધરાવતી તમામ ઍપ અને સેવાઓ માટે ઍક્સેસને અનબ્લૉક કરે છે."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"આ તમારા કૅમેરા અથવા માઇક્રોફોનનો ઉપયોગ કરવાની મંજૂરી ધરાવતી તમામ ઍપ અને સેવાઓ માટે ઍક્સેસને અનબ્લૉક કરે છે."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"અન્ય ડિવાઇસ"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ઝલકને ટૉગલ કરો"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"અલાર્મ, રિમાઇન્ડર, ઇવેન્ટ અને તમે ઉલ્લેખ કરો તે કૉલર સિવાય તમને ધ્વનિ કે વાઇબ્રેશન દ્વારા ખલેલ પહોંચાડવામાં આવશે નહીં. સંગીત, વીડિઓ અને રમતો સહિત તમે જે કંઈપણ ચલાવવાનું પસંદ કરશો તે સંભળાતું રહેશે."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ડૉકથી ચાર્જ થઈ રહ્યું છે • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>માં સંપૂર્ણ ચાર્જ થઈ જશે"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"કાઢી નાખો"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ફરી સ્વાગત છે, અતિથિ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"શું તમે તમારું સત્ર ચાલુ રાખવા માંગો છો?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"શરૂ કરો"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"ઉમેરો"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> દ્વારા સૂચન કરેલા"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"ડિવાઇસ લૉક કરેલું છે"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"વધુ જોવા માટે સ્વાઇપ કરો"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"સુઝાવ લોડ કરી રહ્યાં છીએ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"મીડિયા"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"શું <xliff:g id="APP_NAME">%1$s</xliff:g> માટે મીડિયાના નિયંત્રણો છુપાવીએ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"હાલનું મીડિયા સત્ર છુપાવી શકાતું નથી."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"છુપાવો"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"આ સત્ર કાસ્ટ કરવા માટે, કૃપા કરીને ઍપ ખોલો."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"અજાણી ઍપ"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"કાસ્ટ કરવાનું રોકો"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string>
<string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"સક્રિય ઍપ"</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_copy" msgid="770856373439969178">"કૉપિ કરો"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"કૉપિ કરવામાં આવી"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>માંથી"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"\'UI | યૂઝર ઇન્ટરફેસ (UI) કૉપિ કરો\'ને છોડી દો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 9f3a4f5b76ae..607ce9da259d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"स्‍क्रीन अपने आप घुमाना"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> को <xliff:g id="USB_DEVICE">%2$s</xliff:g> के ऐक्सेस की अनुमति दें?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> को <xliff:g id="USB_DEVICE">%2$s</xliff:g> ऐक्सेस करने की अनुमति देना चाहते हैं?\nइस ऐप्लिकेशन को रिकॉर्ड करने की अनुमति नहीं दी गई है. हालांकि, ऐप्लिकेशन इस यूएसबी डिवाइस से ऑडियो कैप्चर कर सकता है."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"क्या <xliff:g id="APPLICATION">%1$s</xliff:g> को <xliff:g id="USB_DEVICE">%2$s</xliff:g> का ऐक्सेस देना है?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"क्या <xliff:g id="USB_DEVICE">%2$s</xliff:g> का इस्तेमाल करने के लिए <xliff:g id="APPLICATION">%1$s</xliff:g> को खोलना है?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"इस ऐप्लिकेशन को रिकॉर्ड करने की अनुमति नहीं दी गई है. हालांकि, ऐप्लिकेशन इस यूएसबी डिवाइस से ऑडियो रिकॉर्ड कर सकता है. <xliff:g id="APPLICATION">%1$s</xliff:g> का इस्तेमाल इस डिवाइस के साथ करने पर, हो सकता है कि कॉल, सूचनाएं, और अलार्म की आवाज़ सुनाई न दे."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> का इस्तेमाल इस डिवाइस के साथ करने पर, हो सकता है कि कॉल, सूचनाएं, और अलार्म की आवाज़ सुनाई न दे."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> को <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> के ऐक्सेस की अनुमति दें?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> के लिए <xliff:g id="APPLICATION">%1$s</xliff:g> खोलें?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> का इस्तेमाल करने के लिए <xliff:g id="APPLICATION">%1$s</xliff:g> को खोलना चाहते हैं?\n इस ऐप्लिकेशन को रिकॉर्ड करने की अनुमति नहीं दी गई है. हालांकि, ऐप्लिकेशन इस यूएसबी डिवाइस से ऑडियो कैप्चर कर सकता है."</string>
@@ -131,7 +135,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="1597899891472340950">"आपके चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"पुष्टि हो गई"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन इस्तेमाल करें"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पैटर्न इस्तेमाल करें"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ऐसा करने से, माइक्रोफ़ोन का ऐक्सेस उन सभी ऐप्लिकेशन और सेवाओं के लिए अनब्लॉक हो जाएगा जिन्हें माइक्रोफ़ोन का इस्तेमाल करने की अनुमति दी गई है."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ऐसा करने से, कैमरे का ऐक्सेस उन सभी ऐप्लिकेशन और सेवाओं के लिए अनब्लॉक हो जाएगा जिन्हें कैमरे का इस्तेमाल करने की अनुमति दी गई है."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ऐसा करने से, कैमरा या माइक्रोफ़ोन का ऐक्सेस उन सभी ऐप्लिकेशन और सेवाओं के लिए अनब्लॉक हो जाएगा जिन्हें ये इस्तेमाल करने की अनुमति है."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"अन्य डिवाइस"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"खास जानकारी टॉगल करें"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"आपको अलार्म, रिमाइंडर, इवेंट और चुनिंदा कॉल करने वालों के अलावा किसी और तरह से (आवाज़ करके और थरथरा कर ) परेशान नहीं किया जाएगा. आप फिर भी संगीत, वीडियो और गेम सहित अपना चुना हुआ सब कुछ सुन सकते हैं."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • डॉक पर चार्ज हो रहा है • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> में पूरा चार्ज हो जाएगा"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सत्र के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"निकालें"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"मेहमान, आपका फिर से स्वागत है!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"क्‍या आप अपना सत्र जारी रखना चाहते हैं?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"फिर से शुरू करें"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"जोड़ें"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> से मिला सुझाव"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"डिवाइस लॉक है"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ज़्यादा देखने के लिए स्वाइप करें"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सुझाव लोड हो रहे हैं"</string>
<string name="controls_media_title" msgid="1746947284862928133">"मीडिया"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"क्या <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए, इस मीडिया कंट्रोल को छिपाना है?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"मौजूदा मीडिया सेशन को छिपाया नहीं जा सकता."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"छिपाएं"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"फिर से शुरू करें"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"इस सेशन को कास्ट करने के लिए, कृपया ऐप्लिकेशन खोलें."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अनजान ऐप्लिकेशन"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्टिंग करना रोकें"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
<string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ये ऐप्लिकेशन चालू हैं"</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_copy" msgid="770856373439969178">"कॉपी करें"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"कॉपी किया गया"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> से"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"कॉपी किया गया यूज़र इंटरफ़ेस (यूआई) खारिज करें"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 8004b5e4a955..1f5f044c4953 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatski zakreni zaslon"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Želite li dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Želite li dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTa aplikacija nema dopuštenje za snimanje, no mogla bi primati zvuk putem tog USB uređaja."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Želite li dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Želite li otvoriti aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> radi upravljanja uređajem <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ta aplikacija nema dopuštenje za snimanje, no mogla bi primati zvuk putem ovog USB uređaja. Zbog upotrebe aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g> s ovim uređajem možda nećete čuti pozive, obavijesti i alarme."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Zbog upotrebe aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g> s ovim uređajem možda nećete čuti pozive, obavijesti i alarme."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Želite li dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Želite li otvoriti aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> radi upravljanja uređajem <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Želite li upravljati uređajem <xliff:g id="USB_DEVICE">%2$s</xliff:g> putem aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g>?\nTa aplikacija nema dopuštenje za snimanje, no mogla bi primati zvuk putem tog USB uređaja."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Otključano vašim licem. Pritisnite da biste nastavili."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentičnost provjerena"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite uzorak"</string>
@@ -289,6 +294,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Time se deblokira pristup za sve aplikacije i usluge kojima je dopuštena upotreba vašeg mikrofona."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Time se deblokira pristup za sve aplikacije i usluge kojima je dopuštena upotreba vašeg fotoaparata."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Time se deblokira pristup za sve aplikacije i usluge kojima je dopuštena upotreba vašeg fotoaparata ili mikrofona."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Ostali uređaji"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Uključivanje/isključivanje pregleda"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Neće vas ometati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivatelja koje navedete. I dalje ćete čuti sve što želite reproducirati, uključujući glazbu, videozapise i igre."</string>
@@ -322,7 +345,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Priključna stanica za punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do napunjenosti"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji bit će izbrisani."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli natrag, gostu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
@@ -772,6 +794,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
<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>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Potvrdite uređaj <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Pogrešan PIN"</string>
@@ -821,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste emitirali ovu sesiju, otvorite aplikaciju."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi emitiranje"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -898,7 +946,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiraj"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Iz aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Odbaci kopiranje korisničkog sučelja"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index ec9a40e4fc8b..f5a4c9d20d37 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Képernyő automatikus forgatása"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Engedélyezi a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> számára, hogy hozzáférjen a következőhöz: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Lehetővé teszi a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazásnak, hogy hozzáférjen a következőhöz: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEz az alkalmazás nem rendelkezik rögzítési engedéllyel, de ezzel az USB-eszközzel képes a hangfelvételre."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Engedélyezi a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás számára, hogy hozzáférjen a következőhöz: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Megnyitja a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazást a következő kezeléséhez: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ez az alkalmazás nem rendelkezik rögzítési engedéllyel, de ezzel az USB-eszközzel képes a hangfelvételre. Ha a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazást használja ezzel az eszközzel, előfordulhat, hogy nem hallja meg a hívásokat, értesítéseket és riasztásokat."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ha a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazást használja ezzel az eszközzel, előfordulhat, hogy nem hallja meg a hívásokat, értesítéseket és riasztásokat."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Engedélyezi a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> számára, hogy hozzáférjen a következőhöz: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Megnyitja a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazást a(z) <xliff:g id="USB_DEVICE">%2$s</xliff:g> kezeléséhez?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Megnyitja a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazást, hogy kezelje a következőt: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEz az alkalmazás nem rendelkezik rögzítési engedéllyel, de ezzel az USB-eszközzel képes a hangfelvételre."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Zárolás feloldva arccal. Nyomja meg a folytatáshoz."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Hitelesítve"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-kód használata"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Minta használata"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ezzel feloldja a hozzáférés letiltását az összes olyan alkalmazás és szolgáltatás esetében, amelyek számára engedélyezte a mikrofon használatát."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ezzel feloldja a hozzáférés letiltását az összes olyan alkalmazás és szolgáltatás esetében, amelyek számára engedélyezte a kamera használatát."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ezzel feloldja a hozzáférés letiltását az összes olyan alkalmazás és szolgáltatás esetében, amelyek számára engedélyezte a kamera vagy a mikrofon használatát."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Más eszköz"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Áttekintés be- és kikapcsolása"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Az Ön által meghatározott ébresztéseken, emlékeztetőkön, eseményeken és hívókon kívül nem fogja Önt más hang vagy rezgés megzavarni. Továbbra is lesz hangjuk azoknak a tartalmaknak, amelyeket Ön elindít, például zenék, videók és játékok."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Töltődokk • A teljes töltöttségig: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Felhasználóváltás"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eltávolítás"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Örülünk, hogy visszatért, vendég!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Folytatja a munkamenetet?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Újrakezdés"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Hozzáadás"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> javasolta"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Az eszköz zárolva van"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"A PIN-kód betűket vagy szimbólumokat tartalmaz"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ellenőrzése"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Helytelen PIN-kód"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"A munkamenet átküldéséhez nyissa meg az alkalmazást."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ismeretlen alkalmazás"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Átküldés leállítása"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
<string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktív alkalmazások"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Leállítás"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Leállítva"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Másolás"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Másolva"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Forrás: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Másolási UI elvetése"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 999a37f69f3e..f9983b759115 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ինքնապտտվող էկրան"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Թույլատրե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին օգտագործել <xliff:g id="USB_DEVICE">%2$s</xliff:g> լրասարքը։"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Թույլատրե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին օգտագործել <xliff:g id="USB_DEVICE">%2$s</xliff:g>ը։\nՀավելվածը ձայնագրելու թույլտվություն չունի, սակայն կկարողանա գրանցել ձայնն այս USB սարքի միջոցով։"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Հասանելի դարձնե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին <xliff:g id="USB_DEVICE">%2$s</xliff:g> սարքը"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Բացե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածը՝ <xliff:g id="USB_DEVICE">%2$s</xliff:g> սարքը կառավարելու համար"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Հավելվածը ձայնագրելու թույլտվություն չունի, սակայն կկարողանա գրանցել ձայնն այս USB սարքի միջոցով։ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածն այս սարքի հետ օգտագործելիս հնարավոր է, որ չլսեք զանգերի, ծանուցումների և զարթուցիչների ձայները։"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածն այս սարքի հետ օգտագործելիս հնարավոր է, որ չլսեք զանգերի, ծանուցումների և զարթուցիչների ձայները։"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Թույլատրե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին օգտագործել <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> լրասարքը։"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Բացե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածը <xliff:g id="USB_DEVICE">%2$s</xliff:g> լրասարքը մշակելու համար։"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Բացե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածը՝ <xliff:g id="USB_DEVICE">%2$s</xliff:g>ն օգտագործելու համար:\nՀավելվածը ձայնագրելու թույլտվություն չունի, սակայն կկարողանա գրանցել ձայնն այս USB սարքի միջոցով։"</string>
@@ -131,7 +135,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="1597899891472340950">"Ապակողպվեց դեմքով։ Սեղմեք՝ շարունակելու համար։"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Նույնականացված է"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Օգտագործել PIN կոդ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Օգտագործել նախշ"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Սա բացում է մուտքը բոլոր հավելվածների և ծառայությունների համար, որոնք ունեն ձեր խոսափողն օգտագործելու թույլտվություն։"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Սա բացում է մուտքը բոլոր հավելվածների և ծառայությունների համար, որոնք ունեն ձեր տեսախցիկն օգտագործելու թույլտվություն։"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Սա բացում է մուտքը բոլոր հավելվածների և ծառայությունների համար, որոնք ունեն ձեր տեսախցիկը կամ խոսափողն օգտագործելու թույլտվություն։"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Այլ սարք"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Միացնել/անջատել համատեսքը"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Ձայները և թրթռոցները չեն անհանգստացնի ձեզ, բացի ձեր կողմից նշված զարթուցիչները, հիշեցումները, միջոցառումների ծանուցումները և զանգերը։ Դուք կլսեք ձեր ընտրածի նվագարկումը, այդ թվում՝ երաժշտություն, տեսանյութեր և խաղեր:"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Լիցքավորում դոկ-կայանի միջոցով • Մնացել է <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր ծրագրերն ու տվյալները կջնջվեն:"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Հեռացնել"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Բարի վերադարձ, հյուր"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Շարունակե՞լ աշխատաշրջանը։"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Վերսկսել"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ավելացնել"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Առաջարկվել է <xliff:g id="APP">%s</xliff:g> հավելվածի կողմից"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Սարքը կողպված է"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN կոդը տառեր և նշաններ է պարունակում"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Ստուգել <xliff:g id="DEVICE">%s</xliff:g> սարքը"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN կոդը սխալ է"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Սահեցրեք մատը՝ ավելին իմանալու համար"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Բեռնման խորհուրդներ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Մեդիա"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Թաքցնե՞լ <xliff:g id="APP_NAME">%1$s</xliff:g>-ի մեդիա աշխատաշրջանի կառավարման տարրը։"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Չհաջողվեց թաքցնել մեդիայի ընթացիկ աշխատաշրջանը։"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Թաքցնել"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Շարունակել"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Այս աշխատաշրջանը հեռարձակելու համար բացեք հավելվածը"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Անհայտ հավելված"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Կանգնեցնել հեռարձակումը"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
<string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ակտիվ հավելվածներ"</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_copy" msgid="770856373439969178">"Պատճենել"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Պատճենվեց"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածից"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Փակել պատճենների միջերեսը"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3fb87acf8bd2..82542145af5c 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Putar layar otomatis"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Izinkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Izinkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAplikasi ini belum diberi izin merekam, tetapi dapat merekam audio melalui perangkat USB ini."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Izinkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk menangani <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Aplikasi ini tidak diberi izin merekam, tetapi dapat merekam audio melalui perangkat USB ini. Menggunakan <xliff:g id="APPLICATION">%1$s</xliff:g> dengan perangkat ini dapat mencegah Anda mendengar panggilan, notifikasi, dan alarm."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Menggunakan <xliff:g id="APPLICATION">%1$s</xliff:g> dengan perangkat ini dapat mencegah Anda mendengar panggilan, notifikasi, dan alarm."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Izinkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk menangani <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk menangani <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAplikasi ini belum diberi izin merekam, tetapi dapat merekam audio melalui perangkat USB ini."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Kunci dibuka dengan wajah Anda. Tekan untuk melanjutkan."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Diautentikasi"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan pola"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan mikrofon."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan kamera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Langkah ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan kamera atau mikrofon."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Perangkat lainnya"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Aktifkan Ringkasan"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Anda tidak akan terganggu oleh suara dan getaran, kecuali dari alarm, pengingat, acara, dan penelepon yang Anda tentukan. Anda akan tetap mendengar apa pun yang telah dipilih untuk diputar, termasuk musik, video, dan game."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengisi Daya dengan Dok • Penuh dalam waktu <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Beralih pengguna"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data di sesi ini akan dihapus."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hapus"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat datang kembali, tamu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Tambahkan"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Disarankan oleh <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Perangkat terkunci"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN berisi huruf atau simbol"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifikasi <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN salah"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Geser untuk melihat selengkapnya"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuat rekomendasi"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Sembunyikan kontrol media ini untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media aktif tidak dapat disembunyikan."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Lanjutkan"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Buka aplikasi untuk mentransmisikan sesi ini."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikasi tidak dikenal"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hentikan transmisi"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
<string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikasi aktif"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Hentikan"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dihentikan"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Salin"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Disalin"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Dari <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Tutup UI salin"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 39fb762c0069..c1225d29c543 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Snúa skjá sjálfkrafa"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Viltu veita <xliff:g id="APPLICATION">%1$s</xliff:g> aðgang að <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Viltu veita <xliff:g id="APPLICATION">%1$s</xliff:g> aðgang að <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nÞetta forrit hefur ekki fengið heimild fyrir upptöku en gæti tekið upp hljóð í gegnum þetta USB-tæki."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Viltu veita <xliff:g id="APPLICATION">%1$s</xliff:g> aðgang að <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Viltu opna <xliff:g id="APPLICATION">%1$s</xliff:g> til að sjá um <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Þetta forrit hefur ekki fengið heimild fyrir upptöku en gæti tekið upp hljóð í gegnum þetta USB-tæki. Notkun <xliff:g id="APPLICATION">%1$s</xliff:g> með þessu tæki getur komið í veg fyrir að símtöl, tilkynningar og viðvaranir heyrist."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Notkun <xliff:g id="APPLICATION">%1$s</xliff:g> með þessu tæki getur komið í veg fyrir að símtöl, tilkynningar og viðvaranir heyrist."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Viltu veita <xliff:g id="APPLICATION">%1$s</xliff:g> aðgang að <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Viltu opna <xliff:g id="APPLICATION">%1$s</xliff:g> til að sjá um <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Viltu opna <xliff:g id="APPLICATION">%1$s</xliff:g> til að vinna með <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nÞetta forrit hefur ekki fengið heimild fyrir upptöku en gæti tekið upp hljóð í gegnum þetta USB-tæki."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Opnað með andlitinu á þér. Ýttu til að halda áfram."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Auðkennt"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Nota PIN-númer"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Nota mynstur"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Þetta veitir öllum forritum og þjónustum aðgang að hljóðnemanum þínum."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Þetta veitir öllum forritum og þjónustum aðgang að myndavélinni þinni."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Þetta veitir öllum forritum og þjónustum aðgang að myndavélinni og hljóðnemanum þínum."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Annað tæki"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Kveikja/slökkva á yfirliti"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Þú verður ekki fyrir truflunum frá hljóðmerkjum og titringi, fyrir utan vekjara, áminningar, viðburði og símtöl frá þeim sem þú leyfir fyrirfram. Þú heyrir áfram í öllu sem þú velur að spila, svo sem tónlist, myndskeiðum og leikjum."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Hleður í dokku • Full hleðsla eftir <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjarlægja"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkominn aftur, gestur!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Viltu halda áfram með lotuna?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Byrja upp á nýtt"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Bæta við"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Tillaga frá <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Tækið er læst"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN inniheldur bókstafi eða tákn"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Staðfesta <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Rangt PIN-númer"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Strjúktu til að sjá meira"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Hleður tillögum"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Margmiðlunarefni"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Fela þessa efnisstýringu fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Ekki tókst að fela opna efnislotu."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fela"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Halda áfram"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Opnaðu forritið til að senda þessa lotu út."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Óþekkt forrit"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stöðva útsendingu"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
<string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Virk forrit"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stöðva"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stöðvað"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Afrita"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Afritað"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Frá <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Loka afriti notendaviðmóts"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index a8d73d026359..58c49053fb2b 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotazione automatica schermo"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vuoi consentire all\'app <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nA questa app non è stata concessa l\'autorizzazione di registrazione, ma l\'app potrebbe acquisire l\'audio tramite questo dispositivo USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Consentire all\'app <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Aprire l\'app <xliff:g id="APPLICATION">%1$s</xliff:g> per gestire <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"All\'app non è stata concessa l\'autorizzazione di registrazione, ma potrebbe comunque acquisire audio tramite questo dispositivo USB. Se usi l\'app <xliff:g id="APPLICATION">%1$s</xliff:g> con questo dispositivo, potresti non riuscire a sentire chiamate, notifiche e sveglie."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Se usi l\'app <xliff:g id="APPLICATION">%1$s</xliff:g> con questo dispositivo, potresti non riuscire a sentire chiamate, notifiche e sveglie."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Vuoi aprire <xliff:g id="APPLICATION">%1$s</xliff:g> per gestire <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Vuoi aprire <xliff:g id="APPLICATION">%1$s</xliff:g> per gestire <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nA questa app non è stata concessa l\'autorizzazione di registrazione, ma l\'app potrebbe acquisire l\'audio tramite questo dispositivo USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Dispositivo sbloccato con il volto. Premi per continuare."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticazione eseguita"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizza PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usa sequenza"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Viene sbloccato l\'accesso per tutti i servizi e le app autorizzati a usare il microfono."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Viene sbloccato l\'accesso per tutti i servizi e le app autorizzati a usare la fotocamera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Viene sbloccato l\'accesso per tutti i servizi e le app autorizzati a usare la fotocamera o il microfono."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Altro dispositivo"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Attiva/disattiva la panoramica"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Non verrai disturbato da suoni e vibrazioni, ad eccezione di sveglie, promemoria, eventi, chiamate da contatti da te specificati ed elementi che hai scelto di continuare a riprodurre, inclusi video, musica e giochi."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • In carica nel dock • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> alla ricarica completa"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambio utente"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Rimuovi"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Ti ridiamo il benvenuto alla sessione Ospite."</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Aggiungi"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggerito da <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloccato"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Il PIN contiene lettere o simboli"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifica <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN errato"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Scorri per vedere altro"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Caricamento dei consigli"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Contenuti multimediali"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Nascondere questo controllo multimediale per <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Imposs. nascondere sessione multimediale corrente."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Nascondi"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Riprendi"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per trasmettere questa sessione devi aprire l\'app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App sconosciuta"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Interrompi trasmissione"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
<string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"App attive"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Interrompi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Interrotta"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copia"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiato"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Da <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignora copia UI"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index fc5d81898f5b..f33f47fe94cb 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"סיבוב אוטומטי של המסך"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"לתת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"‏האם לאפשר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nאפליקציה זו לא קיבלה הרשאה להקליט אך יכולה לתעד אודיו באמצעות מכשיר USB זה."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"האם לתת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"האם לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> כדי לעבוד עם <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"‏לאפליקציה הזו אין הרשאת הקלטה, אבל אפשר להקליט אודיו באמצעות מכשיר ה-USB הזה. השימוש באפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> עם המכשיר הזה יכול למנוע ממך לשמוע שיחות, התראות או שעונים מעוררים."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"השימוש באפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> עם המכשיר הזה יכול למנוע ממך לשמוע שיחות, התראות או שעונים מעוררים."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"האם לתת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"האם לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> כדי לעבוד עם <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"‏לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> לטיפול בהתקן <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nהאפליקציה הזו לא קיבלה הרשאה להקליט אך היא יכולה לתעד אודיו באמצעות התקן ה-USB הזה."</string>
@@ -131,7 +135,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="1597899891472340950">"הנעילה בוטלה עם זיהוי הפנים שלך. יש ללחוץ כדי להמשיך."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"שימוש בקוד אימות"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"שימוש בקו ביטול נעילה"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"הפעולה הזו מבטלת את חסימת הגישה של כל האפליקציות והשירותים שמורשים להשתמש במיקרופון."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"הפעולה הזו מבטלת את חסימת הגישה של כל האפליקציות והשירותים שמורשים להשתמש במצלמה."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"הפעולה הזו מבטלת את חסימת הגישה של כל האפליקציות והשירותים שמורשים להשתמש במצלמה או במיקרופון."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"מכשיר אחר"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"החלפת מצב של מסכים אחרונים"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"כדי לא להפריע לך, המכשיר לא ירטוט ולא ישמיע שום צליל, חוץ מהתראות, תזכורות, אירועים ושיחות ממתקשרים מסוימים לבחירתך. המצב הזה לא ישפיע על צלילים שהם חלק מתוכן שבחרת להפעיל, כמו מוזיקה, סרטונים ומשחקים."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • אביזר העגינה בטעינה • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> עד לסיום"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"החלפת משתמש"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"הסרה"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"שמחים לראותך שוב!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"סשן חדש"</string>
@@ -778,6 +800,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"הוספה"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"הוצע על-ידי <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"המכשיר נעול"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -787,8 +821,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"יש להחליק כדי להציג עוד פריטים"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ההמלצות בטעינה"</string>
<string name="controls_media_title" msgid="1746947284862928133">"מדיה"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"להסתיר את בקר המדיה הזה לאפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"לא ניתן להסתיר את סשן המדיה הנוכחי."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"הסתרה"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"המשך"</string>
@@ -828,6 +861,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‏כדי להעביר (cast) את הסשן הזה, צריך לפתוח את האפליקציה."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"אפליקציה לא ידועה"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"‏עצירת ההעברה (casting)"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"‏מספר Build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"‏מספר ה-Build הועתק ללוח."</string>
<string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string>
@@ -906,7 +953,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"אפליקציות פעילות"</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_copy" msgid="770856373439969178">"העתקה"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"הועתק"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"המקור: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ביטול של העתקת ממשק המשתמש"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 0f07c41f35c0..32e0a1aaeb83 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自動回転画面"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> に <xliff:g id="USB_DEVICE">%2$s</xliff:g> へのアクセスを許可しますか?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> に <xliff:g id="USB_DEVICE">%2$s</xliff:g>へのアクセスを許可しますか?\nこのアプリに録音権限は付与されていませんが、アクセスを許可すると、この USB デバイスから音声を収集できるようになります。"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> に <xliff:g id="USB_DEVICE">%2$s</xliff:g> へのアクセスを許可しますか?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> を起動して <xliff:g id="USB_DEVICE">%2$s</xliff:g> を処理しますか?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"このアプリに録音権限は付与されていませんが、この USB デバイスから音声を収集できるようになります。このデバイスで <xliff:g id="APPLICATION">%1$s</xliff:g> を使用すると、着信音、通知音、アラームが鳴らなくなる可能性があります。"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"このデバイスで <xliff:g id="APPLICATION">%1$s</xliff:g> を使用すると、着信音、通知音、アラームが鳴らなくなる可能性があります。"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> に <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> へのアクセスを許可しますか?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="APPLICATION">%1$s</xliff:g> を起動して <xliff:g id="USB_DEVICE">%2$s</xliff:g> を処理しますか?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> を開いて <xliff:g id="USB_DEVICE">%2$s</xliff:g>を利用しますか?\nこのアプリに録音権限は付与されていませんが、この USB デバイスから音声を収集できるようになります。"</string>
@@ -41,8 +45,8 @@
<string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"このUSBアクセサリを扱うアプリはインストールされていません。詳細: <xliff:g id="URL">%1$s</xliff:g>"</string>
<string name="title_usb_accessory" msgid="1236358027511638648">"USBアクセサリ"</string>
<string name="label_view" msgid="6815442985276363364">"表示"</string>
- <string name="always_use_device" msgid="210535878779644679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> を接続したら常に <xliff:g id="APPLICATION">%1$s</xliff:g> を起動する"</string>
- <string name="always_use_accessory" msgid="1977225429341838444">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> を接続したら常に <xliff:g id="APPLICATION">%1$s</xliff:g> を起動する"</string>
+ <string name="always_use_device" msgid="210535878779644679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> を接続している場合は常に <xliff:g id="APPLICATION">%1$s</xliff:g> を起動する"</string>
+ <string name="always_use_accessory" msgid="1977225429341838444">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> を接続している場合は常に <xliff:g id="APPLICATION">%1$s</xliff:g> を起動する"</string>
<string name="usb_debugging_title" msgid="8274884945238642726">"USB デバッグを許可しますか?"</string>
<string name="usb_debugging_message" msgid="5794616114463921773">"このパソコンのRSAキーのフィンガープリント:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="4003121804294739548">"このパソコンからの USB デバッグを常に許可する"</string>
@@ -131,7 +135,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="1597899891472340950">"顔認識でロックを解除しました。押して続行してください。"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"認証済み"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN を使用"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"パターンを使用"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"マイクの使用が許可されているすべてのアプリとサービスでアクセスのブロックが解除されます。"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"カメラの使用が許可されているすべてのアプリとサービスでアクセスのブロックが解除されます。"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"カメラやマイクの使用が許可されているすべてのアプリとサービスでアクセスのブロックが解除されます。"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"その他のデバイス"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"概要を切り替え"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"アラーム、リマインダー、予定、指定した人からの着信以外の音やバイブレーションに煩わされることはありません。音楽、動画、ゲームなど再生対象として選択したコンテンツは引き続き再生されます。"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ホルダーで充電中 • 完了まで <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ユーザーを切り替える"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"削除"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"おかえりなさい、ゲストさん"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"セッションを続行しますか?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"最初から開始"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"追加"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> によるおすすめ"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"デバイス: ロック状態"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ロック画面にデバイスを表示して操作しますか?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ロック画面に外部デバイスのコントロールを追加できます。\n\nスマートフォンやタブレットのロックを解除しなくても、デバイスアプリによって一部のデバイスを操作できる可能性があります。\n\n設定でいつでも変更できます。"</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ロック画面でデバイスを操作しますか?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"スマートフォンやタブレットのロックを解除しなくても一部のデバイスを操作できます。\n\nこの方法でどのデバイスを操作できるかは、デバイスアプリが判断します。"</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"いいえ"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"はい"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN に英字や記号を含める"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>の確認"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN が間違っています"</string>
@@ -775,8 +803,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"スワイプすると他の構造が表示されます"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"候補を読み込んでいます"</string>
<string name="controls_media_title" msgid="1746947284862928133">"メディア"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> のこのメディア コントロールを非表示にしますか?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"現在のメディア セッションは非表示にできません。"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"非表示"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"再開"</string>
@@ -816,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"このセッションをキャストするには、アプリを開いてください。"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明なアプリ"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"キャストを停止"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
<string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
@@ -892,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"有効なアプリ"</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_copy" msgid="770856373439969178">"コピー"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"完了"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"コピーしました"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> から"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"コピー UI を閉じる"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index e0bf927a2bc2..60198563b0d9 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ეკრანის ავტოროტაცია"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"მიეცეს <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ზე წვდომის უფლება?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"დართავთ <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ზე წვდომის ნებას?\nამ აპს არ აქვს მინიჭებული ჩაწერის ნებართვა, მაგრამ შეუძლია ჩაიწეროს აუდიო ამ USB მოწყობილობის მეშვეობით."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"გსურთ მიანიჭოთ <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ზე წვდომა?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"გსურთ, გახსნათ <xliff:g id="APPLICATION">%1$s</xliff:g>, <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ის გამოსაყენებლად?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ამ აპს არ აქვს მინიჭებული ჩაწერის ნებართვა, მაგრამ შეუძლია ჩაიწეროს აუდიო ამ USB მოწყობილობის მეშვეობით. ამ მოწყობილობაზე <xliff:g id="APPLICATION">%1$s</xliff:g>-ის გამოყენებამ შეიძლება ზარების, შეტყობინებებისა და მაღვიძარის ხმა გამორთოს."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ამ მოწყობილობაზე <xliff:g id="APPLICATION">%1$s</xliff:g>-ის გამოყენებამ შეიძლება ზარების, შეტყობინებებისა და მაღვიძარის ხმა გამორთოს."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"მიეცეს <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>-ზე წვდომის უფლება?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"გსურთ, გახსნათ <xliff:g id="APPLICATION">%1$s</xliff:g>, <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ის გამოსაყენებლად?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"გახსნით <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ის გამოსაყენებლად?\nამ აპს არ აქვს მინიჭებული ჩაწერის ნებართვა, მაგრამ შეუძლია ჩაიწეროს აუდიო ამ USB მოწყობილობის მეშვეობით."</string>
@@ -131,7 +135,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="1597899891472340950">"განბლოკილია თქვენი სახით. დააჭირეთ გასაგრძელებლად."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ავტორიზებულია"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-კოდის გამოყენება"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ნიმუშის გამოყენება"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ამ მოქმედების მეშვეობით განიბლოკება ყველა აპსა და მომსახურებაზე წვდომა, რომელთაც აქვთ თქვენი მიკროფონის გამოყენების უფლება."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ამ მოქმედების მეშვეობით განიბლოკება ყველა აპსა და მომსახურებაზე წვდომა, რომელთაც აქვთ თქვენი კამერის გამოყენების უფლება."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ამ მოქმედების მეშვეობით განიბლოკება ყველა აპსა და მომსახურებაზე წვდომა, რომელთაც აქვთ თქვენი კამერის ან მიკროფონის გამოყენების უფლება."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"სხვა მოწყობილობა"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"მიმოხილვის გადართვა"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"თქვენ მიერ მითითებული მაღვიძარების, შეხსენებების, მოვლენებისა და ზარების გარდა, არავითარი ხმა და ვიბრაცია არ შეგაწუხებთ. თქვენ მაინც შეძლებთ სასურველი კონტენტის, მაგალითად, მუსიკის, ვიდეოებისა და თამაშების აუდიოს მოსმენა."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • დამტენი სამაგრი • დატენამდე დარჩა <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"მომხმარებლის გადართვა"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ამოშლა"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"სტუმარო, გვიხარია, რომ დაბრუნდით!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"გსურთ, თქვენი სესიის გაგრძელება?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ხელახლა დაწყება"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"დამატება"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"შემოთავაზებულია <xliff:g id="APP">%s</xliff:g>-ის მიერ"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"მოწყობილ. ჩაკეტილია"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-კოდი შეიცავს ასოებს ან სიმბოლოებს"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"დაადასტურეთ <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN-კოდი არასწორია"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ამ სესიის ტრანსლირებისთვის გახსენით აპი."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"უცნობი აპი"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ტრანსლირების შეწყვეტა"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
<string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"აქტიური აპები"</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_copy" msgid="770856373439969178">"კოპირება"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"კოპირებულია"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>-დან"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"მომხმარებლის ინტერფეისის ასლის გაუქმება"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index d83420a551c2..545f20aec656 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -34,8 +34,12 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Авто айналатын экран"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына <xliff:g id="USB_DEVICE">%2$s</xliff:g> құрылғысына кіруге рұқсат берілсін бе?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына <xliff:g id="USB_DEVICE">%2$s</xliff:g> құрылғысын пайдалануға рұқсат етілсін бе?\nҚолданбаның жазу рұқсаты жоқ, бірақ осы USB құрылғысы арқылы аудио жаза алады."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына <xliff:g id="USB_DEVICE">%2$s</xliff:g> құрылғысына кіруге рұқсат берілсін бе?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> құрылғысын басқару үшін <xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасы ашылсын ба?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Қолданбаға жазу рұқсаты берілмеді, бірақ ол осы USB құрылғысы арқылы дыбыс жаза алады. Осы құрылғыда <xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасын пайдаланған кезде, қоңырау, хабарландыру және дабыл дыбыстары естілмей қалуы мүмкін."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Осы құрылғыда <xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасын пайдаланған кезде, қоңырау, хабарландыру және дабыл дыбыстары естілмей қалуы мүмкін."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> жабдығына кіруге рұқсат берілсін бе?"</string>
- <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> жабдығын басқару үшін <xliff:g id="APPLICATION">%1$s</xliff:g> ашылсын ба?"</string>
+ <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> басқару үшін <xliff:g id="APPLICATION">%1$s</xliff:g> ашылсын ба?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> құрылғысын пайдалану үшін <xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасын ашу керек пе?\nҚолданбаға жазу рұқсаты берілмеді, бірақ ол осы USB құрылғысы арқылы дыбыс жаза алады."</string>
<string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> жабдығын басқару үшін <xliff:g id="APPLICATION">%1$s</xliff:g> ашылсын ба?"</string>
<string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Орнатылған қолданбалар осы USB жабдығымен жұмыс жасамайды.Жабдықты <xliff:g id="URL">%1$s</xliff:g> ден қараңыз."</string>
@@ -131,7 +135,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="1597899891472340950">"Құлып бетіңіз арқылы ашылды. Жалғастыру үшін басыңыз."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификацияланған"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодын пайдалану"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Өрнекті пайдалану"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Микрофоныңызды пайдалануға рұқсат берілген барлық қолданба мен қызметтің бөгеуі алынады."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Камераңызды пайдалануға рұқсат берілген барлық қолданба мен қызметтің бөгеуі алынады."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Камераңызды немесе микрофоныңызды пайдалануға рұқсат берілген барлық қолданба мен қызметтің бөгеуі алынады."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Басқа құрылғы"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Шолуды қосу/өшіру"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Оятқыш, еске салғыш, іс-шара мен өзіңіз көрсеткен контактілердің қоңырауларынан басқа дыбыстар мен дірілдер мазаламайтын болады. Музыка, бейне және ойын сияқты медиафайлдарды қоссаңыз, оларды естисіз."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Қондыру станциясында зарядталуда • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданбалар мен деректер жойылады."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Алып тастау"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Қош келдіңіз, қонақ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Енгізу"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ұсынған"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Құрылғы құлыпталды."</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN коды әріптерден не таңбалардан құралады."</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> растау"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN коды қате"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Толығырақ ақпарат алу үшін сырғытыңыз."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Жүктеуге қатысты ұсыныстар"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мультимедиа"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін медиамазмұн контроллері жасырылсын ба?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Ағымдағы мультимедиа сеансын жасыру мүмкін емес."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жасыру"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бұл сеансты трансляциялау үшін қолданбаны ашыңыз."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгісіз қолданба"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Трансляцияны тоқтату"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
<string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Белсенді қолданбалар"</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_copy" msgid="770856373439969178">"Көшіру"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Көшірілді"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасынан"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Көшіру интерфейсін жабу"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 9ca2645b2a75..562da727fae4 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"បង្វិល​អេក្រង់​ស្វ័យ​ប្រវត្តិ"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"អនុញ្ញាត <xliff:g id="APPLICATION">%1$s</xliff:g> ឱ្យចូលប្រើ <xliff:g id="USB_DEVICE">%2$s</xliff:g> មែនទេ?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"អនុញ្ញាតឱ្យ <xliff:g id="APPLICATION">%1$s</xliff:g> ចូលប្រើ <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nកម្មវិធីនេះ​មិនទាន់បាន​ទទួលសិទ្ធិ​ថតសំឡេងនៅឡើយទេ ប៉ុន្តែ​អាចថត​សំឡេង​តាមរយៈ​ឧបករណ៍ USB នេះបាន។"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"អនុញ្ញាតឱ្យ <xliff:g id="APPLICATION">%1$s</xliff:g> ចូលប្រើ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ឬ?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"បើក <xliff:g id="APPLICATION">%1$s</xliff:g> ដើម្បីគ្រប់គ្រង <xliff:g id="USB_DEVICE">%2$s</xliff:g> ឬ?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"កម្មវិធីនេះ​មិនទាន់បាន​ទទួលសិទ្ធិ​ថតសំឡេង​នៅឡើយទេ ប៉ុន្តែអាច​ថតសំឡេង​តាមរយៈ​ឧបករណ៍ USB នេះបាន។ ការប្រើ <xliff:g id="APPLICATION">%1$s</xliff:g> ជាមួយឧបករណ៍នេះអាចនឹងបិទសំឡេងការហៅទូរសព្ទ ការជូនដំណឹង និងម៉ោងរោទ៍។"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ការប្រើ <xliff:g id="APPLICATION">%1$s</xliff:g> ជាមួយឧបករណ៍នេះអាចនឹងបិទសំឡេងការហៅទូរសព្ទ ការជូនដំណឹង និងម៉ោងរោទ៍។"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"អនុញ្ញាត <xliff:g id="APPLICATION">%1$s</xliff:g> ឱ្យចូលប្រើ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> មែនទេ?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"បើក <xliff:g id="APPLICATION">%1$s</xliff:g> ដើម្បីគ្រប់គ្រង <xliff:g id="USB_DEVICE">%2$s</xliff:g> មែនទេ?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"បើក <xliff:g id="APPLICATION">%1$s</xliff:g> ដើម្បីគ្រប់គ្រង <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nកម្មវិធីនេះ​មិនទាន់បាន​ទទួលសិទ្ធិ​ថតសំឡេង​នៅឡើយទេ ប៉ុន្តែអាច​ថតសំឡេង​តាមរយៈ​ឧបករណ៍ USB នេះ។"</string>
@@ -131,7 +135,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="1597899891472340950">"បានដោះសោ​ដោយប្រើ​មុខរបស់អ្នក។ ចុច ដើម្បីបន្ត។"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"បាន​ផ្ទៀងផ្ទាត់"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ប្រើកូដ PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ប្រើ​លំនាំ"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ការធ្វើបែបនេះ​នឹងឈប់ទប់ស្កាត់​ការចូលប្រើ​សម្រាប់កម្មវិធី និងសេវាកម្ម​ទាំងអស់ ដែលត្រូវបាន​អនុញ្ញាតឱ្យប្រើ​មីក្រូហ្វូនរបស់អ្នក​។"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ការធ្វើបែបនេះ​នឹងឈប់ទប់ស្កាត់​ការចូលប្រើ​សម្រាប់កម្មវិធី និងសេវាកម្ម​ទាំងអស់ ដែលត្រូវបាន​អនុញ្ញាតឱ្យប្រើ​កាមេរ៉ារបស់អ្នក​។"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ការធ្វើបែបនេះ​នឹងឈប់ទប់ស្កាត់​ការចូលប្រើ​សម្រាប់កម្មវិធី និងសេវាកម្ម​ទាំងអស់ ដែលត្រូវបាន​អនុញ្ញាតឱ្យប្រើ​កាមេរ៉ា ឬមីក្រូហ្វូនរបស់អ្នក​។"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"ឧបករណ៍ផ្សេងទៀត"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"បិទ/បើក​ទិដ្ឋភាពរួម"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"សំឡេង និងរំញ័រនឹងមិន​រំខានដល់អ្នកឡើយ លើកលែងតែម៉ោងរោទ៍ ការរំលឹក ព្រឹត្តិការណ៍ និងអ្នកហៅទូរសព្ទដែលអ្នកបញ្ជាក់ប៉ុណ្ណោះ។ អ្នកនឹងនៅតែឮសំឡេងសកម្មភាពគ្រប់យ៉ាងដែលអ្នកលេងដដែល រួមទាំងតន្រ្តី វីដេអូ និងហ្គេម។"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ឧបករណ៍ភ្ជាប់សាកថ្ម • ពេញក្នុងរយៈពេល <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ទៀត"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរ​អ្នក​ប្រើ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យ​ទាំងអស់​ក្នុង​វគ្គ​នេះ​នឹង​ត្រូវ​លុប។"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ដកចេញ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"សូម​ស្វាគមន៍​ការ​ត្រឡប់​មកវិញ, ភ្ញៀវ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"តើ​អ្នក​ចង់​បន្ត​វគ្គ​របស់​អ្នក​ទេ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើមសាជាថ្មី"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"បញ្ចូល"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"បាន​ណែនាំដោយ <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"បានចាក់សោ​ឧបករណ៍"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"កូដ PIN មាន​អក្សរ ឬនិមិត្តសញ្ញា"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"ផ្ទៀងផ្ទាត់ <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"កូដ PIN មិន​ត្រឹមត្រូវ​"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"អូសដើម្បី​មើលច្រើនទៀត"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"កំពុងផ្ទុក​ការណែនាំ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"មេឌៀ"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"លាក់ផ្ទាំង​គ្រប់គ្រង​មេឌៀនេះសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"មិនអាចលាក់វគ្គមេឌៀបច្ចុប្បន្នបានទេ។"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"លាក់"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"បន្ត"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ដើម្បីភ្ជាប់វគ្គនេះ សូមបើកកម្មវិធី។"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"កម្មវិធី​ដែលមិន​ស្គាល់"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"បញ្ឈប់ការភ្ជាប់"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខ​កំណែបង្កើត"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខ​កំណែបង្កើតទៅឃ្លីបបត។"</string>
<string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"កម្មវិធីសកម្ម"</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_copy" msgid="770856373439969178">"ចម្លង"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"បានចម្លង"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"ពី <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ច្រានចោល UI ចម្លង"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 1a1996856a88..9eaf9aaf0103 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಪ್ರವೇಶಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಅನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?\nಈ ಆ್ಯಪ್‌ಗೆ ರೆಕಾರ್ಡ್ ಅನುಮತಿಯನ್ನು ನೀಡಲಾಗಿಲ್ಲ, ಆದರೆ ಈ USB ಸಾಧನದ ಮೂಲಕ ಆಡಿಯೊವನ್ನು ಸೆರೆಹಿಡಿಯಬಹುದು."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಗೆ ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯುವುದೇ?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ಈ ಆ್ಯಪ್‌ಗೆ ರೆಕಾರ್ಡ್ ಅನುಮತಿಯನ್ನು ನೀಡಲಾಗಿಲ್ಲ, ಆದರೆ ಈ USB ಸಾಧನದ ಮೂಲಕ ಆಡಿಯೊವನ್ನು ಸೆರೆಹಿಡಿಯಬಲ್ಲದು. ಈ ಸಾಧನದ ಮೂಲಕ <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಬಳಸುವುದರಿಂದ ಕರೆಗಳು, ಅಧಿಸೂಚನೆಗಳು ಮತ್ತು ಅಲಾರಾಂಗಳನ್ನು ಕೇಳುವುದನ್ನು ತಡೆಯಬಹುದು."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ಈ ಸಾಧನದ ಮೂಲಕ <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಬಳಸುವುದರಿಂದ ಕರೆಗಳು, ಅಧಿಸೂಚನೆಗಳು ಮತ್ತು ಅಲಾರಾಂಗಳನ್ನು ಕೇಳುವುದನ್ನು ತಡೆಯಬಹುದು."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ಗೆ ಪ್ರವೇಶಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯುವುದೇ?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಅನ್ನು ನಿಯಂತ್ರಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯುವುದೇ?\nಈ ಆ್ಯಪ್‌ಗೆ ರೆಕಾರ್ಡ್ ಅನುಮತಿಯನ್ನು ನೀಡಲಾಗಿಲ್ಲ, ಆದರೆ ಈ USB ಸಾಧನದ ಮೂಲಕ ಆಡಿಯೊವನ್ನು ಸೆರೆಹಿಡಿಯಬಹುದು."</string>
@@ -131,7 +135,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="1597899891472340950">"ನಿಮ್ಮ ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ಪಿನ್ ಬಳಸಿ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ಪ್ಯಾಟರ್ನ್ ಬಳಸಿ"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ಇದು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳಿಗೆ ಹಾಗೂ ಸೇವೆಗಳಿಗೆ ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಬಳಸುವುದಕ್ಕಾಗಿ ಇರುವ ಪ್ರವೇಶದ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ಇದು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳಿಗೆ ಹಾಗೂ ಸೇವೆಗಳಿಗೆ ನಿಮ್ಮ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸುವುದಕ್ಕಾಗಿ ಇರುವ ಪ್ರವೇಶದ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ಇದು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳಿಗೆ ಹಾಗೂ ಸೇವೆಗಳಿಗೆ ನಿಮ್ಮ ಕ್ಯಾಮರಾ ಅಥವಾ ಮೈಕ್ರೋಫೋನ್ ಬಳಸುವುದಕ್ಕಾಗಿ ಇರುವ ಪ್ರವೇಶದ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"ಅನ್ಯ ಸಾಧನ"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ಟಾಗಲ್ ನ ಅವಲೋಕನ"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ಅಲಾರಾಂಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್‌ಗಳು ಹಾಗೂ ನೀವು ಸೂಚಿಸಿರುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ ಬೇರಾವುದೇ ಸದ್ದುಗಳು ಅಥವಾ ವೈಬ್ರೇಶನ್‌ಗಳು ನಿಮಗೆ ತೊಂದರೆ ನೀಡುವುದಿಲ್ಲ. ಹಾಗಿದ್ದರೂ, ನೀವು ಪ್ಲೇ ಮಾಡುವ ಸಂಗೀತ, ವೀಡಿಯೊಗಳು ಮತ್ತು ಆಟಗಳ ಆಡಿಯೊವನ್ನು ನೀವು ಕೇಳಿಸಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ಡಾಕ್ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ದಲ್ಲಿ ಚಾರ್ಜ್ ಪೂರ್ಣಗೊಳ್ಳುತ್ತದೆ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಷನ್‌ನಲ್ಲಿನ ಎಲ್ಲ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ತೆಗೆದುಹಾಕಿ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ಮತ್ತೆ ಸುಸ್ವಾಗತ, ಅತಿಥಿ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್‌ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"ಸೇರಿಸಿ"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್ ಸೂಚಿಸಿದೆ"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"ಸಾಧನ ಲಾಕ್ ಆಗಿದೆ"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ಈ ಸೆಶನ್ ಕಾಸ್ಟ್ ಮಾಡಲು, ಆ್ಯಪ್ ಅನ್ನು ತೆರೆಯಿರಿ."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ಅಪರಿಚಿತ ಆ್ಯಪ್"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
<string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ಸಕ್ರಿಯ ಆ್ಯಪ್‌ಗಳು"</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_copy" msgid="770856373439969178">"ನಕಲಿಸಿ"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ನಕಲಿಸಲಾಗಿದೆ"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ನಿಂದ"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI ನಕಲನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index cc4ecdfabdf5..f7b0a402f215 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"화면 자동 회전"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱이 <xliff:g id="USB_DEVICE">%2$s</xliff:g>에 액세스하도록 허용하시겠습니까?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>에서 <xliff:g id="USB_DEVICE">%2$s</xliff:g>에 액세스하도록 허용하시겠습니까?\n이 앱에는 녹음 권한이 부여되지 않았지만, 이 USB 기기를 통해 오디오를 녹음할 수 있습니다."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱이 <xliff:g id="USB_DEVICE">%2$s</xliff:g>에 액세스하도록 허용하시겠습니까?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱을 열어 <xliff:g id="USB_DEVICE">%2$s</xliff:g>을 처리하시겠습니까?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"이 앱에는 녹음 권한이 부여되지 않았지만, 이 USB 기기를 통해 오디오를 녹음할 수 있습니다. 이 기기와 함께 <xliff:g id="APPLICATION">%1$s</xliff:g> 앱을 사용하면 전화, 알림, 알람 소리가 들리지 않을 수 있습니다."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"이 기기와 함께 <xliff:g id="APPLICATION">%1$s</xliff:g> 앱을 사용하면 전화, 알림, 알람 소리가 들리지 않을 수 있습니다."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱이 <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>에 액세스하도록 허용하시겠습니까?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱을 열어 <xliff:g id="USB_DEVICE">%2$s</xliff:g>을(를) 처리하시겠습니까?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>을(를) 처리하기 위해 <xliff:g id="APPLICATION">%1$s</xliff:g>을(를) 여시겠습니까?\n이 앱에는 녹음 권한이 부여되지 않았지만, 이 USB 기기를 통해 오디오를 녹음할 수 있습니다."</string>
@@ -131,7 +135,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="1597899891472340950">"얼굴 인식으로 잠금 해제했습니다. 계속하려면 누르세요."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"인증됨"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN 사용"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"패턴 사용"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"마이크를 사용할 수 있는 모든 앱 및 서비스에 대해 액세스가 차단 해제됩니다."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"카메라를 사용할 수 있는 모든 앱 및 서비스에 대해 액세스가 차단 해제됩니다."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"카메라 또는 마이크를 사용할 수 있는 모든 앱 및 서비스에 대해 액세스가 차단 해제됩니다."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"기타 기기"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"최근 사용 버튼 전환"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"알람, 알림, 일정 및 지정한 발신자로부터 받은 전화를 제외한 소리와 진동을 끕니다. 음악, 동영상, 게임 등 재생하도록 선택한 소리는 정상적으로 들립니다."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 충전 거치대 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> 후 충전 완료"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"사용자 전환"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"삭제"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"게스트 세션 진행"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"세션을 계속 진행하시겠습니까?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"다시 시작"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"추가"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g>에서 제안"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"기기 잠김"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN에 문자나 기호가 포함됨"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> 확인"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"잘못된 PIN"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"자세히 보려면 스와이프하세요."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"추천 제어 기능 로드 중"</string>
<string name="controls_media_title" msgid="1746947284862928133">"미디어"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 이 미디어 컨트롤 숨기기"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"현재 미디어 세션은 숨길 수 없습니다."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"숨기기"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"세션을 전송하려면 앱을 열어 주세요"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"알 수 없는 앱"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"전송 중지"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
<string name="basic_status" msgid="2315371112182658176">"대화 열기"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"활성 상태의 앱"</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_copy" msgid="770856373439969178">"복사"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"복사됨"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"복사한 위치: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI 복사 닫기"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index f2807c2b2bab..f44c69e0bf77 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -34,14 +34,18 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Экранды авто буруу"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдоно берсинби?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу үчүн <xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүнө мүмкүнчүлүк алууга уруксат бересизби?\nБул колдонмонун жаздырууга уруксаты жок, бирок бул USB түзмөгү аркылуу аудиону жаздыра алат."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_DEVICE">%2$s</xliff:g> кабелин колдоно берсинби?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдонуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун ачасызбы?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Бул колдонмонун жаздырууга уруксаты жок, бирок бул USB түзмөгү аркылуу аудиону жаздыра алат. <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун бул түзмөктө иштетсеңиз, чалууларды, билдирмелерди жана ойготкучтарды уга албай калышыңыз мүмкүн."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун бул түзмөктө иштетсеңиз, чалууларды, билдирмелерди жана ойготкучтарды уга албай калышыңыз мүмкүн."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> кабелин колдоно берсинби?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүнө туташуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу ачылсынбы?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> кабелине туташуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> ачылсынбы?\nБул колдонмонун жаздырууга уруксаты жок, бирок бул USB түзмөгү аркылуу аудиону жаздыра алат."</string>
- <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> кабелине туташуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу ачылсынбы?"</string>
+ <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> колдонуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун ачасызбы?"</string>
<string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Эч бир орнотулган колдонмо USB аксессуар м-н иштебейт. Кенен маалыматтар: <xliff:g id="URL">%1$s</xliff:g>"</string>
<string name="title_usb_accessory" msgid="1236358027511638648">"USB шайманы"</string>
<string name="label_view" msgid="6815442985276363364">"Карап көрүү"</string>
- <string name="always_use_device" msgid="210535878779644679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> туташып турганда, <xliff:g id="APPLICATION">%1$s</xliff:g> ар дайым ачык болун"</string>
+ <string name="always_use_device" msgid="210535878779644679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> туташып турганда, <xliff:g id="APPLICATION">%1$s</xliff:g> ар дайым ачык болсун"</string>
<string name="always_use_accessory" msgid="1977225429341838444">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> туташып турганда, <xliff:g id="APPLICATION">%1$s</xliff:g> ар дайым ачык болсун"</string>
<string name="usb_debugging_title" msgid="8274884945238642726">"USB аркылуу жөндөөгө уруксат берилсинби?"</string>
<string name="usb_debugging_message" msgid="5794616114463921773">"Компүтердин RSA ачкычынын контролдук суммасы:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
@@ -131,7 +135,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="1597899891472340950">"Жүзүңүз менен ачылды. Улантуу үчүн басыңыз."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аныктыгы текшерилди"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодду колдонуу"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Графикалык ачкычты колдонуу"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Микрофонуңузду колдонууга уруксат алган бардык колдонмолор менен кызматтар бөгөттөн чыгат."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Камераны колдонууга уруксат алган бардык колдонмолор менен кызматтар бөгөттөн чыгат."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Камераңызды же микрофонуңузду колдонууга уруксат алган бардык колдонмолор менен кызматтар бөгөттөн чыгат."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Башка түзмөк"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Назар режимин өчүрүү/күйгүзүү"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Ойготкучтардан, эскертүүлөрдөн, жылнаамадагы иш-чараларды эстеткичтерден жана белгиленген байланыштардын чалууларынан тышкары башка үндөр жана дирилдөөлөр тынчыңызды албайт. Бирок ойнотулуп жаткан музыканы, видеолорду жана оюндарды мурдагыдай эле уга бересиз."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Кубаттоо догу • Толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> калды"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана маалыматтар өчүрүлөт."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Өчүрүү"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Кайтып келишиңиз менен!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Кошуу"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> сунуштайт"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Түзмөк кулпуланды"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN код тамгалардан же символдордон турат"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> түзмөгүн ырастаңыз"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN код туура эмес"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бул сеансты тышкы экранга чыгаруу үчүн колдонмону ачыңыз."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгисиз колдонмо"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Тышкы экранга чыгарууну токтотуу"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
<string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Жигердүү колдонмолор"</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_copy" msgid="770856373439969178">"Көчүрүү"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Көчүрүлдү"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосунан"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Көчүрмөнү жабуу интерфейси"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index ffdb491961be..3a99a2c5b5d3 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"ອະນຸຍາດໃຫ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ເຂົ້າເຖິງ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ໄດ້ບໍ?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"ອະນຸຍາດໃຫ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ເຂົ້າເຖິງ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ໄດ້ບໍ?\nແອັບນີ້ບໍ່ໄດ້ຮັບອະນຸາດໃຫ້ບັນທຶກໄດ້ແຕ່ສາມາດບັນທຶກສຽງໄດ້ຜ່ານອຸປະກອນ USB ນີ້."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"ອະນຸຍາດໃຫ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ເຂົ້າເຖິງ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ໄດ້ບໍ?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"ເປີດ <xliff:g id="APPLICATION">%1$s</xliff:g> ເພື່ອຈັດການ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ບໍ?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ແອັບນີ້ບໍ່ໄດ້ຮັບການອະນຸຍາດໃນການບັນທຶກ ແຕ່ສາມາດບັນທຶກສຽງໄດ້ຜ່ານອຸປະກອນ USB ນີ້ໄດ້. ການໃຊ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ກັບອຸປະກອນນີ້ອາດປ້ອງກັນບໍ່ໃຫ້ໄດ້ຍິນສຽງໂທລະສັບ, ການແຈ້ງເຕືອນ ແລະ ໂມງປຸກ."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ການໃຊ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ກັບອຸປະກອນນີ້ອາດປ້ອງກັນບໍ່ໃຫ້ໄດ້ຍິນສຽງໂທລະສັບ, ການແຈ້ງເຕືອນ ແລະ ໂມງປຸກ."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"ອະນຸຍາດໃຫ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ເຂົ້າເຖິງ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ໄດ້ບໍ?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"ເປີດ <xliff:g id="APPLICATION">%1$s</xliff:g> ເພື່ອໃຊ້ກັບ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ບໍ?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"ເປີດ <xliff:g id="APPLICATION">%1$s</xliff:g> ເພື່ອໃຊ້ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ບໍ?\nແອັບນີ້ຍັງບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ບັນທຶກເທື່ອ ແຕ່ສາມາດບັນທຶກສຽງຜ່ານອຸປະກອນ USB ນີ້ໄດ້."</string>
@@ -131,7 +135,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="1597899891472340950">"ປົດລັອກດ້ວຍໜ້າຂອງທ່ານແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ໃຊ້ PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ໃຊ້ຮູບແບບ"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ນີ້ຈະຍົກເລີກການບລັອກການເຂົ້າເຖິງແອັບ ແລະ ບໍລິການທັງໝົດທີ່ອະນຸຍາດໃຫ້ໃຊ້ໄມໂຄຣໂຟນຂອງທ່ານ."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ນີ້ຈະຍົກເລີກການບລັອກການເຂົ້າເຖິງແອັບ ແລະ ບໍລິການທັງໝົດທີ່ອະນຸຍາດໃຫ້ໃຊ້ກ້ອງຖ່າຍຮູບຂອງທ່ານ."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ນີ້ຈະປົດບລັອກການເຂົ້າເຖິງແອັບ ແລະ ບໍລິການທັງໝົດທີ່ອະນຸຍາດໃຫ້ໃຊ້ກ້ອງຖ່າຍຮູບ ຫຼື ໄມໂຄຣໂຟນຂອງທ່ານ."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"ອຸປະກອນອື່ນໆ"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ສະຫຼັບພາບຮວມ"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ທ່ານຈະບໍ່ໄດ້ຮັບການລົບກວນຈາກສຽງ ແລະ ການສັ່ນເຕືອນ, ຍົກເວັ້ນໃນເວລາໂມງປຸກດັງ, ມີການແຈ້ງເຕືອນ ຫຼື ມີສາຍໂທເຂົ້າຈາກຜູ້ໂທທີ່ທ່ານລະບຸໄວ້. ທ່ານອາດຍັງຄົງໄດ້ຍິນຫາກທ່ານເລືອກຫຼິ້ນເພງ, ວິດີໂອ ແລະ ເກມ."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ກຳລັງສາກໄຟຜ່ານດັອກ • ຈະເຕັມໃນອີກ <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ສະຫຼັບຜູ້ໃຊ້"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯ​ແລະ​ຂໍ້​ມູນ​ທັງ​ໝົດ​ໃນ​ເຊດ​ຊັນ​ນີ້​ຈະ​ຖືກ​ລຶບ​ອອກ."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ລຶບ​"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ຍິນ​ດີ​ຕ້ອນ​ຮັບ​ກັບ​ມາ, ຜູ້ຢ້ຽມຢາມ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ທ່ານ​ຕ້ອງ​ການ​ສືບ​ຕໍ່​ເຊດ​ຊັນ​ຂອງ​ທ່ານບໍ່?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ເລີ່ມຕົ້ນໃຫມ່"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"ເພີ່ມ"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"ແນະນຳໂດຍ <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"ອຸປະກອນຖືກລັອກໄວ້"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ປະກອບມີຕົວອັກສອນ ຫຼື ສັນຍາລັກ"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"ຢັ້ງຢືນ <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN ບໍ່ຖືກຕ້ອງ"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ປັດເພື່ອເບິ່ງເພີ່ມເຕີມ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ກຳລັງໂຫຼດຄຳແນະນຳ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ມີເດຍ"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"ເຊື່ອງຕົວຄວບຄຸມມີເດຍນີ້ສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"ບໍ່ສາມາດເຊື່ອງເຊດຊັນມີເດຍປັດຈຸບັນໄດ້."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"ເຊື່ອງ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ສືບຕໍ່"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ເພື່ອສົ່ງສັນຍານເຊດຊັນນີ້, ກະລຸນາເປີດແອັບ."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ແອັບທີ່ບໍ່ຮູ້ຈັກ"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ຢຸດການສົ່ງສັນຍານ"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
<string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ແອັບທີ່ນຳໃຊ້ຢູ່"</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_copy" msgid="770856373439969178">"ສຳເນົາ"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ສຳເນົາແລ້ວ"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"ຈາກ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ປິດການສຳເນົາສ່ວນຕິດຕໍ່ຜູ້ໃຊ້ໄວ້"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 99395909926d..1293105e535a 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatiškai sukti ekraną"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Leisti „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Leisti „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?\nŠiai programai nebuvo suteiktas leidimas įrašyti, bet ji gali užfiksuoti garsą per šį USB įrenginį."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Leisti „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Atidaryti „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kad būtų galima tvarkyti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Šiai programai nebuvo suteiktas leidimas įrašyti, bet ji gali užfiksuoti garsą per šį USB įrenginį. Naudodami „<xliff:g id="APPLICATION">%1$s</xliff:g>“ šiuo įrenginiu galite negirdėti skambučių, pranešimų ir signalų."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Naudodami „<xliff:g id="APPLICATION">%1$s</xliff:g>“ šiuo įrenginiu galite negirdėti skambučių, pranešimų ir signalų."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Leisti „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti įrenginį (<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>)?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Atidaryti „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kad būtų galima tvarkyti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Atidaryti programą „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kad ji galėtų tvarkyti „<xliff:g id="USB_DEVICE">%2$s</xliff:g>“?\nŠiai programai nebuvo suteiktas leidimas įrašyti, bet ji gali užfiksuoti garsą per šį USB įrenginį."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Atrakinta pagal veidą. Paspauskite, jei norite tęsti."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikuota"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Naudoti PIN kodą"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Naudoti atrakinimo piešinį"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Tai atlikus visų programų ir paslaugų prieigos blokavimas panaikinamas ir joms leidžiama naudoti mikrofoną."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Tai atlikus visų programų ir paslaugų prieigos blokavimas panaikinamas ir joms leidžiama naudoti fotoaparatą."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Tai atlikus visų programų ir paslaugų prieigos blokavimas panaikinamas ir joms leidžiama naudoti fotoaparatą ar mikrofoną."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Kitas įrenginys"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Perjungti apžvalgą"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Jūsų netrikdys garsai ir vibravimas, išskyrus nurodytų signalų, priminimų, įvykių ir skambintojų garsus. Vis tiek girdėsite viską, ką pasirinksite leisti, įskaitant muziką, vaizdo įrašus ir žaidimus."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Įkraunama doke • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> iki visiško įkrovimo"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Perjungti naudotoją"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Pašalinti"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Sveiki sugrįžę, svety!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Ar norite tęsti sesiją?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Pradėti iš naujo"</string>
@@ -778,6 +800,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Pridėti"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Siūlo „<xliff:g id="APP">%s</xliff:g>“"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Įrenginys užrakintas"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN kodą sudaro raidės arba simboliai"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> patvirtinimas"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Netinkamas PIN kodas"</string>
@@ -787,8 +821,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Perbraukite, kad peržiūrėtumėte daugiau"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Įkeliamos rekomendacijos"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medija"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Slėpti šį programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ medijos valdiklį?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Dabartinio medijos seanso negalima paslėpti."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Slėpti"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tęsti"</string>
@@ -828,6 +861,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jei norite perduoti šį seansą, atidarykite programą."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nežinoma programa"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sustabdyti perdavimą"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
<string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string>
@@ -906,7 +953,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktyvios programos"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Sustabdyti"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Sustabdyta"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopijuoti"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nukopijuota"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Iš „<xliff:g id="APPNAME">%1$s</xliff:g>“"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Atsisakyti kopijavimo NS"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 3ac9579536f3..2147bee0b1bf 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automātiska ekrāna pagriešana"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vai atļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šai ierīcei: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vai atļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt ierīcei “<xliff:g id="USB_DEVICE">%2$s</xliff:g>”?\nŠai lietotnei nav piešķirta ierakstīšanas atļauja, taču tā varētu tvert audio, izmantojot šo USB ierīci."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Vai atļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šai ierīcei: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Vai atvērt lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, lai izmantotu šo ierīci: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Šai lietotnei nav piešķirta ierakstīšanas atļauja, taču tā varētu tvert audio, izmantojot šo USB ierīci. Ja izmantosiet lietotni <xliff:g id="APPLICATION">%1$s</xliff:g> kopā ar šo ierīci, varbūt nedzirdēsiet zvanus, paziņojumus un brīdinājumus."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ja izmantosiet lietotni <xliff:g id="APPLICATION">%1$s</xliff:g> kopā ar šo ierīci, varbūt nedzirdēsiet zvanus, paziņojumus un brīdinājumus."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Vai atļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šim piederumam: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Vai atvērt lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, lai izmantotu šo ierīci: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Vai vēlaties atvērt lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, lai pārvaldītu ierīci <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nŠai lietotnei nav piešķirta ierakstīšanas atļauja, taču tā varētu tvert audio, izmantojot šo USB ierīci."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Sākta autorizācija pēc sejas. Nospiediet, lai turpinātu."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikācija veikta"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Izmantot PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Izmantot kombināciju"</string>
@@ -289,6 +294,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Visas lietotnes un pakalpojumi, kurām ir atļauts izmantot mikrofonu, varēs tam piekļūt."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Visas lietotnes un pakalpojumi, kuriem ir atļauts izmantot kameru, varēs tai piekļūt."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Visas lietotnes un pakalpojumi, kuriem ir atļauts izmantot kameru vai mikrofonu, varēs tiem piekļūt."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Cita ierīce"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Pārskata pārslēgšana"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Jūs netraucēs skaņas un vibrācija, izņemot signālus, atgādinājumus, pasākumus un zvanītājus, ko būsiet norādījis. Jūs joprojām dzirdēsiet atskaņošanai izvēlētos vienumus, tostarp mūziku, videoklipus un spēles."</string>
@@ -322,7 +345,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Notiek uzlāde dokā • Līdz pilnai uzlādei atlicis: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mainīt lietotāju"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Noņemt"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Laipni lūdzam atpakaļ, viesi!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vai vēlaties turpināt savu sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Sākt no sākuma"</string>
@@ -772,6 +794,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Pievienot"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Ieteica: <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Ierīce ir bloķēta"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ietver burtus vai simbolus."</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifikācija: <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Nepareizs PIN"</string>
@@ -781,8 +815,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Velciet, lai skatītu citus vienumus"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Notiek ieteikumu ielāde"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multivide"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Vai paslēpt šo lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> multivides vadīklu?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Pašreizējo multivides sesiju nevar paslēpt."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Paslēpt"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Atsākt"</string>
@@ -822,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Lai apraidītu šo sesiju, lūdzu, atveriet lietotni."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nezināma lietotne"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Apturēt apraidi"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
<string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string>
@@ -899,7 +946,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktīvās lietotnes"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Apturēt"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Apturēta"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopēt"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nokopēts"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"No lietotnes <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Noraidīt ar kopēšanu saistīto lietotāja saskarnes elementu"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 289fcdf99031..e9dcdaca2a87 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Автоматско ротирање на екранот"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Ќе дозволите <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапува до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Дали дозволувате <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапи до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nНа апликацијава не ѝ е доделена дозвола за снимање, но може да снима аудио преку овој USB-уред."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Ќе дозволите <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапува до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Да се отвори <xliff:g id="APPLICATION">%1$s</xliff:g> за да управува со <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"На апликацијава не ѝ е доделена дозвола за снимање, но може да снима аудио преку овој USB-уред. Ако ја користите <xliff:g id="APPLICATION">%1$s</xliff:g> со уредов, може да се спречи слушањето повици, известувања и аларми."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ако ја користите <xliff:g id="APPLICATION">%1$s</xliff:g> со уредов, може да се спречи слушањето повици, известувања и аларми."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Ќе дозволите <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапува до <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Да се отвори <xliff:g id="APPLICATION">%1$s</xliff:g> за да управува со <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Да се отвори ли <xliff:g id="APPLICATION">%1$s</xliff:g> за да се управува со <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nНа апликацијава не ѝ е доделена дозвола за снимање, но може да снима аудио преку овој USB-уред."</string>
@@ -131,7 +135,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="1597899891472340950">"Отклучен со вашето лице. Притиснете за да продолжите."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Проверена"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користи PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користи шема"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ова ќе го одблокира пристапот за сите апликации и услуги на кои им е дозволено користење на микрофонот."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ова ќе го одблокира пристапот за сите апликации и услуги на кои им е дозволено користење на камерата."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ова ќе го одблокира пристапот за сите апликации и услуги на кои им е дозволено користење на камерата или микрофонот."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Друг уред"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Вклучи/исклучи преглед"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Нема да ве вознемируваат звуци и вибрации, освен од аларми, потсетници, настани и повикувачи што ќе ги наведете. Сѐ уште ќе слушате сѐ што ќе изберете да пуштите, како музика, видеа и игри."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Се полни на док • Полн за <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Промени го корисникот"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијата ќе се избришат."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Отстрани"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Добре дојде пак, гостине!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Дали сакате да продолжите со сесијата?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни одново"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Додај"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Предложено од <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Уредот е заклучен"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-кодот содржи букви или симболи"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Потврдете го <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Погрешен PIN"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да ја емитувате сесијава, отворете ја апликацијата."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Сопри со емитување"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
<string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни апликации"</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_copy" msgid="770856373439969178">"Копирај"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Од <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Отфрли го корисничкиот интерфејс за копирање"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index c08c1bc3e189..85a5eca27abb 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"സ്‌ക്രീൻ സ്വയമേ തിരിയുക"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ആക്‌സസ് ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g>-നെ അനുവദിക്കണോ?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ആക്‌സസ് ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?\nഈ ആപ്പിന് റെക്കോർഡ് അനുമതി നൽകിയിട്ടില്ല, എന്നാൽ ഈ USB ഉപകരണത്തിലൂടെ ഓഡിയോ ക്യാപ്‌ചർ ചെയ്യാനാവും."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ആക്‌സസ് ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> കൈകാര്യം ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g> തുറക്കണോ?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ഈ ആപ്പിന് റെക്കോർഡ് അനുമതി നൽകിയിട്ടില്ല, എന്നാൽ ഈ USB ഉപകരണത്തിലൂടെ ഓഡിയോ ക്യാപ്‌ചർ ചെയ്യാനാവും. ഈ ഉപകരണത്തിൽ <xliff:g id="APPLICATION">%1$s</xliff:g> ഉപയോഗിക്കുന്നത് കോളുകളും അറിയിപ്പുകളും അലാറങ്ങളും കേൾക്കുന്നതിൽ നിന്ന് തടഞ്ഞേക്കാം."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ഈ ഉപകരണത്തിൽ <xliff:g id="APPLICATION">%1$s</xliff:g> ഉപയോഗിക്കുന്നത് കോളുകളും അറിയിപ്പുകളും അലാറങ്ങളും കേൾക്കുന്നതിൽ നിന്ന് തടഞ്ഞേക്കാം."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ആക്‌സസ് ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g>-നെ അനുവദിക്കണോ?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> കൈകാര്യം ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g> തുറക്കണോ?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> തുറന്ന് <xliff:g id="USB_DEVICE">%2$s</xliff:g> കൈകാര്യം ചെയ്യണോ?\nഈ ആപ്പിന് റെക്കോർഡ് അനുമതി നൽകിയിട്ടില്ല, എന്നാൽ ഈ USB ഉപകരണത്തിലൂടെ ഓഡിയോ ക്യാപ്‌ചർ ചെയ്യാനാവും."</string>
@@ -131,7 +135,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="1597899891472340950">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അമർത്തുക."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"പരിശോധിച്ചുറപ്പിച്ചു"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"പിൻ ഉപയോഗിക്കുക"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"പാറ്റേൺ ഉപയോഗിക്കുക"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"നിങ്ങളുടെ മൈക്രോഫോൺ ഉപയോഗിക്കാൻ അനുവദിച്ചിരിക്കുന്ന എല്ലാ ആപ്പുകൾക്കും സേവനങ്ങൾക്കുമുള്ള ആക്‌സസ് ഇത് അൺബ്ലോക്ക് ചെയ്യുന്നു."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"നിങ്ങളുടെ ക്യാമറ ഉപയോഗിക്കാൻ അനുവദിച്ചിരിക്കുന്ന എല്ലാ ആപ്പുകൾക്കും സേവനങ്ങൾക്കുമുള്ള ആക്‌സസ് ഇത് അൺബ്ലോക്ക് ചെയ്യുന്നു."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"നിങ്ങളുടെ ക്യാമറയോ മൈക്രോഫോണോ ഉപയോഗിക്കാൻ അനുവദിച്ചിരിക്കുന്ന എല്ലാ ആപ്പുകൾക്കും സേവനങ്ങൾക്കുമുള്ള ആക്‌സസ് ഇത് അൺബ്ലോക്ക് ചെയ്യുന്നു."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"മറ്റ് ഉപകരണം"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"അവലോകനം മാറ്റുക"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"നിങ്ങൾ സജ്ജീകരിച്ച അലാറങ്ങൾ, റിമൈൻഡറുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവയിൽ നിന്നുള്ള ശബ്‌ദങ്ങളും വൈബ്രേഷനുകളുമൊഴികെ മറ്റൊന്നും നിങ്ങളെ ശല്യപ്പെടുത്തുകയില്ല. സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയുൾപ്പെടെ പ്ലേ ചെയ്യുന്നതെന്തും നിങ്ങൾക്ക് ‌തുടർന്നും കേൾക്കാൻ കഴിയും."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ചാർജിംഗ് ഡോക്ക് • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-ൽ പൂർത്തിയാകും"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ഉപയോക്താവ് മാറുക"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"നീക്കംചെയ്യുക"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"അതിഥി, വീണ്ടും സ്വാഗതം!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"നിങ്ങളുടെ സെഷൻ തുടരണോ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"പുനരാംരംഭിക്കുക"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"ചേർക്കുക"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> നിർദ്ദേശിച്ചത്"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"ഉപകരണം ലോക്ക് ചെയ്തു"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ലോക്ക് സ്‌ക്രീനിൽ നിന്ന് ഉപകരണങ്ങൾ കാണിക്കുകയും നിയന്ത്രിക്കുകയും ചെയ്യണോ?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"നിങ്ങളുടെ ബാഹ്യ ഉപകരണങ്ങൾക്കുള്ള നിയന്ത്രണങ്ങൾ ലോക്ക് സ്‌ക്രീനിലേക്ക് ചേർക്കാനാകും.\n\nനിങ്ങളുടെ ഫോണോ ടാബ്‌ലെറ്റോ അൺലോക്ക് ചെയ്യാതെ ചില ഉപകരണങ്ങൾ നിയന്ത്രിക്കാൻ നിങ്ങളുടെ ഉപകരണ ആപ്പ് അനുവദിച്ചേക്കും.\n\nനിങ്ങൾക്ക് ക്രമീകരണത്തിൽ ഏതുസമയത്തും മാറ്റങ്ങൾ വരുത്താം."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ലോക്ക് സ്‌ക്രീനിൽ നിന്ന് ഉപകരണങ്ങൾ നിയന്ത്രിക്കണോ?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"നിങ്ങളുടെ ഫോണോ ടാബ്‌ലെറ്റോ അൺലോക്ക് ചെയ്യാതെ ചില ഉപകരണങ്ങൾ നിയന്ത്രിക്കാം.\n\nഏതൊക്കെ ഉപകരണങ്ങൾ ഈ രീതിയിൽ നിയന്ത്രിക്കാൻ കഴിയുമെന്ന് നിങ്ങളുടെ ഉപകരണ ആപ്പ് നിർണ്ണയിക്കുന്നു."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"വേണ്ട, നന്ദി"</string>
+ <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>
@@ -775,8 +803,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"കൂടുതൽ കാണാൻ സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"നിർദ്ദേശങ്ങൾ ലോഡ് ചെയ്യുന്നു"</string>
<string name="controls_media_title" msgid="1746947284862928133">"മീഡിയ"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ആപ്പിനുള്ള ഈ മീഡിയാ കൺട്രോൾ മറയ്ക്കണോ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"നിലവിലെ മീഡിയ സെഷൻ മറയ്ക്കാനാകില്ല."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"മറയ്‌ക്കുക"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"പുനരാരംഭിക്കുക"</string>
@@ -816,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ഈ സെഷൻ കാസ്റ്റ് ചെയ്യാൻ, ആപ്പ് തുറക്കുക."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"അജ്ഞാതമായ ആപ്പ്"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
<string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string>
@@ -892,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"സജീവമായ ആപ്പുകൾ"</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_copy" msgid="770856373439969178">"പകർത്തുക"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"പൂർത്തിയായി"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"പകർത്തി"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്നതിൽ നിന്ന്"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"പകർപ്പ് UI ഡിസ്‌മിസ് ചെയ്യുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 30a45ed8998f..33e859da5acd 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Дэлгэцийг автоматаар эргүүлэх"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г <xliff:g id="USB_DEVICE">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>-д <xliff:g id="USB_DEVICE">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?\nЭнэ аппад бичих зөвшөөрөл олгогдоогүй ч USB төхөөрөмжөөр дамжуулан аудио бичиж чадсан."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g>-д <xliff:g id="USB_DEVICE">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>-г зохицуулахын тулд <xliff:g id="APPLICATION">%1$s</xliff:g>-г нээх үү?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Энэ аппад бичих зөвшөөрөл олгоогүй хэдий ч энэ USB төхөөрөмжөөр дамжуулан аудио бичиж болно. <xliff:g id="APPLICATION">%1$s</xliff:g>-г энэ төхөөрөмжтэй ашигласнаар дуудлага, мэдэгдэл болон сэрүүлэг сонсохоос сэргийлж магадгүй."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г энэ төхөөрөмжтэй ашигласнаар дуудлага, мэдэгдэл болон сэрүүлэг сонсохоос сэргийлж магадгүй."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>-г зохицуулахын тулд <xliff:g id="APPLICATION">%1$s</xliff:g>-г нээх үү?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>-г зохицуулахын тулд <xliff:g id="APPLICATION">%1$s</xliff:g>-г нээх үү?\nЭнэ апликейшнд бичих зөвшөөрөл олгогдоогүй ч энэ USB төхөөрөмжөөр дамжуулан аудио бичиж чадсан."</string>
@@ -131,7 +135,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="1597899891472340950">"Таны царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Баталгаажуулагдсан"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ПИН ашиглах"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Хээ ашиглах"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Энэ нь таны микрофоныг ашиглах зөвшөөрөлтэй бүх апп болон үйлчилгээний хандалтыг блокоос гаргана."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Энэ нь таны камерыг ашиглах зөвшөөрөлтэй бүх апп болон үйлчилгээний хандалтыг блокоос гаргана."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Энэ нь таны камер эсвэл микрофоныг ашиглах зөвшөөрөлтэй бүх апп болон үйлчилгээний хандалтыг блокоос гаргана."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Бусад төхөөрөмж"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Тоймыг асаах/унтраах"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Танд сэрүүлэг, сануулга, арга хэмжээ, таны сонгосон дуудлага илгээгчээс бусад дуу, чичиргээ саад болохгүй. Та хөгжим, видео, тоглоом зэрэг тоглуулахыг хүссэн бүх зүйлээ сонсох боломжтой хэвээр байна."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Цэнэглэх холбогч • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-н дараа дүүрнэ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Хэрэглэгчийг сэлгэх"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Хасах"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Эргэн тавтай морилно уу!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Та үргэлжлүүлэхийг хүсэж байна уу?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Дахин эхлүүлэх"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Нэмэх"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g>-н санал болгосон"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Төхөөрөмжийг түгжсэн"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Түгжигдсэн дэлгэцээс төхөөрөмжүүдийг харуулж, хянах уу?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Та түгжигдсэн дэлгэцэд гадаад төхөөрөмжүүдийнхээ хяналтыг нэмэх боломжтой.\n\nТаны төхөөрөмжийн апп танд утас эсвэл таблетынхаа түгжээг тайлахгүйгээр зарим төхөөрөмжийг хянах боломжийг олгож магадгүй.\n\nТа хүссэн үедээ Тохиргоонд өөрчлөлт хийж болно."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Төхөөрөмжүүдийг түгжигдсэн дэлгэцээс хянах уу?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Та утас эсвэл таблетынхаа түгжээг тайлахгүйгээр зарим төхөөрөмжийг хянах боломжтой.\n\nТаны төхөөрөмжийн апп энэ аргаар ямар төхөөрөмжүүдийг хянах боломжтойг тодорхойлно."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Үгүй, баярлалаа"</string>
+ <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>
@@ -815,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Энэ үйл явдлыг дамжуулахын тулд аппыг нээнэ үү."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Үл мэдэгдэх апп"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Дамжуулахыг зогсоох"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string>
<string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string>
@@ -891,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Идэвхтэй аппууд"</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_copy" msgid="770856373439969178">"Хуулах"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Болсон"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Хууллаа"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>-с"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Хуулах UI-г хаах"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 6352e2117354..6acecee64e08 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ऑटो-रोटेट स्क्रीन"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची का?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची का?\nया अ‍ॅपला रेकॉर्ड करण्याची परवानगी दिलेली नाही पण या USB डिव्हाइसद्वारे ऑडिओ कॅप्चर केला जाऊ शकतो."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची आहे का?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> हाताळण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे आहे का?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"या अ‍ॅपला रेकॉर्ड करण्याची परवानगी दिलेली नाही पण या USB डिव्हाइसद्वारे ऑडिओ कॅप्चर केला जाऊ शकतो. <xliff:g id="APPLICATION">%1$s</xliff:g> चा वापर या डिव्हाइससह केल्याने कॉल, सूचना आणि अलार्मचा आवाज कदाचित ऐकू येणार नाही."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> चा वापर या डिव्हाइससह केल्याने कॉल, सूचना आणि अलार्मचा आवाज कदाचित ऐकू येणार नाही."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची का?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> हाताळण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे का?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> हँडल करण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे आहे का? \n या अ‍ॅपला रेकॉर्ड करण्याची परवानगी दिलेली नाही पण या USB डिव्हाइसद्वारे ऑडिओ कॅप्चर केला जाऊ शकतो."</string>
@@ -41,7 +45,7 @@
<string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"इंस्टॉल केलेली अ‍ॅप्स या USB उपसाधनासह कार्य करत नाहीत. <xliff:g id="URL">%1$s</xliff:g> येथे या उपसाधनाविषयी अधिक जाणून घ्या"</string>
<string name="title_usb_accessory" msgid="1236358027511638648">"USB उपसाधन"</string>
<string name="label_view" msgid="6815442985276363364">"पहा"</string>
- <string name="always_use_device" msgid="210535878779644679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> कनेक्ट केलेली असताना नेहमी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडा"</string>
+ <string name="always_use_device" msgid="210535878779644679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> कनेक्ट केलेले असताना नेहमी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडा"</string>
<string name="always_use_accessory" msgid="1977225429341838444">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> कनेक्ट केलेली असताना नेहमी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडा"</string>
<string name="usb_debugging_title" msgid="8274884945238642726">"USB डीबग करण्यास अनुमती द्यायची?"</string>
<string name="usb_debugging_message" msgid="5794616114463921773">"संगणकाची RSA की फिंगरप्रिंट ही आहे:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
@@ -131,7 +135,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="1597899891472340950">"तुमच्या चेहऱ्याने अनलॉक केले. पुढे सुरू ठेवण्यासाठी दाबा."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन वापरा"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पॅटर्न वापरा"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"हे तुमचा मायक्रोफोन वापरण्याची परवानगी असलेल्या सर्व ॲप्स आणि सेवांसाठी अ‍ॅक्सेस अनब्लॉक करते."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"हे तुमचा कॅमेरा वापरण्याची परवानगी असलेल्या सर्व ॲप्स आणि सेवांसाठी अ‍ॅक्सेस अनब्लॉक करते."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"हे तुमचा कॅमेरा आणि मायक्रोफोन वापरण्याची परवानगी असलेल्या सर्व ॲप्स व सेवांसाठी अ‍ॅक्सेस अनब्लॉक करते."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"इतर डिव्हाइस"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"अवलोकन टॉगल करा."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"अलार्म, रिमाइंडर, इव्‍हेंट आणि तुम्ही निश्चित केलेल्या कॉलर व्यतिरिक्त तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज ऐकू शकतात."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • चार्जिंग डॉक • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मध्ये पूर्ण होईल"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"वापरकर्ता स्विच करा"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अ‍ॅप्स आणि डेटा हटवला जाईल."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"काढा"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"अतिथी, तुमचे पुन्‍हा स्‍वागत आहे!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"तुम्ही तुमचे सत्र सुरू ठेवू इच्छिता?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"येथून सुरू करा"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"जोडा"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ने सुचवले आहे"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"डिव्हाइस लॉक आहे"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"हे सेशन कास्ट करण्यासाठी, कृपया ॲप उघडा."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात अ‍ॅप"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट करणे थांबवा"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string>
<string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"अ‍ॅक्टिव्ह ॲप्स"</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_copy" msgid="770856373439969178">"कॉपी करा"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"कॉपी केले"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> वरून"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"कॉपी केलेले UI डिसमिस करा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index f0e48d43a8e3..1aa203995ab1 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Autoputar skrin"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nApl ini belum diberikan kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk mengendalikan <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Apl ini belum diberikan kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini. Tindakan menggunakan <xliff:g id="APPLICATION">%1$s</xliff:g> dengan peranti ini mungkin menghalang anda daripada mendengar panggilan, pemberitahuan dan penggera."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Tindakan menggunakan <xliff:g id="APPLICATION">%1$s</xliff:g> dengan peranti ini mungkin menghalang anda daripada mendengar panggilan, pemberitahuan dan penggera."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk mengendalikan <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk mengendalikan <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nApl ini belum diberikan kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Dibuka kunci oleh wajah anda. Tekan untuk meneruskan."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Disahkan"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan corak"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Tindakan ini menyahsekat akses bagi semua apl dan perkhidmatan yang dibenarkan untuk menggunakan mikrofon anda."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Tindakan ini menyahsekat akses bagi semua apl dan perkhidmatan yang dibenarkan untuk menggunakan kamera anda."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Tindakan ini menyahsekat akses bagi semua apl dan perkhidmatan yang dibenarkan untuk menggunakan kamera atau mikrofon anda."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Peranti lain"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Togol Ikhtisar"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Anda tidak akan diganggu oleh bunyi dan getaran, kecuali daripada penggera, peringatan, acara dan pemanggil yang anda tetapkan. Anda masih mendengar item lain yang anda pilih untuk dimainkan termasuk muzik, video dan permainan."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengecas dengan Dok • Penuh dalam masa <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alih keluar"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat kembali, tetamu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Adakah anda ingin meneruskan sesi anda?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulakan semula"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Tambah"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Dicadangkan oleh <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Peranti dikunci"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN mengandungi huruf atau simbol"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Sahkan <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN salah"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Leret untuk melihat selanjutnya"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuatkan cadangan"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Sembunyikan kawalan media ini untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media semasa tidak dapat disembunyikan."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Sambung semula"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Untuk menghantar sesi ini, sila buka apl."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Apl yang tidak diketahui"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Berhenti menghantar"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
<string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apl aktif"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Berhenti"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dihentikan"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Salin"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Disalin"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Daripada <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ketepikan penyalinan UI"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 8a0250e5293c..48ba1d1d350b 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -34,8 +34,12 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ဖန်သားပြင် အလိုအလျောက်လှည့်ရန်"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> အား ဝင်သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ခွင့်ပြုပါသလား။"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> အား <xliff:g id="USB_DEVICE">%2$s</xliff:g> ကို သုံးခွင့်ပြုမလား။\nဤအက်ပ်ကို အသံဖမ်းခွင့် ပေးမထားသော်လည်း ၎င်းသည် ဤ USB စက်ပစ္စည်းမှတစ်ဆင့် အသံများကို ဖမ်းယူနိုင်ပါသည်။"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ဝင်သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ခွင့်ပြုမလား။"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ဆောင်ရွက်ရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ဖွင့်လိုပါသလား။"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ဤအက်ပ်ကို အသံဖမ်းခွင့် ပေးမထားသော်လည်း ၎င်းသည် ဤ USB စက်ပစ္စည်းမှတစ်ဆင့် အသံများကို ဖမ်းယူနိုင်ပါသည်။ ဤစက်ဖြင့် <xliff:g id="APPLICATION">%1$s</xliff:g> အသုံးပြုခြင်းက ဖုန်းအဝင်၊ အကြောင်းကြားချက်နှင့် နှိုးစက်သံ မကြားခြင်းများ ဖြစ်စေနိုင်သည်။"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ဤစက်ဖြင့် <xliff:g id="APPLICATION">%1$s</xliff:g> အသုံးပြုခြင်းက ဖုန်းအဝင်၊ အကြောင်းကြားချက်နှင့် နှိုးစက်သံ မကြားခြင်းများ ဖြစ်စေနိုင်သည်။"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> အား ဝင်သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ခွင့်ပြုပါသလား။"</string>
- <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ဆောင်ရွက်ရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ဖွင့်လိုပါသလား။"</string>
+ <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> စီမံရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ဖွင့်လိုပါသလား။"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ကို သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ဖွင့်မလား။\nဤအက်ပ်ကို အသံဖမ်းခွင့် ပေးမထားသော်လည်း ၎င်းသည် ဤ USB စက်ပစ္စည်းမှတစ်ဆင့် အသံများကို ဖမ်းယူနိုင်ပါသည်။"</string>
<string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ဆောင်ရွက်ရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ဖွင့်လိုပါသလား။"</string>
<string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"ဒီUSBပစ္စည်းနှင့်ဘယ်အပ်ပလီကေးရှင်းမှ အလုပ်မလုပ်ပါ။ ပိုမိုသိရန် <xliff:g id="URL">%1$s</xliff:g>တွင် လေ့လာပါ"</string>
@@ -131,7 +135,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="1597899891472340950">"သင့်မျက်နှာဖြင့် ဖွင့်သည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"အထောက်အထားစိစစ်ပြီးပြီ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ပင်နံပါတ်သုံးရန်"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ပုံစံကို သုံးရန်"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"၎င်းက သင့်မိုက်ခရိုဖုန်းသုံးရန် ခွင့်ပြုထားသော အက်ပ်နှင့် ဝန်ဆောင်မှုအားလုံးအတွက် သုံးခွင့်ကို ပြန်ဖွင့်ပေးသည်။"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"၎င်းက သင့်ကင်မရာသုံးရန် ခွင့်ပြုထားသော အက်ပ်နှင့် ဝန်ဆောင်မှုအားလုံးအတွက် သုံးခွင့်ကို ပြန်ဖွင့်ပေးသည်။"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"၎င်းက သင့်ကင်မရာ (သို့) မိုက်ခရိုဖုန်းသုံးရန် ခွင့်ပြုထားသော အက်ပ်နှင့် ဝန်ဆောင်မှုအားလုံးအတွက် သုံးခွင့်ကို ပြန်ဖွင့်ပေးသည်။"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"အခြားစက်ပစ္စည်း"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ဖွင့်၊ ပိတ် အနှစ်ချုပ်"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"နှိုးစက်သံ၊ သတိပေးချက်အသံများ၊ ပွဲစဉ်သတိပေးသံများနှင့် သင်ခွင့်ပြုထားသူများထံမှ ဖုန်းခေါ်မှုများမှလွဲ၍ အခြားအသံများနှင့် တုန်ခါမှုများက သင့်ကို အနှောင့်အယှက်ပြုမည် မဟုတ်ပါ။ သို့သော်လည်း သီချင်း၊ ဗီဒီယိုနှင့် ဂိမ်းများအပါအဝင် သင်ကရွေးချယ်ဖွင့်ထားသည့် အရာတိုင်း၏ အသံကိုမူ ကြားနေရဆဲဖြစ်ပါလိမ့်မည်။"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • အားသွင်းအထိုင် • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> တွင် ပြည့်မည်"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ဖယ်ထုတ်ပါ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ဧည့်သည်ကို ပြန်လည် ကြိုဆိုပါသည်။"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်၏ စက်ရှင်ကို ဆက်လုပ်လိုပါသလား။"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ပြန်စပါ"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"ထည့်ရန်"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> က အကြံပြုထားသည်"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"စက်ကိုလော့ခ်ချထားသည်"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ပိုကြည့်ရန် ပွတ်ဆွဲပါ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"အကြံပြုချက်များ ဖွင့်နေသည်"</string>
<string name="controls_media_title" msgid="1746947284862928133">"မီဒီယာ"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ၏ ဤမီဒီယာ ထိန်းချုပ်ကိရိယာကို ဖျောက်ထားမလား။"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"လက်ရှိ မီဒီယာစက်ရှင်ကို ဝှက်၍မရပါ။"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"ဖျောက်ထားမည်"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ဆက်လုပ်ရန်"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"အက်ပ်ဖွင့်ပြီး ဤစက်ရှင်ကို ကာစ်လုပ်နိုင်သည်။"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"အမည်မသိ အက်ပ်"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ကာစ် ရပ်ရန်"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
<string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ပွင့်နေသည့်အက်ပ်များ"</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_copy" msgid="770856373439969178">"မိတ္တူကူးရန်"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ကူးပြီးပါပြီ"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ထံမှ"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI မိတ္တူမကူးတော့ရန်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index bbceca79d4a0..fc9fd8beb334 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotér skjermen automatisk"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vil du gi <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vil du gi <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDenne appen har ikke fått tillatelse til å spille inn, men kan ta opp lyd med denne USB-enheten."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Vil du gi <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Vil du åpne <xliff:g id="APPLICATION">%1$s</xliff:g> for å behandle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Denne appen har ikke fått tillatelse til å spille inn, men kan ta opp lyd med denne USB-enheten. Hvis du bruker <xliff:g id="APPLICATION">%1$s</xliff:g> med denne enheten, kan det føre til at du ikke hører anrop, varsler og alarmer."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Hvis du bruker <xliff:g id="APPLICATION">%1$s</xliff:g> med denne enheten, kan det føre til at du ikke hører anrop, varsler og alarmer."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Vil du gi <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Vil du åpne <xliff:g id="APPLICATION">%1$s</xliff:g> for å behandle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Vil du åpne <xliff:g id="APPLICATION">%1$s</xliff:g> for å håndtere <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDenne appen har ikke fått tillatelse til å spille inn, men kan ta opp lyd med denne USB-enheten."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Låst opp med ansiktet ditt. Trykk for å fortsette."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentisert"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Bruk PIN-kode"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Bruk mønster"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Dette opphever blokkeringen av tilgang for alle apper og tjenester som har tillatelse til å bruke mikrofonen."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Dette opphever blokkeringen av tilgang for alle apper og tjenester som har tillatelse til å bruke kameraet."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Dette opphever blokkeringen av tilgang for alle apper og tjenester som har tillatelse til å bruke kameraet eller mikrofonen."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Annen enhet"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Slå oversikten av eller på"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Du blir ikke forstyrret av lyder og vibrasjoner, med unntak av alarmer, påminnelser, aktiviteter og oppringere du angir. Du kan fremdeles høre alt du velger å spille av, for eksempel musikk, videoer og spill."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ladedokk • Fulladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle appene og all informasjon i denne økten slettes."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbake, gjest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Legg til"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Foreslått av <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Enheten er låst"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-koden inneholder bokstaver eller symboler"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Bekreft <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Feil PIN-kode"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Sveip for å se flere"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laster inn anbefalinger"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medier"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Vil du skjule denne mediekontrollen for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Den nåværende medieøkten kan ikke skjules."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"For å caste denne økten, åpne appen."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukjent app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stopp castingen"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
<string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive apper"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stopp"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stoppet"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiér"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiert"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Fra <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Lukk kopi-UI"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index a7879e6cc226..fe66b9438aca 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"स्वत:घुम्ने स्क्रिन"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> माथि पहुँच राख्ने अनुमति दिने हो?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> माथि पहुँच राख्न अनुमति दिने हो?\nयो एपलाई रेकर्ड गर्ने अनुमति प्रदान गरिएको छैन तर यसले USB यन्त्रमार्फत अडियो क्याप्चर गर्न सक्छ।"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> प्रयोग गर्ने अनुमति दिने हो?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> को व्यवस्थापन गर्न <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्ने हो?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"यो एपलाई रेकर्ड गर्ने अनुमति दिइएको छैन तर यसले यो USB डिभाइसमार्फत अडियो रेकर्ड गर्न सक्छ। तपाईंले यो डिभाइसमा <xliff:g id="APPLICATION">%1$s</xliff:g> प्रयोग गर्नुभयो भने तपाईंले कल, सूचना र अलार्मको आवाज नसुन्ने सम्भावना हुन्छ।"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"तपाईंले यो डिभाइसमा <xliff:g id="APPLICATION">%1$s</xliff:g> प्रयोग गर्नुभयो भने तपाईंले कल, सूचना र अलार्मको आवाज नसुन्ने सम्भावना हुन्छ।"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> माथि पहुँच राख्ने अनुमति दिने हो?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> को व्यवस्थापन गर्न <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्ने हो?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> सञ्चालन गर्न खोल्ने हो?\nयो एपलाई रेकर्ड गर्ने अनुमति प्रदान गरिएको छैन तर यसले USB यन्त्रमार्फत अडियो क्याप्चर गर्न सक्छ।"</string>
@@ -131,7 +135,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="1597899891472340950">"तपाईंको अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न थिच्नुहोस्।"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"प्रमाणीकरण गरियो"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN प्रयोग गर्नुहोस्"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ढाँचा प्रयोग गर्नुहोस्"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"यसो गर्नुभयो भने माइक्रोफोन प्रयोग गर्ने अनुमति दिइएका सबै एप तथा सेवाहरूका लागि सो अनुमति अनब्लक गरिन्छ।"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"यसो गर्नुभयो भने क्यामेरा प्रयोग गर्ने अनुमति दिइएका सबै एप तथा सेवाहरूका लागि सो अनुमति अनब्लक गरिन्छ।"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"यसो गर्नुभयो भने क्यामेरा वा माइक्रोफोन प्रयोग गर्ने अनुमति दिइएका सबै एप तथा सेवाहरूका लागि सो अनुमति अनब्लक गरिन्छ।"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"अर्को डिभाइड"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"परिदृश्य टगल गर्नुहोस्"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"तपाईंलाई अलार्म, रिमाइन्डर, कार्यक्रम र तपाईंले निर्दिष्ट गर्नुभएका कलरहरू बाहेकका ध्वनि र कम्पनहरूले बाधा पुऱ्याउने छैनन्। तपाईंले अझै सङ्गीत, भिडियो र खेलहरू लगायत आफूले प्ले गर्न छनौट गरेका जुनसुकै कुरा सुन्न सक्नुहुनेछ।"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • डक चार्ज हुँदै छ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मा पूरै चार्ज हुन्छ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"हटाउनुहोस्"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"तपाईंलाई फेरि स्वागत छ, अतिथि"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"थप्नुहोस्"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ले सिफारिस गरेको"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"यन्त्र लक गरिएको छ"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN मा अक्षर वा चिन्हहरू समाविष्ट हुन्छन्"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> पुष्टि गर्नुहोस्"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN मिलेन"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"यो सत्र कास्ट गर्न चाहनुहुन्छ भने कृपया एप खोल्नुहोस्।"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात एप"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट गर्न छाड्नुहोस्"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string>
<string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"सक्रिय एपहरू"</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_copy" msgid="770856373439969178">"कपी गर्नुहोस्"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"कपी गरियो"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> बाट"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"कपी UI खारेज गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 46e190ecef55..23381d0dfed3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Scherm automatisch draaien"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDeze app heeft geen opnamerechten gekregen, maar zou audio kunnen vastleggen via dit USB-apparaat."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> openen om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te verwerken?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Deze app heeft geen opnamerechten gekregen, maar zou audio kunnen vastleggen via dit USB-apparaat. Als je <xliff:g id="APPLICATION">%1$s</xliff:g> gebruikt met dit apparaat, hoor je misschien geen gesprekken, meldingen en wekkers."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Als je <xliff:g id="APPLICATION">%1$s</xliff:g> gebruikt met dit apparaat, hoor je misschien geen gesprekken, meldingen en wekkers."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="APPLICATION">%1$s</xliff:g> openen om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te verwerken?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> openen om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te verwerken?\nDeze app heeft geen opnamerechten gekregen, maar zou audio kunnen vastleggen via dit USB-apparaat."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Ontgrendeld met je gezicht. Druk om door te gaan."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Geverifieerd"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Pincode gebruiken"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Patroon gebruiken"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Hiermee hef je de toegangsblokkering op voor alle apps en services die rechten hebben om je microfoon te gebruiken."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Hiermee hef je de toegangsblokkering op voor alle apps en services die rechten hebben om je camera te gebruiken."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Hiermee hef je de toegangsblokkering op voor alle apps en services die rechten hebben om je camera of microfoon te gebruiken."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Ander apparaat"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Overzicht aan- of uitzetten"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Je wordt niet gestoord door geluiden en trillingen, behalve bij wekkers, herinneringen, afspraken en specifieke bellers die je selecteert. Je kunt nog steeds alles horen wat je wilt afspelen, waaronder muziek, video\'s en games."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oplaaddock • Vol over <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwijderen"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gast!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Wil je doorgaan met je sessie?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Opnieuw starten"</string>
@@ -334,7 +356,7 @@
<string name="user_remove_user_message" msgid="6702834122128031833">"Alle apps en gegevens van deze gebruiker worden verwijderd."</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"Verwijderen"</string>
<string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> krijgt toegang tot alle informatie die zichtbaar is op je scherm of die wordt afgespeeld vanaf je apparaat tijdens het opnemen of casten. Dit omvat informatie zoals wachtwoorden, betalingsgegevens, foto\'s, berichten en audio die je afspeelt."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"De service die deze functie levert, krijgt toegang tot alle informatie die zichtbaar is op je scherm of die wordt afgespeeld vanaf je apparaat tijdens het opnemen of casten. Dit omvat informatie zoals wachtwoorden, betalingsgegevens, foto\'s, berichten en audio die je afspeelt."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"De service die deze functie levert, krijgt tijdens het opnemen of casten toegang tot alle informatie die op je scherm te zien is of op je apparaat wordt afgespeeld. Dit omvat informatie zoals wachtwoorden, betalingsgegevens, foto\'s, berichten en audio die je afspeelt."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Beginnen met opnemen of casten?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Beginnen met opnemen of casten met <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Alles wissen"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Toevoegen"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Voorgesteld door <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Apparaat vergrendeld"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pincode bevat letters of symbolen"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> verifiëren"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Onjuiste pincode"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Als je deze sessie wilt casten, open je de app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Casten stoppen"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string>
<string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Actieve apps"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stoppen"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Gestopt"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiëren"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Gekopieerd"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Uit <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI voor kopiëren sluiten"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 38931742d41c..c01fbeafaa10 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ଅଟୋ-ରୋଟେଟ୍‌ ସ୍କ୍ରିନ୍"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ଆକ୍ସେସ୍‍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ଆକ୍ସେସ୍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ କି?\nଏହି ଆପ୍‌କୁ ରେକର୍ଡ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ କିନ୍ତୁ ଏହି USB ଡିଭାଇସ୍ ଜରିଆରେ ଅଡିଓ କ୍ୟାପ୍ଟର୍ କରିପାରିବ।"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>କୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>କୁ ନିୟନ୍ତ୍ରଣ କରିବା ପାଇଁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଖୋଲିବେ?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ଏହି ଆପକୁ ରେକର୍ଡ କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇନାହିଁ, କିନ୍ତୁ ଏହି USB ଡିଭାଇସ ମାଧ୍ୟମରେ ଏହା ଅଡିଓକୁ କ୍ୟାପଚର କରିପାରିବ। ଏହି ଡିଭାଇସରେ <xliff:g id="APPLICATION">%1$s</xliff:g> ବ୍ୟବହାର କରିବା କଲ, ବିଜ୍ଞପ୍ତି ଏବଂ ଆଲାରାମଗୁଡ଼ିକୁ ଶୁଣିବାରୁ ପ୍ରତିରୋଧ କରିପାରେ।"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ଏହି ଡିଭାଇସରେ <xliff:g id="APPLICATION">%1$s</xliff:g> ବ୍ୟବହାର କରିବା କଲ, ବିଜ୍ଞପ୍ତି ଏବଂ ଆଲାରାମଗୁଡ଼ିକୁ ଶୁଣିବାରୁ ପ୍ରତିରୋଧ କରିପାରେ।"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ଆକ୍ସେସ୍‍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ନିୟନ୍ତ୍ରଣ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g> ଖୋଲିବେ?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ପରିଚାଳନା କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଖୋଲିବେ?\nଏହି ଆପ୍‌କୁ ରେକର୍ଡ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ କିନ୍ତୁ ଏହି USB ଡିଭାଇସ୍ ଜରିଆରେ, ଏହା ଅଡିଓ କ୍ୟାପ୍ଟର୍ କରିପାରିବ।"</string>
@@ -131,7 +135,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="1597899891472340950">"ଆପଣଙ୍କ ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ପାଟର୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ଆପଣଙ୍କ ମାଇକ୍ରୋଫୋନକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇଥିବା ସମସ୍ତ ଆପ୍ ଓ ସେବା ପାଇଁ ଏହା ଆକ୍ସେସକୁ ଅନବ୍ଲକ୍ କରେ।"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ଆପଣଙ୍କ କ୍ୟାମେରାକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇଥିବା ସମସ୍ତ ଆପ୍ ଓ ସେବା ପାଇଁ ଏହା ଆକ୍ସେସକୁ ଅନବ୍ଲକ୍ କରେ।"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ଆପଣଙ୍କ କ୍ୟାମେରା କିମ୍ବା ମାଇକ୍ରୋଫୋନକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇଥିବା ସମସ୍ତ ଆପ୍ ଓ ସେବା ପାଇଁ ଏହା ଆକ୍ସେସକୁ ଅନବ୍ଲକ୍ କରେ।"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"ଅନ୍ୟ ଡିଭାଇସ୍"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ସଂକ୍ଷିପ୍ତ ବିବରଣୀକୁ ଟୋଗଲ୍ କରନ୍ତୁ"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ଆଲାର୍ମ, ରିମାଇଣ୍ଡର୍‌, ଇଭେଣ୍ଟ ଏବଂ ଆପଣ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିବା କଲର୍‌ଙ୍କ ବ୍ୟତୀତ ଆପଣଙ୍କ ଧ୍ୟାନ ଅନ୍ୟ କୌଣସି ଧ୍ୱନୀ ଏବଂ ଭାଇବ୍ରେଶନ୍‌ରେ ଆକର୍ଷଣ କରାଯିବନାହିଁ। ମ୍ୟୁଜିକ୍‍, ଭିଡିଓ ଏବଂ ଗେମ୍‌ ସମେତ ନିଜେ ଚଲାଇବାକୁ ବାଛିଥିବା ଅନ୍ୟ ସବୁକିଛି ଆପଣ ଶୁଣିପାରିବେ।"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ଡକରୁ ଚାର୍ଜ ହେଉଛି • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ରେ ସମ୍ପୂର୍ଣ୍ଣ ହେବ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ୟୁଜର୍‍ ବଦଳାନ୍ତୁ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"କାଢ଼ିଦିଅନ୍ତୁ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ପୁଣି ସ୍ୱାଗତ, ଅତିଥି!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ସେସନ୍ ଜାରି ରଖିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"ଯୋଗ କରନ୍ତୁ"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ଦ୍ଵାରା ପ୍ରସ୍ତାବିତ"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"ଡିଭାଇସ୍ ଲକ୍ ହୋଇଯାଇଛି"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PINରେ ଅକ୍ଷର କିମ୍ୱା ପ୍ରତୀକଗୁଡ଼ିକ ଥାଏ"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"ଭୁଲ PIN"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ଅଧିକ ଦେଖିବାକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ସୁପାରିଶଗୁଡ଼ିକ ଲୋଡ୍ କରାଯାଉଛି"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ମିଡିଆ"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ଏହି ମିଡିଆ ନିୟନ୍ତ୍ରଣକୁ ଲୁଚାଇବେ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"ବର୍ତ୍ତମାନର ମିଡିଆ ସେସନକୁ ଲୁଚାଯାଇପାରିବ ନାହିଁ।"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"ଲୁଚାନ୍ତୁ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ଏହି ସେସନକୁ କାଷ୍ଟ କରିବା ପାଇଁ, ଦୟାକରି ଆପ ଖୋଲନ୍ତୁ।"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ଅଜଣା ଆପ"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
<string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ସକ୍ରିୟ ଆପଗୁଡ଼ିକ"</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_copy" msgid="770856373439969178">"କପି କରନ୍ତୁ"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"କପି କରାଯାଇଛି"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>ରୁ"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"କପି କରାଯାଇଥିବା UIକୁ ଖାରଜ କରନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 6e2d33ade485..4aa88f26d41a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ਸਕ੍ਰੀਨ ਸਵੈ-ਘੁਮਾਓ"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"ਕੀ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਤੱਕ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"ਕੀ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?\nਇਸ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਪਰ ਇਹ USB ਡੀਵਾਈਸ ਰਾਹੀਂ ਆਡੀਓ ਕੈਪਚਰ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"ਕੀ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"ਕੀ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਨੂੰ ਵਰਤਣ ਲਈ <xliff:g id="APPLICATION">%1$s</xliff:g> ਖੋਲ੍ਹਣੀ ਹੈ?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ਇਸ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਪਰ ਇਹ USB ਡੀਵਾਈਸ ਰਾਹੀਂ ਆਡੀਓ ਕੈਪਚਰ ਕਰ ਸਕਦੀ ਹੈ। ਸ਼ਾਇਦ ਇਸ ਡੀਵਾਈਸ ਨਾਲ <xliff:g id="APPLICATION">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਨ \'ਤੇ ਕਾਲਾਂ, ਸੂਚਨਾਵਾਂ ਅਤੇ ਅਲਾਰਮਾਂ ਦੀ ਅਵਾਜ਼ ਸੁਣਾਈ ਨਾ ਦੇਵੇ।"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ਸ਼ਾਇਦ ਇਸ ਡੀਵਾਈਸ ਨਾਲ <xliff:g id="APPLICATION">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਨ \'ਤੇ ਕਾਲਾਂ, ਸੂਚਨਾਵਾਂ ਅਤੇ ਅਲਾਰਮਾਂ ਦੀ ਅਵਾਜ਼ ਸੁਣਾਈ ਨਾ ਦੇਵੇ।"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"ਕੀ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ਤੱਕ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"ਕੀ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਨੂੰ ਵਰਤਣ ਲਈ <xliff:g id="APPLICATION">%1$s</xliff:g> ਖੋਲ੍ਹਣੀ ਹੈ?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ਨੂੰ ਸੰਭਾਲਣ ਲਈ <xliff:g id="APPLICATION">%1$s</xliff:g> ਖੋਲ੍ਹੋ?\nਇਸ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਪਰ ਇਹ USB ਡੀਵਾਈਸ ਰਾਹੀਂ ਆਡੀਓ ਕੈਪਚਰ ਕਰ ਸਕਦੀ ਹੈ।"</string>
@@ -131,7 +135,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="1597899891472340950">"ਤੁਹਾਡੇ ਚਿਹਰੇ ਵੱਲੋਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ਪਿੰਨ ਵਰਤੋ"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ਪੈਟਰਨ ਵਰਤੋ"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ਇਹ ਉਹਨਾਂ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ ਪਹੁੰਚ ਨੂੰ ਅਣਬਲਾਕ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਨੂੰ ਤੁਹਾਡਾ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੱਤੀ ਗਈ ਹੈ।"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ਇਹ ਉਹਨਾਂ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ ਪਹੁੰਚ ਨੂੰ ਅਣਬਲਾਕ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਨੂੰ ਤੁਹਾਡਾ ਕੈਮਰਾ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੱਤੀ ਗਈ ਹੈ।"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ਇਹ ਉਹਨਾਂ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ ਪਹੁੰਚ ਨੂੰ ਅਣਬਲਾਕ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਨੂੰ ਤੁਹਾਡਾ ਕੈਮਰਾ ਜਾਂ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੱਤੀ ਗਈ ਹੈ।"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"ਹੋਰ ਡੀਵਾਈਸ"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ਰੂਪ-ਰੇਖਾ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟਾਂ ਤੁਹਾਨੂੰ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕਰਨਗੀਆਂ, ਸਿਵਾਏ ਅਲਾਰਮਾਂ, ਯਾਦ-ਦਹਾਨੀਆਂ, ਵਰਤਾਰਿਆਂ, ਅਤੇ ਤੁਹਾਡੇ ਵੱਲੋਂ ਨਿਰਧਾਰਤ ਕੀਤੇ ਕਾਲਰਾਂ ਦੀ ਸੂਰਤ ਵਿੱਚ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਸੰਗੀਤ, ਵੀਡੀਓ ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ ਆਪਣੀ ਚੋਣ ਅਨੁਸਾਰ ਕੁਝ ਵੀ ਸੁਣ ਸਕਦੇ ਹੋ।"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ਡੌਕ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ਵਿੱਚ ਪੂਰਾ ਚਾਰਜ ਹੋਵੇਗਾ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿੱਚ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ਹਟਾਓ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ਮਹਿਮਾਨ, ਫਿਰ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ਵੱਲੋਂ ਸੁਝਾਇਆ ਗਿਆ"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"ਡੀਵਾਈਸ ਲਾਕ ਹੈ"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ਹੋਰ ਦੇਖਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ਸਿਫ਼ਾਰਸ਼ਾਂ ਲੋਡ ਹੋ ਰਹੀਆਂ ਹਨ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ਮੀਡੀਆ"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਇਸ ਮੀਡੀਆ ਕੰਟਰੋਲ ਲੁਕਾਉਣਾ ਹੈ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"ਮੌਜੂਦਾ ਮੀਡੀਆ ਸੈਸ਼ਨ ਲੁਕਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"ਲੁਕਾਓ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ਇਸ ਸੈਸ਼ਨ ਨੂੰ ਕਾਸਟ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਐਪ ਖੋਲ੍ਹੋ।"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ਅਗਿਆਤ ਐਪ"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string>
<string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ"</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_copy" msgid="770856373439969178">"ਕਾਪੀ ਕਰੋ"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ਕਾਪੀ ਕੀਤੀ ਗਈ"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ਤੋਂ"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ਕਾਪੀ ਕੀਤੇ UI ਨੂੰ ਖਾਰਜ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 9b2e901237aa..3160f4da1aea 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Autoobracanie ekranu"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTa aplikacja nie ma uprawnień do nagrywania, ale może rejestrować dźwięk za pomocą tego urządzenia USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Otworzyć aplikację <xliff:g id="APPLICATION">%1$s</xliff:g> na potrzeby obsługi urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ta aplikacja nie ma uprawnień do nagrywania, ale może rejestrować dźwięk za pomocą tego urządzenia USB. Używanie aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na tym urządzeniu może zakłócać słyszenie połączeń, powiadomień i alertów."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Używanie aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na tym urządzeniu może zakłócać słyszenie połączeń, powiadomień i alertów."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Otworzyć aplikację <xliff:g id="APPLICATION">%1$s</xliff:g> do obsługi urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na obsługę urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTa aplikacja nie ma uprawnień do nagrywania, ale może rejestrować dźwięk za pomocą tego urządzenia USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Odblokowano skanem twarzy. Kliknij, aby kontynuować."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Uwierzytelniono"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Użyj kodu PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Użyj wzoru"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Spowoduje to odblokowanie dostępu dla wszystkich aplikacji i usług, które mają uprawnienia do korzystania z mikrofonu."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Spowoduje to odblokowanie dostępu dla wszystkich aplikacji i usług, które mają uprawnienia do korzystania z aparatu."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Spowoduje to odblokowanie dostępu dla wszystkich aplikacji i usług, które mają uprawnienia do korzystania z aparatu lub mikrofonu."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Inne urządzenie"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Przełącz Przegląd"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Nie będą Cię niepokoić żadne dźwięki ani wibracje z wyjątkiem alarmów, przypomnień, wydarzeń i połączeń od wybranych osób. Będziesz słyszeć wszystkie odtwarzane treści, takie jak muzyka, filmy czy gry."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ładowanie na stacji dokującej • Pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Usuń"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Witaj ponownie, Gościu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string>
@@ -778,6 +800,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Sugestia: <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Urządzenie zablokowane"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kod PIN zawiera litery lub symbole"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Sprawdź urządzenie <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Nieprawidłowy kod PIN"</string>
@@ -787,8 +821,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Przesuń palcem, by zobaczyć więcej"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Wczytuję rekomendacje"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Ukryć tę opcję sterowania multimediami w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Nie można ukryć tej sesji multimediów."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ukryj"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Wznów"</string>
@@ -828,6 +861,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Aby przesłać tę sesję, otwórz aplikację."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nieznana aplikacja"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zatrzymaj przesyłanie"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
<string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string>
@@ -906,7 +953,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktywne aplikacje"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zatrzymaj"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zatrzymano"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiuj"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Skopiowano"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Od: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Zamknij UI kopiowania"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 306f9c03a651..5cd852ce8888 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Giro automático da tela"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsse app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse este dispositivo: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para lidar com este dispositivo: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Esse app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB. O uso do app <xliff:g id="APPLICATION">%1$s</xliff:g> com esse dispositivo pode impedir que você ouça chamadas, notificações e alarmes."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"O uso do app <xliff:g id="APPLICATION">%1$s</xliff:g> com esse dispositivo pode impedir que você ouça chamadas, notificações e alarmes."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para lidar com o <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para usar o <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsse app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Desbloqueado pelo seu rosto. Pressione para continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Essa ação desbloqueia o acesso para todos os apps e serviços com autorização para usar seu microfone."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Essa ação desbloqueia o acesso para todos os apps e serviços com autorização para usar sua câmera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Essa ação desbloqueia o acesso para todos os apps e serviços com autorização para usar sua câmera ou seu microfone."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Outro dispositivo"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Alternar Visão geral"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregando na base • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloq."</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Mostrar e controlar dispositivos na tela de bloqueio?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Você pode adicionar à tela de bloqueio controles para dispositivos externos.\n\nO app do dispositivo pode permitir que você controle alguns dispositivos sem desbloquear o smartphone ou tablet.\n\nÉ possível fazer mudanças a qualquer momento nas Configurações."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Controlar dispositivos na tela de bloqueio?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"É possível controle alguns dispositivos sem desbloquear o smartphone ou tablet.\n\nO app do dispositivo determina quais dispositivos podem ser controlados dessa maneira."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Agora não"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Sim"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contém letras ou símbolos"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verificar <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorreto"</string>
@@ -815,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -891,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parado"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copiar"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Concluído"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Do app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dispensar cópia da IU"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 01cfbbb8aafb..0c082baefc8e 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rodar ecrã automaticamente"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Permitir que a app <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao dispositivo <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> aceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta app não recebeu autorização de gravação, mas pode capturar áudio através deste dispositivo USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Permitir que a app <xliff:g id="APPLICATION">%1$s</xliff:g> aceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Abrir a app <xliff:g id="APPLICATION">%1$s</xliff:g> para controlar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Esta app não recebeu autorização de gravação, mas pode capturar áudio através deste dispositivo USB. A utilização da app <xliff:g id="APPLICATION">%1$s</xliff:g> neste dispositivo pode impedir a audição de chamadas, notificações e alarmes."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"A utilização da app <xliff:g id="APPLICATION">%1$s</xliff:g> neste dispositivo pode impedir a audição de chamadas, notificações e alarmes."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Permitir que a app <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao acessório <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Pretende abrir a app <xliff:g id="APPLICATION">%1$s</xliff:g> para controlar o acessório <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Pretende abrir a app <xliff:g id="APPLICATION">%1$s</xliff:g> para controlar o acessório <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta app não recebeu autorização de gravação, mas pode capturar áudio através deste dispositivo USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Desbloqueado com o rosto. Prima para continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilizar padrão"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Isto desbloqueia o acesso a todas as apps e serviços com autorização para utilizar o seu microfone."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Isto desbloqueia o acesso a todas as apps e serviços com autorização para utilizar a sua câmara."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Isto desbloqueia o acesso a todas as apps e serviços com autorização para utilizar a sua câmara ou microfone."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Outro dispositivo"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Ativar/desativar Vista geral"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Não é incomodado por sons e vibrações, exceto de alarmes, lembretes, eventos e autores de chamadas que especificar. Continua a ouvir tudo o que optar por reproduzir, incluindo música, vídeos e jogos."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • A carregar na estação de ancoragem • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo de volta, convidado!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloq."</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contém letras ou símbolos."</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Validar <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorreto"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize rapidamente para ver mais."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"A carregar recomendações…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar este controlo de multimédia para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Não pode ocultar a sessão de multimédia atual."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sessão, abra a app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecida"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativas"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parada"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copiar"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Da app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorar cópia de IU"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 306f9c03a651..5cd852ce8888 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Giro automático da tela"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsse app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse este dispositivo: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para lidar com este dispositivo: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Esse app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB. O uso do app <xliff:g id="APPLICATION">%1$s</xliff:g> com esse dispositivo pode impedir que você ouça chamadas, notificações e alarmes."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"O uso do app <xliff:g id="APPLICATION">%1$s</xliff:g> com esse dispositivo pode impedir que você ouça chamadas, notificações e alarmes."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para lidar com o <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para usar o <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsse app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Desbloqueado pelo seu rosto. Pressione para continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Essa ação desbloqueia o acesso para todos os apps e serviços com autorização para usar seu microfone."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Essa ação desbloqueia o acesso para todos os apps e serviços com autorização para usar sua câmera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Essa ação desbloqueia o acesso para todos os apps e serviços com autorização para usar sua câmera ou seu microfone."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Outro dispositivo"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Alternar Visão geral"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregando na base • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloq."</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Mostrar e controlar dispositivos na tela de bloqueio?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Você pode adicionar à tela de bloqueio controles para dispositivos externos.\n\nO app do dispositivo pode permitir que você controle alguns dispositivos sem desbloquear o smartphone ou tablet.\n\nÉ possível fazer mudanças a qualquer momento nas Configurações."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Controlar dispositivos na tela de bloqueio?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"É possível controle alguns dispositivos sem desbloquear o smartphone ou tablet.\n\nO app do dispositivo determina quais dispositivos podem ser controlados dessa maneira."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Agora não"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Sim"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contém letras ou símbolos"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verificar <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorreto"</string>
@@ -815,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -891,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parado"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copiar"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Concluído"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Do app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dispensar cópia da IU"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 53d4526c8aaa..d8486b7a599b 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotire automată a ecranului"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Permiteți <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Permiteți accesul aplicației <xliff:g id="APPLICATION">%1$s</xliff:g> la <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nPermisiunea de înregistrare nu a fost acordată aplicației, dar aceasta poate să înregistreze conținut audio prin intermediul acestui dispozitiv USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Permiteți ca <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Deschideți <xliff:g id="APPLICATION">%1$s</xliff:g> ca să gestioneze <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Permisiunea de înregistrare nu a fost acordată aplicației, dar aceasta poate să înregistreze conținut audio prin intermediul acestui dispozitiv USB. Dacă folosiți <xliff:g id="APPLICATION">%1$s</xliff:g> cu acest dispozitiv, acest lucru vă poate împiedica să auziți apeluri, notificări și alarme."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Dacă folosiți <xliff:g id="APPLICATION">%1$s</xliff:g> cu acest dispozitiv, acest lucru vă poate împiedica să auziți apeluri, notificări și alarme."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Permiteți <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Deschideți <xliff:g id="APPLICATION">%1$s</xliff:g> ca să gestioneze <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Deschideți <xliff:g id="APPLICATION">%1$s</xliff:g> pentru a gestiona <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nPermisiunea de înregistrare nu a fost acordată aplicației, dar aceasta poate să înregistreze conținut audio prin intermediul acestui dispozitiv USB."</string>
@@ -131,7 +135,8 @@
<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ți Confirmați pentru a finaliza"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1597899891472340950">"S-a deblocat cu ajutorul feței. Apăsați pentru a continua."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificat"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Folosiți PIN-ul"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Folosiți modelul"</string>
@@ -289,6 +294,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Astfel, deblocați accesul pentru toate aplicațiile și serviciile care au permisiunea de a folosi microfonul."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Astfel, deblocați accesul pentru toate aplicațiile și serviciile care au permisiunea de a folosi camera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Astfel, deblocați accesul pentru toate aplicațiile și serviciile care au permisiunea de a folosi camera sau microfonul."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Alt dispozitiv"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Comutați secțiunea Recente"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Se vor anunța prin sunete și vibrații numai alarmele, mementourile, evenimentele și apelanții specificați de dvs. Totuși, veți auzi tot ce alegeți să redați, inclusiv muzică, videoclipuri și jocuri."</string>
@@ -322,7 +345,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Suport de încărcare • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> până la încărcarea completă"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Comutați între utilizatori"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ștergeți"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bine ați revenit în sesiunea pentru invitați!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vreți să continuați sesiunea?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începeți din nou"</string>
@@ -772,6 +794,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Adăugați"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Sugerat de <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Dispozitiv blocat"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Codul PIN conține litere sau simboluri"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verificați <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Cod PIN greșit"</string>
@@ -821,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pentru a proiecta această sesiune, deschideți aplicația."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicație necunoscută"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Nu mai proiectați"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Deschideți conversația"</string>
@@ -898,7 +946,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicații active"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Opriți"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Oprită"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copiați"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"S-a copiat"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Din <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Închideți copierea interfeței de utilizare"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index fc99fcb904f5..bf6d6aa15b5a 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Автоповорот экрана"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Предоставить приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к устройству \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Предоставить приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к устройству \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?\nПриложению не разрешено вести запись, однако с помощью этого USB-устройства оно может записывать звук."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Разрешить приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к устройству \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Открыть приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" для управления устройством \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Приложению не разрешено вести запись, однако оно может записывать аудио с помощью этого USB-устройства. Во время использования приложения \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" с этим устройством вы можете не услышать звуков уведомлений, звонков и будильников."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Во время использования приложения \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" с этим устройством вы можете не услышать звуков уведомлений, звонков и будильников."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Предоставить приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к устройству \"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>\"?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Открыть приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" для управления устройством \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Открыть приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" для использования устройства \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?\nПриложению не разрешено вести запись, однако с помощью этого USB-устройства оно может записывать звук."</string>
@@ -131,7 +135,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="1597899891472340950">"Сработало распознавание лица. Нажмите, чтобы продолжить."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификация выполнена"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-код"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Использовать графический ключ"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Будет снята блокировка доступа для всех приложений и сервисов с разрешением на использование микрофона."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Будет снята блокировка доступа для всех приложений и сервисов с разрешением на использование камеры."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Будет снята блокировка доступа для всех приложений и сервисов с разрешением на использование камеры или микрофона."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Другое устройство"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Переключить режим обзора"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника, напоминаний, уведомлений о мероприятиях и звонков от помеченных контактов. Вы по-прежнему будете слышать включенную вами музыку, видео, игры и т. д."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарядка от док-станции • Ещё <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Удалить"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Рады видеть вас снова!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Продолжить сеанс?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Начать заново"</string>
@@ -778,6 +800,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Добавить"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Предложено приложением \"<xliff:g id="APP">%s</xliff:g>\""</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Устройство заблокировано"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код содержит буквы или символы"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Подтвердите устройство \"<xliff:g id="DEVICE">%s</xliff:g>\""</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Неверный PIN-код"</string>
@@ -787,8 +821,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Проведите по экрану, чтобы увидеть больше"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загрузка рекомендаций…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Скрыть этот элемент управления в приложении \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Этот мультимедийный сеанс невозможно скрыть."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скрыть"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Возобновить"</string>
@@ -828,6 +861,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Чтобы начать трансляцию сеанса, откройте приложение"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестное приложение"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Остановить трансляцию"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
<string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string>
@@ -906,7 +953,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активные приложения"</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_copy" msgid="770856373439969178">"Копировать"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скопировано."</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Из приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрыть меню копирования"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 51d28f3d411d..8096315779f8 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ස්වයංක්‍රීයව-භ්‍රමණය වන තිරය"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> හට <xliff:g id="USB_DEVICE">%2$s</xliff:g> වෙත පිවිසීමට ඉඩ දෙන්නද?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> වෙත ප්‍රවේශ වීමට <xliff:g id="USB_DEVICE">%2$s</xliff:g> හට ඉඩ දෙන්නද?\n මෙම යෙදුමට පටිගත කිරීම් අවසරයක් ලබා දී නොමැති නමුත් මෙම USB උපාංගය හරහා ශ්‍රව්‍ය ග්‍රහණය කර ගත හැකිය."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> හට <xliff:g id="USB_DEVICE">%2$s</xliff:g> වෙත පිවිසීමට ඉඩ දෙන්නද?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> හැසිරවීමට <xliff:g id="APPLICATION">%1$s</xliff:g> විවෘත කරන්නද?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"මෙම යෙදුමට පටිගත කිරීම් අවසරයක් ලබා දී නොමැති නමුත් මෙම USB උපාංගය හරහා ශ්‍රව්‍ය ග්‍රහණය කර ගත හැකිය. මෙම උපාංගය සමග <xliff:g id="APPLICATION">%1$s</xliff:g> භාවිත කිරීම ඇමතුම්, දැනුම්දීම් සහ එලාම ඇසීම වැළැක්විය හැකිය."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"මෙම උපාංගය සමග <xliff:g id="APPLICATION">%1$s</xliff:g> භාවිත කිරීම ඇමතුම්, දැනුම්දීම් සහ එලාම ඇසීම වැළැක්විය හැකිය."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> හට <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> වෙත පිවිසීමට ඉඩ දෙන්නද?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> හැසිරවීමට <xliff:g id="APPLICATION">%1$s</xliff:g> විවෘත කරන්නද?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_DEVICE">%2$s</xliff:g> හැසිරවීමට විවෘත කරන්නද?\n මෙම යෙදුමට පටිගත කිරීම් අවසරයක් ලබා දී නොමැති නමුත් මෙම USB උපාංගය හරහා ශ්‍රව්‍ය ග්‍රහණය කර ගත හැකිය."</string>
@@ -131,7 +135,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="1597899891472340950">"ඔබගේ මුහුණෙන් අගුලු හරින ලදී. ඉදිරියට යාමට ඔබන්න."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"සත්‍යාපනය විය"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN භාවිත කරන්න"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"රටාව භාවිත කරන්න"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"මෙය ඔබගේ මයික්‍රෆෝනය භාවිත කිරීමට ඉඩ දී ඇති සියලු යෙදුම් සහ සේවා සඳහා ප්‍රවේශය අවහිර කිරීම ඉවත් කරයි."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"මෙය ඔබගේ කැමරාව භාවිතා කිරීමට ඉඩ දී ඇති සියලු යෙදුම් සහ සේවා සඳහා ප්‍රවේශය අවහිර කිරීම ඉවත් කරයි."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"මෙය ඔබගේ කැමරාව හෝ මයික්‍රෆෝනය භාවිත කිරීමට ඉඩ දී ඇති සියලු යෙදුම් සහ සේවා සඳහා ප්‍රවේශය අවහිර කිරීම ඉවත් කරයි."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"වෙනත් උපාංගය"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"දළ විශ්ලේෂණය ටොගල කරන්න"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"එලාම සිහිකැඳවීම්, සිදුවීම්, සහ ඔබ සඳහන් කළ අමතන්නන් හැර, ශබ්ද සහ කම්පනවලින් ඔබට බාධා නොවනු ඇත. සංගීතය, වීඩියෝ, සහ ක්‍රීඩා ඇතුළු ඔබ වාදනය කිරීමට තෝරන ලද සියලු දේ ඔබට තවම ඇසෙනු ඇත."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ආරෝපණ ඩොකය • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>කින් සම්පූර්ණ වේ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"පරිශීලක මාරුව"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ඉවත් කරන්න"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"නැවත සාදරයෙන් පිළිගනිමු, අමුත්තා!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ඔබගේ සැසිය දිගටම කරගෙන යෑමට ඔබට අවශ්‍යද?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"යළි මුල සිට අරඹන්න"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"එක් කරන්න"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"යෝජනා කළේ <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"උපාංගය අගුලු දමා ඇත"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN හි අකුරු හෝ සංකේත අඩංගු වේ"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> සත්‍යාපනය කරන්න"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"වැරදි PIN එකකි"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"තව බැලීමට ස්වයිප් කරන්න"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"නිර්දේශ පූරණය කරමින්"</string>
<string name="controls_media_title" msgid="1746947284862928133">"මාධ්‍ය"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා මෙම මාධ්‍ය පාලනය වසන්නද?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"වත්මන් මාධ්‍ය සැසිය සැඟවිය නොහැකිය."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"සඟවන්න"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"නැවත පටන් ගන්න"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"මෙම සැසිය විකාශය කිරීමට, කරුණාකර යෙදුම විවෘත කරන්න."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"නොදන්නා යෙදුම"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"විකාශය නවතන්න"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
<string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"සක්‍රිය යෙදුම්"</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_copy" msgid="770856373439969178">"පිටපත් කරන්න"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"පිටපත් කරන ලදි"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> සිට"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dismiss copy UI"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 17384203ca56..69873d41155a 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatické otočenie obrazovky"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> pristupovať k zariadeniu <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTejto aplikácii nebolo udelené povolenie na nahrávanie, môže však snímať zvuk cez toto zariadenie USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Chcete povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Chcete otvoriť aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g> na spravovanie zariadenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Tejto aplikácii nebolo udelené povolenie na nahrávanie, ale môže nahrávať zvuk cez toto zariadenie USB. Ak budete s týmto zariadením používať aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g>, nemusíte počuť hovory, upozornenia ani budíky."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ak budete s týmto zariadením používať aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g>, nemusíte počuť hovory, upozornenia ani budíky."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Otvoriť aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g> na použitie zariadenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Chcete otvoriť aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g> na správu zariadenia <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?\nTejto aplikácii nebolo udelené povolenie na nahrávanie, ale môže nasnímať zvuk cez toto zariadenie USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Odomkli ste svojou tvárou. Pokračujte stlačením."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Overené"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použiť PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použiť vzor"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Táto akcia odblokuje prístup všetkým aplikáciám a službám, ktoré majú povolené používať mikrofón."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Táto akcia odblokuje prístup všetkým aplikáciám a službám, ktoré majú povolené používať fotoaparát."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Táto akcia odblokuje prístup všetkým aplikáciám a službám, ktoré majú povolené používať fotoaparát alebo mikrofón."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Iné zariadenie"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Prepnúť prehľad"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Nebudú vás vyrušovať zvuky ani vibrácie, iba budíky, pripomenutia, udalosti a volajúci, ktorých určíte. Budete naďalej počuť všetko, čo sa rozhodnete prehrať, ako napríklad hudbu, videá a hry."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíjací dok • Do úplného nabitia zostáva <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrániť"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Hosť, vitajte späť!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relácii pokračovať?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začať odznova"</string>
@@ -778,6 +800,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Pridať"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Navrhuje <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Uzamknuté zariadenie"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Chcete zobrazovať a ovládať zariadenia na uzamknutej obrazovke?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na uzamknutú obrazovku si môžete pridať ovládanie externých zariadení.\n\nAplikácia zariadenia vám môže umožniť ovládať niektoré zariadenia bez odomknutia telefónu či tabletu.\n\nZmeny môžete vykonať kedykoľvek v Nastaveniach."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Chcete ovládať zariadenia na uzamknutej obrazovke?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Niektoré zariadenia môžete ovládať bez odomknutia telefónu či tabletu.\n\nAplikácia zariadenia určuje, ktoré zariadenia sa dajú týmto spôsobom ovládať."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nie, vďaka"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Áno"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN obsahuje písmená či symboly"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>, overenie"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Nesprávny PIN"</string>
@@ -787,8 +815,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Potiahnutím zobrazíte ďalšie položky"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítavajú sa odporúčania"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Médiá"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Chcete tento ovládač médií pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> skryť?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Aktuálna relácia média sa nedá skryť."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skryť"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string>
@@ -828,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ak chcete túto reláciu prenášať, otvorte aplikáciu."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznáma aplikácia"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastaviť prenos"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string>
@@ -906,7 +947,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktívne aplikácie"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ukončiť"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zastavená"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopírovať"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Hotovo"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Skopírované"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Z aplikácie <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Používateľské rozhranie zahodenia kópie"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index ec68ce66afb8..6f9d453d4e49 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Samodejno zasukaj zaslon"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Ali aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> dovolite dostop do dodatka USB <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Ali aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> dovolite dostop do naprave <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTa aplikacija sicer nima dovoljenja za snemanje, vendar bi lahko zajemala zvok prek te naprave USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Ali aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> dovolite dostop do naprave USB <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Želite odpreti aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje naprave USB <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ta aplikacija sicer nima dovoljenja za snemanje, vendar bi lahko zajemala zvok prek te naprave USB. Uporaba aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g> s to napravo lahko povzroči, da boste preslišali klice, obvestila in alarme."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Uporaba aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g> s to napravo lahko povzroči, da boste preslišali klice, obvestila in alarme."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Ali aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> dovolite dostop do dodatka USB <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Želite odpreti aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje dodatka USB <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Želite odpreti aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje naprave <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTa aplikacija sicer nima dovoljenja za snemanje, vendar bi lahko zajemala zvok prek te naprave USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Odklenili ste z obrazom. Pritisnite za nadaljevanje."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Preverjena pristnost"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Uporabi kodo PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Uporabi vzorec"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"S tem boste odblokirali dostop za vse aplikacije in storitve, ki imajo dovoljenje za uporabo mikrofona."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"S tem boste odblokirali dostop za vse aplikacije in storitve, ki imajo dovoljenje za uporabo fotoaparata."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"S tem boste odblokirali dostop za vse aplikacije in storitve, ki imajo dovoljenje za uporabo fotoaparata ali mikrofona."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Druga naprava"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Vklop/izklop pregleda"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Ne bodo vas motili zvoki ali vibriranje, razen v primeru alarmov, opomnikov, dogodkov in klicateljev, ki jih določite. Še vedno pa boste slišali vse, kar se boste odločili predvajati, vključno z glasbo, videoposnetki in igrami."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Polnjenje na nosilcu • Polno čez <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrani"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Znova pozdravljeni, gost!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite nadaljevati sejo?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začni znova"</string>
@@ -778,6 +800,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Predlagala aplikacija <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Naprava je zaklenjena"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Želite prikazati in upravljati naprave na zaklenjenem zaslonu?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Kontrolnike za zunanje naprave lahko dodate na zaklenjen zaslon.\n\nAplikacija v napravi vam bo morda omogočala upravljanje nekaterih naprav brez odklepanja telefona ali tabličnega računalnika.\n\nTe spremembe lahko kadar koli izvedete v nastavitvah."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Želite upravljati naprave na zaklenjenem zaslonu?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Nekatere naprave lahko upravljate brez odklepanja telefona ali tabličnega računalnika.\n\nAplikacija v napravi določa, katere naprave je mogoče upravljati na ta način."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Da"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Koda PIN vsebuje črke ali simbole"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Preverjanje naprave <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Napačna koda PIN"</string>
@@ -787,8 +815,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Če si želite ogledati več, povlecite"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nalaganje priporočil"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Predstavnost"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Želite skriti ta nadzor predstavnosti za apl. <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Trenutne seje predstavnosti ni mogoče skriti."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nadaljuj"</string>
@@ -828,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Če želite predvajati to sejo, odprite aplikacijo."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznana aplikacija"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ustavi predvajanje"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
<string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
@@ -906,7 +947,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ustavi"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Ustavljeno"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiraj"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Končano"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Iz aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Opusti kopiranje uporabniškega vmesnika"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 1156572c0702..47249bb2c851 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rrotullimi automatik i ekranit"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Të lejohet <xliff:g id="APPLICATION">%1$s</xliff:g> të ketë qasje te <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Dëshiron të lejosh që <xliff:g id="APPLICATION">%1$s</xliff:g> të ketë qasje te <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nKëtij aplikacioni nuk i është dhënë leje për regjistrim, por mund të regjistrojë audio përmes kësaj pajisjeje USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Të lejohet që <xliff:g id="APPLICATION">%1$s</xliff:g> të ketë qasje te <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Të hapet <xliff:g id="APPLICATION">%1$s</xliff:g> për të përdorur <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Këtij aplikacioni nuk i është dhënë leje për regjistrim, por mund të regjistrojë audio përmes kësaj pajisjeje USB. Përdorimi i <xliff:g id="APPLICATION">%1$s</xliff:g> me këtë pajisje mund të ndalojë dëgjimin e telefonatave, njoftimeve dhe alarmeve."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Përdorimi i <xliff:g id="APPLICATION">%1$s</xliff:g> me këtë pajisje mund të ndalojë dëgjimin e telefonatave, njoftimeve dhe alarmeve."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Të lejohet <xliff:g id="APPLICATION">%1$s</xliff:g> të ketë qasje te <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Të hapet <xliff:g id="APPLICATION">%1$s</xliff:g> për të përdorur <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Dëshiron të hapësh <xliff:g id="APPLICATION">%1$s</xliff:g> që të përpunojë <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nKëtij aplikacioni nuk i është dhënë leje për regjistrim, por mund të regjistrojë audio përmes kësaj pajisjeje USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Shkyçur nga fytyra jote. Shtyp për të vazhduar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"U vërtetua"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Përdor kodin PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Përdor motivin"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Kjo zhbllokon qasjen për të gjitha aplikacionet dhe shërbimet që lejohen të përdorin mikrofonin tënd."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Kjo zhbllokon qasjen për të gjitha aplikacionet dhe shërbimet që lejohen të përdorin kamerën tënde."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Kjo zhbllokon qasjen për të gjitha aplikacionet dhe shërbimet që lejohen të përdorin kamerën ose mikrofonin tënd."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Pajisje tjetër"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Kalo te përmbledhja"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç alarmeve, alarmeve rikujtuese, ngjarjeve dhe telefonuesve që specifikon. Do të vazhdosh të dëgjosh çdo gjë që zgjedh të luash duke përfshirë muzikën, videot dhe lojërat."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet në stacion • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ndërro përdorues"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hiq"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Mirë se erdhe, i ftuar!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Shto"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Sugjeruar nga <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Pajisja është e kyçur"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kodi PIN përmban shkronja ose simbole"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifiko <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Kod PIN i gabuar"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Rrëshqit shpejt për të shikuar më shumë"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Po ngarkon rekomandimet"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Të fshihet kontrolluesi i medias për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Seanca aktuale e medias nuk mund të fshihet."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fshih"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Vazhdo"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Hap aplikacionin për të transmetuar këtë seancë."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikacion i panjohur"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ndalo transmetimin"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
<string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikacionet aktive"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ndalo"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Ndaluar"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopjo"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"U kopjua"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Nga <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Hiq kopjen e ndërfaqes së përdoruesit"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 9fbef6683cd7..fe8923776a78 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аутоматско ротирање екрана"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nОва апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили уређај <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ова апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја. Ако користите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> са овим уређајем, можда нећете чути позиве, обавештења и аларме."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ако користите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> са овим уређајем, можда нећете чути позиве, обавештења и аларме."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили уређај <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> ради руковања уређајем <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nОва апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
@@ -131,7 +135,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="1597899891472340950">"Откључали сте лицем. Притисните да бисте наставили."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Идентитет је потврђен"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користите PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користите шаблон"</string>
@@ -289,6 +294,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење микрофона."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење камере."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење камере или микрофона."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Други уређај"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Укључи/искључи преглед"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Неће вас узнемиравати звукови и вибрације осим за аларме, подсетнике, догађаје и позиваоце које наведете. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре."</string>
@@ -322,7 +345,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Базна станица за пуњење • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Уклони"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Добро дошли назад, госте!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string>
@@ -772,6 +794,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Додај"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Предлаже <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Уређај је закључан"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN садржи слова или симболе"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Верификујте: <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Погрешан PIN"</string>
@@ -781,8 +815,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Превуците да бисте видели још"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Учитавају се препоруке"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медији"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Желите ли да сакријете ову контролу за медије за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Актуелна сесија медија не може да буде сакривена."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
@@ -822,6 +855,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Да бисте пребацивали ову сесију, отворите апликацију."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Заустави пребацивање"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
<string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
@@ -899,7 +946,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активне апликације"</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_copy" msgid="770856373439969178">"Копирај"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано је"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Из: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Одбаци копирање корисничког интерфејса"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index ffcb699454f2..30a3aa9d551e 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotera skärmen automatiskt"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vill du ge <xliff:g id="APPLICATION">%1$s</xliff:g> åtkomst till <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vill du ge <xliff:g id="APPLICATION">%1$s</xliff:g> åtkomst till <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAppen har inte fått inspelningsbehörighet men kan spela in ljud via denna USB-enhet."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Vill du ge <xliff:g id="APPLICATION">%1$s</xliff:g> åtkomst till <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Vill du öppna <xliff:g id="APPLICATION">%1$s</xliff:g> och hantera <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Appen har inte fått inspelningsbehörighet men kan spela in ljud via denna USB-enhet. Om du använder <xliff:g id="APPLICATION">%1$s</xliff:g> med enheten kanske du inte hör samtal, aviseringar eller alarm."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Om du använder <xliff:g id="APPLICATION">%1$s</xliff:g> med enheten kanske du inte hör samtal, aviseringar eller alarm."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Vill du ge <xliff:g id="APPLICATION">%1$s</xliff:g> åtkomst till <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Vill du öppna <xliff:g id="APPLICATION">%1$s</xliff:g> och hantera <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Vill du öppna <xliff:g id="APPLICATION">%1$s</xliff:g> för att hantera <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAppen har inte fått inspelningsbehörighet men kan spela in ljud via denna USB-enhet."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Låstes upp med ansiktet. Tryck för att fortsätta."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Använd pinkod"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Använd mönster"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Detta återaktiverar åtkomsten för alla appar och tjänster som tillåts att använda mikrofonen."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Detta återaktiverar åtkomsten för alla appar och tjänster som tillåts att använda kameran."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Detta återaktiverar åtkomsten för alla appar och tjänster som tillåts att använda kameran eller mikrofonen."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Annan enhet"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Aktivera och inaktivera översikten"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Du blir inte störd av ljud och vibrationer, förutom från alarm, påminnelser, händelser och specifika samtal. Ljudet är fortfarande på för sådant du väljer att spela upp, till exempel musik, videor och spel."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Dockningsstation • Fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Byt användare"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ta bort"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Välkommen tillbaka som gäst!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Lägg till"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Förslag från <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Enheten är låst"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pinkoden innehåller bokstäver eller symboler"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verifiera <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Fel pinkod"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Svep om du vill se mer"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Rekommendationer läses in"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Vill du dölja detta uppspelningsreglage för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Den aktuella mediesessionen kan inte döljas."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Dölj"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öppna appen om du vill casta den här sessionen."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Okänd app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sluta casta"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
<string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiva appar"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stoppa"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stoppad"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopiera"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopierades"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Från <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Stäng användargränssnittet för kopiering"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9ad8f78a92eb..e7180e45e857 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Skrini ijizungushe kiotomatiki"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nProgramu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Ungependa kufungua <xliff:g id="APPLICATION">%1$s</xliff:g> ishughulikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Programu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB. Ukitumia <xliff:g id="APPLICATION">%1$s</xliff:g> kwenye kifaa hiki kunaweza kuzuia kusikia simu, arifa na kengele."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ukitumia <xliff:g id="APPLICATION">%1$s</xliff:g> kwenye kifaa hiki kunaweza kuzuia kusikia simu, arifa na kengele."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Ungependa kufungua <xliff:g id="APPLICATION">%1$s</xliff:g> ili itumie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Ungependa kufungua <xliff:g id="APPLICATION">%1$s</xliff:g> ishughulikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nProgramu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili uendelee."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Umethibitishwa"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Tumia PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Tumia mchoro"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Hatua hii huruhusu programu na huduma zote zenye idhini zitumie maikrofoni yako."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Hatua hii huruhusu programu na huduma zote zenye idhini zitumie kamera yako."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Hatua hii huruhusu programu na huduma zote zenye idhini zitumie kamera au maikrofoni yako."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Kifaa kingine"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Washa Muhtasari"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Hutasumbuliwa na sauti na mitetemo, isipokuwa kengele, vikumbusho, matukio na simu zinazopigwa na watu uliobainisha. Bado utasikia chochote utakachochagua kucheza, ikiwa ni pamoja na muziki, video na michezo."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Kituo cha Kuchaji • Itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Badili mtumiaji"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ondoa"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Karibu tena mgeni!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza upya"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Weka"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Kimependekezwa na <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Kifaa kimefungwa"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ina herufi au alama"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Thibitisha <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Nambari ya PIN si sahihi"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Telezesha kidole ili uone zaidi"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Inapakia mapendekezo"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Maudhui"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Ungependa kuficha kidhibiti hiki cha maudhui kwa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Kipindi cha sasa cha maudhui hakiwezi kufichwa."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ficha"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ili utume kipindi hiki, tafadhali fungua programu."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Programu isiyojulikana"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Acha kutuma"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
<string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Programu zinazotumika"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Simamisha"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Imesimamishwa"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Nakili"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Imenakiliwa"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Kutoka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ondoa kiolesura cha nakala"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 41824e6ee40b..0ebf998b8ca9 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"திரையைத் தானாகச் சுழற்று"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ஐ அணுக, <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ஐப் பயன்படுத்த <xliff:g id="APPLICATION">%1$s</xliff:g>ஐ அனுமதிக்கவா?\nஇந்த ஆப்ஸிற்கு ரெக்கார்டு செய்வதற்கான அனுமதி வழங்கப்படவில்லை, எனினும் இந்த USB சாதனம் மூலம் ஆடியோவைப் பதிவுசெய்யும்."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> சாதனத்தை அணுக <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> சாதனத்தைக் கையாள <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸைத் திறக்கவா?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"இந்த ஆப்ஸில் ரெக்கார்டு செய்வதற்கு அனுமதி இல்லை, எனினும் இந்த USB சாதனம் மூலம் ஆடியோவைப் பதிவுசெய்யலாம். இந்தச் சாதனத்தில் <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸைப் பயன்படுத்தினால் அழைப்புகள், அறிவிப்புகள், அலாரங்கள் ஆகியவற்றின் ஒலி கேட்பது தடுக்கப்படக்கூடும்."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"இந்தச் சாதனத்தில் <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸைப் பயன்படுத்தினால் அழைப்புகள், அறிவிப்புகள், அலாரங்கள் ஆகியவற்றின் ஒலி கேட்பது தடுக்கப்படக்கூடும்."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ஐ அணுக, <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ஐக் கையாள, <xliff:g id="APPLICATION">%1$s</xliff:g> பயன்பாட்டைத் திறக்கவா?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ஐக் கையாள <xliff:g id="APPLICATION">%1$s</xliff:g>ஐத் திறக்கவா?\nஇந்த ஆப்ஸிற்கு ரெக்கார்டு செய்வதற்கான அனுமதி வழங்கப்படவில்லை, எனினும் இந்த USB சாதனம் மூலம் ஆடியோவைப் பதிவுசெய்ய முடியும்."</string>
@@ -131,7 +135,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="1597899891472340950">"முகத்தை வைத்து அன்லாக் செய்யப்பட்டது. திறக்க அழுத்தவும்."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"அங்கீகரிக்கப்பட்டது"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"பின்னைப் பயன்படுத்து"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"பேட்டர்னைப் பயன்படுத்து"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"உங்கள் மைக்ரோஃபோனைப் பயன்படுத்த அனுமதிக்கப்பட்டுள்ள அனைத்து ஆப்ஸ் மற்றும் சேவைகளை அணுகுவதற்கான தடுப்பை இது நீக்கும்."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"உங்கள் கேமராவைப் பயன்படுத்த அனுமதிக்கப்பட்டுள்ள அனைத்து ஆப்ஸ் மற்றும் சேவைகளை அணுகுவதற்கான தடுப்பை இது நீக்கும்."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"உங்கள் கேமராவையோ மைக்ரோஃபோனையோ பயன்படுத்த அனுமதிக்கப்பட்டுள்ள அனைத்து ஆப்ஸ் மற்றும் சேவைகளை அணுகுவதற்கான தடுப்பை இது நீக்கும்."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"பிற சாதனம்"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"மேலோட்டப் பார்வையை நிலைமாற்று"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள் மற்றும் குறிப்பிட்ட அழைப்பாளர்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள், கேம்ஸ் போன்றவை) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • டாக் மூலம் சார்ஜாகிறது • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> இல் முழுமையாகச் சார்ஜாகிவிடும்"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"பயனரை மாற்று"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"அகற்று"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"நல்வரவு!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"உங்கள் அமர்வைத் தொடர விருப்பமா?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"மீண்டும் தொடங்கு"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"சேர்"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ஆப்ஸால் பரிந்துரைக்கப்பட்டது"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"சாதனம் பூட்டப்பட்டது"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"இந்த அமர்வை அலைபரப்ப ஆப்ஸைத் திறங்கள்."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"அறியப்படாத ஆப்ஸ்"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"அலைபரப்புவதை நிறுத்து"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
<string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"செயலிலுள்ள ஆப்ஸ்"</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_copy" msgid="770856373439969178">"நகலெடு"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"நகலெடுக்கப்பட்டது"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸிலிருந்து"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"கிளிப்போர்டு மேலடுக்கை மூடுக"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 38489a20001d..a7851a0167e7 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"స్క్రీన్ ఆటో-రొటేట్‌"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ని యాక్సెస్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ని అనుమతించాలా?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>యాక్సెస్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ను అనుమతించాలా?\nఈ యాప్‌నకు రికార్డ్ చేసే అనుమతి మంజూరు చేయబడలేదు, కానీ ఈ USB పరికరం ద్వారా ఆడియోను క్యాప్చర్ చేయగలదు."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>‌ను యాక్సెస్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>‌ను అనుమతించాలా?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>‌ను నిర్వహించడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>‌ను తెరవాలా?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ఈ యాప్‌నకు రికార్డ్ చేసే అనుమతి మంజూరు కాలేదు, అయినా ఈ USB పరికరం ద్వారా ఆడియోను క్యాప్చర్ చేయగలదు. ఈ పరికరంలో <xliff:g id="APPLICATION">%1$s</xliff:g>‌ను ఉపయోగించడం వలన కాల్స్, నోటిఫికేషన్‌లు, అలారంలను వినబడనీయకుండా నివారించవచ్చు."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ఈ పరికరంలో <xliff:g id="APPLICATION">%1$s</xliff:g>‌ను ఉపయోగించడం వలన కాల్స్, నోటిఫికేషన్‌లు, అలారంలను వినబడనీయకుండా నివారించవచ్చు."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ని యాక్సెస్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ని అనుమతించాలా?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ని నిర్వహించడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ని తెరవాలా?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ని హ్యాండిల్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ను తెరవాలా?\nఈ యాప్‌కు రికార్డ్ చేసే అనుమతి మంజూరు కాలేదు, అయినా ఈ USB పరికరం ద్వారా ఆడియోను క్యాప్చర్ చేయగలదు."</string>
@@ -131,7 +135,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="1597899891472340950">"మీ ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి నొక్కండి."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ప్రామాణీకరించబడింది"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"పిన్‌ను ఉపయోగించు"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ఆకృతిని ఉపయోగించు"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"మీ మైక్రోఫోన్‌ను ఉపయోగించడానికి అనుమతి పొందిన అన్ని యాప్‌లు, సర్వీస్‌లకు యాక్సెస్‌ను ఇది అన్‌బ్లాక్ చేస్తుంది."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ఇది, మీ కెమెరాను ఉపయోగించడానికి అనుమతి పొందిన అన్ని యాప్‌లకు, సర్వీస్‌లకు యాక్సెస్‌ను అన్‌బ్లాక్ చేస్తుంది."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ఇది, మీ కెమెరాను లేదా మైక్రోఫోన్‌ను ఉపయోగించడానికి అనుమతి పొందిన అన్ని యాప్‌లకు, సర్వీస్‌లకు యాక్సెస్‌ను అన్‌బ్లాక్ చేస్తుంది."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"ఇతర పరికరం"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"స్థూలదృష్టిని టోగుల్ చేయి"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"మీరు పేర్కొనే అలారాలు, రిమైండర్‌లు, ఈవెంట్‌లు మరియు కాలర్‌ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ఛార్జింగ్ డాక్ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"వినియోగదారుని మార్చు"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్‌లోని అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"తీసివేయి"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"గెస్ట్‌కు తిరిగి స్వాగతం!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్‌ని కొనసాగించాలనుకుంటున్నారా?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"జోడించండి"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ద్వారా సూచించబడింది"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"పరికరంలాక్ చేయబడింది"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<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>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ఈ సెషన్‌ను ప్రసారం చేయడానికి, దయచేసి యాప్‌ను తెరవండి."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"తెలియని యాప్"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ప్రసారాన్ని ఆపివేయండి"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
<string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"యాక్టివ్‌గా ఉన్న యాప్‌లు"</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_copy" msgid="770856373439969178">"కాపీ చేయండి"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"కాపీ అయింది"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> నుండి"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"కాపీ UIని విస్మరించండి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 3daf67f4d747..e3f44b10509c 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"หมุนหน้าจออัตโนมัติ"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม\nแอปนี้ไม่ได้รับอนุญาตให้อัดเสียงแต่จะอัดเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง<xliff:g id="USB_DEVICE">%2$s</xliff:g> ใช่ไหม"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"เปิด <xliff:g id="APPLICATION">%1$s</xliff:g> เพื่อจัดการ<xliff:g id="USB_DEVICE">%2$s</xliff:g> ใช่ไหม"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"แอปนี้ไม่ได้รับอนุญาตให้อัดเสียงแต่จะอัดเสียงผ่านอุปกรณ์ USB นี้ได้ การใช้ <xliff:g id="APPLICATION">%1$s</xliff:g> กับอุปกรณ์นี้อาจทำให้คุณไม่ได้ยินเสียงสายเรียกเข้า การแจ้งเตือน และการปลุก"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"การใช้ <xliff:g id="APPLICATION">%1$s</xliff:g> กับอุปกรณ์นี้อาจทำให้คุณไม่ได้ยินเสียงสายเรียกเข้า การแจ้งเตือน และการปลุก"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ไหม"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"เปิด <xliff:g id="APPLICATION">%1$s</xliff:g> เพื่อจัดการ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"เปิด <xliff:g id="APPLICATION">%1$s</xliff:g> เพื่อจัดการ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ใช่ไหม\nแอปนี้ไม่ได้รับอนุญาตให้อัดเสียงแต่จะอัดเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
@@ -131,7 +135,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="1597899891472340950">"ปลดล็อกโดยใช้ใบหน้าแล้ว กดเพื่อดำเนินการต่อ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ตรวจสอบสิทธิ์แล้ว"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ใช้ PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ใช้รูปแบบ"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"การดำเนินการนี้จะเลิกบล็อกสิทธิ์เข้าถึงของแอปและบริการทั้งหมดที่ได้รับอนุญาตให้ใช้ไมโครโฟนของคุณ"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"การดำเนินการนี้จะเลิกบล็อกสิทธิ์เข้าถึงของแอปและบริการทั้งหมดที่ได้รับอนุญาตให้ใช้กล้องของคุณ"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"การดำเนินการนี้จะเลิกบล็อกสิทธิ์เข้าถึงของแอปและบริการทั้งหมดที่ได้รับอนุญาตให้ใช้กล้องหรือไมโครโฟนของคุณ"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"อุปกรณ์อื่น"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"สลับภาพรวม"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นเสียงนาฬิกาปลุก การช่วยเตือน กิจกรรม และผู้โทรที่ระบุไว้ คุณจะยังคงได้ยินสิ่งที่คุณเลือกเล่น เช่น เพลง วิดีโอ และเกม"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • กำลังชาร์จบนแท่นชาร์จ • จะเต็มในอีก <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"สลับผู้ใช้"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"นำออก"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ยินดีต้อนรับผู้เข้าร่วมกลับมาอีกครั้ง"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"เพิ่ม"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"แนะนำโดย <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"อุปกรณ์ถูกล็อก"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"แสดงและควบคุมอุปกรณ์จากหน้าจอล็อกไหม"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"คุณเพิ่มการควบคุมอุปกรณ์ภายนอกลงในหน้าจอล็อกได้\n\nแอปของอุปกรณ์อาจอนุญาตให้คุณควบคุมอุปกรณ์บางอย่างได้โดยไม่ต้องปลดล็อกโทรศัพท์หรือแท็บเล็ต\n\nคุณเปลี่ยนแปลงได้ทุกเมื่อในการตั้งค่า"</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ควบคุมอุปกรณ์จากหน้าจอล็อกไหม"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"คุณควบคุมอุปกรณ์บางอย่างได้โดยไม่ต้องปลดล็อกโทรศัพท์หรือแท็บเล็ต\n\nแอปของอุปกรณ์จะระบุอุปกรณ์ที่สามารถควบคุมด้วยวิธีนี้ได้"</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ไม่เป็นไร"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"มี"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ประกอบด้วยตัวอักษรหรือสัญลักษณ์"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"ยืนยัน <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN ไม่ถูกต้อง"</string>
@@ -815,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"โปรดเปิดแอปหากต้องการแคสต์เซสชันนี้"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"แอปที่ไม่รู้จัก"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"หยุดแคสต์"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
<string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string>
@@ -891,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ใช้งานอยู่"</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_copy" msgid="770856373439969178">"คัดลอก"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"เสร็จ"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"คัดลอกแล้ว"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"จาก <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"ปิด UI การคัดลอก"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 0ae32928c91a..0fc2195cc87f 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"I-auto rotate ang screen"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Payagan ang <xliff:g id="APPLICATION">%1$s</xliff:g> na ma-access ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Payagan ang <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nHindi nabigyan ng pahintulot ang app na ito para mag-record pero nakakapag-capture ito ng audio sa pamamagitan ng USB device na ito."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Payagan ang <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Buksan ang <xliff:g id="APPLICATION">%1$s</xliff:g> para pangasiwaan ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Hindi nabigyan ng pahintulot ang app na ito na mag-record pero puwede itong mag-capture ng audio sa pamamagitan ng USB device na ito. Kapag ginamit ang <xliff:g id="APPLICATION">%1$s</xliff:g> sa device na ito, posibleng hindi marinig ang mga tawag, notification, at alarm."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Kapag ginamit ang <xliff:g id="APPLICATION">%1$s</xliff:g> sa device na ito, posibleng hindi marinig ang mga tawag, notification, at alarm."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Payagan ang <xliff:g id="APPLICATION">%1$s</xliff:g> na ma-access ang <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Buksan ang <xliff:g id="APPLICATION">%1$s</xliff:g> upang pamahalaan ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Buksan ang <xliff:g id="APPLICATION">%1$s</xliff:g> para pangasiwaan ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nHindi nabigyan ng pahintulot ang app na ito para mag-record pero nakakapag-capture ito ng audio sa pamamagitan ng USB device na ito."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Na-unlock gamit ang mukha mo. Pindutin para magpatuloy."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Na-authenticate"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gumamit ng PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gumamit ng pattern"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ina-unblock nito ang access para sa lahat ng app at serbisyong pinapayagang gumamit ng iyong mikropono."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ina-unblock nito ang access para sa lahat ng app at serbisyong pinapayagang gumamit ng iyong camera."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ina-unblock nito ang access para sa lahat ng app at serbisyong pinapayagang gumamit ng iyong camera o mikropono."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Iba pang device"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"I-toggle ang Overview"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Hindi ka maiistorbo ng mga tunog at pag-vibrate, maliban mula sa mga alarm, paalala, event, at tumatawag na tutukuyin mo. Maririnig mo pa rin ang kahit na anong piliin mong i-play kabilang ang mga musika, video, at laro."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging Dock • Mapupuno sa loob ng <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alisin"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome ulit, bisita!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string>
@@ -766,6 +788,12 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Idagdag"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Iminungkahi ng <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Naka-lock ang device"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Ipakita at kontrolin ang mga device mula sa lock screen?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Puwede kang magdagdag ng mga kontrol para sa iyong mga external device sa lock screen.\n\nPosibleng payagan ka ng app ng iyong device na kontrolin ang ilang device nang hindi ina-unlock ang telepono o tablet mo.\n\nPuwede kang magsagawa ng mga pagbabago anumang oras sa Mga Setting."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Kontrolin ang mga device mula sa lock screen?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Puwede mong kontrolin ang ilang device nang hindi ina-unlock ang iyong telepono o tablet.\n\nNakadepende sa app ng iyong device kung aling mga device ang puwedeng kontrolin sa ganitong paraan."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Huwag na lang"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Oo"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"May mga titik o simbolo ang PIN"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"I-verify ang <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Maling PIN"</string>
@@ -815,6 +843,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para ma-cast ang session na ito, buksan ang app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Hindi kilalang app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ihinto ang pag-cast"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
<string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string>
@@ -891,7 +933,7 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Mga aktibong app"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ihinto"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Inihinto"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopyahin"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Tapos na"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nakopya"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Mula sa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"I-dismiss ang UI ng pagkopya"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 8fe3e346bf0c..3f2972cbede9 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ekranı otomatik döndür"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına erişmesine izin verilsin mi?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına erişmesine izin verilsin mi?\nBu uygulamaya kayıt izni verilmemiş ancak bu USB cihazı aracılığıyla sesleri yakalayabilir."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına erişmesine izin verilsin mi?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> aksesuarını işlemek için <xliff:g id="APPLICATION">%1$s</xliff:g> uygulaması açılsın mı?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Bu uygulamaya ses kaydetme izni verilmedi ancak bu USB cihazı üzerinden sesleri yakalayabilir. <xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının bu cihazla kullanılması aramaları, bildirimleri ve alarmları duymayı engelleyebilir."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının bu cihazla kullanılması aramaları, bildirimleri ve alarmları duymayı engelleyebilir."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> aksesuarına erişmesine izin verilsin mi?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını işlemek için <xliff:g id="APPLICATION">%1$s</xliff:g> uygulaması açılsın mı?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> için <xliff:g id="APPLICATION">%1$s</xliff:g> uygulaması açılsın mı?\n Bu uygulamaya kayıt izni verilmemiş, ancak bu USB cihazı aracılığıyla sesleri yakalabilir."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Kilit, yüzünüzle açıldı. Devam etmek için basın."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kimliği Doğrulandı"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kullan"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Deseni kullan"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Bu işlem, mikrofonunuzu kullanmasına izin verilen tüm uygulama ve hizmetlere erişimin engellemesini kaldırır."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Bu işlem, kameranızı kullanmasına izin verilen tüm uygulama ve hizmetlere erişimin engellemesini kaldırır."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Bu işlem, kamera veya mikrofonunuzu kullanmasına izin verilen tüm uygulama ve hizmetlere erişimin engellemesini kaldırır."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Diğer cihaz"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Genel bakışı aç/kapat"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Alarmlar, hatırlatıcılar, etkinlikler ve sizin seçtiğiniz kişilerden gelen çağrılar dışında hiçbir ses ve titreşimle rahatsız edilmeyeceksiniz. O sırada çaldığınız müzik, seyrettiğiniz video ya da oynadığınız oyunların sesini duymaya devam edeceksiniz."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Yuvada Şarj Oluyor • Dolmasına <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> kaldı"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştirme"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kaldır"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Misafir kullanıcı, tekrar hoşgeldiniz"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ekle"</string>
<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>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN, harf veya simge içerir"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> cihazını doğrulayın"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Yanlış PIN"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Diğer öğeleri görmek için hızlıca kaydırın"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Öneriler yükleniyor"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medya"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> için bu medya kontrolü gizlensin mi?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Geçerli medya oturumu gizlenemez."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizle"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Devam ettir"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu oturumu yayınlamak için lütfen uygulamayı açın."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Bilinmeyen uygulama"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayını durdur"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
<string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Etkin uygulamalar"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Durdur"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Durduruldu"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopyala"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopyalandı"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasından"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopyalanan kullanıcı arayüzünü kapat"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index b234deee1f67..e2240e23a2c5 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Автообертання екрана"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Надати додатку <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до такого аксесуара: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Надати додатку <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nЦей додаток не має дозволу на записування звуку, але може фіксувати його через цей USB-пристрій."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Надати додатку <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до пристрою (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Відкрити додаток <xliff:g id="APPLICATION">%1$s</xliff:g>, щоб використовувати пристрій (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Додаток не має дозволу на запис, але він може фіксувати звук через цей USB-пристрій. Якщо додаток <xliff:g id="APPLICATION">%1$s</xliff:g> використовується з цим пристроєм, звук дзвінків, сповіщень і будильників може не відтворюватися."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Якщо додаток <xliff:g id="APPLICATION">%1$s</xliff:g> використовується з цим пристроєм, звук дзвінків, сповіщень і будильників може не відтворюватися."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Надати додатку <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до такого аксесуара: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Відкрити додаток <xliff:g id="APPLICATION">%1$s</xliff:g>, щоб використовувати такий аксесуар: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Працювати з пристроєм \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\" у додатку <xliff:g id="APPLICATION">%1$s</xliff:g>?\nУ цього додатка немає дозволів на запис, але він може передавати звук у USB-пристрій."</string>
@@ -131,7 +135,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="1597899891472340950">"Розблоковано: фейсконтроль. Натисніть, щоб продовжити."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Ввести PIN-код"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Намалювати ключ"</string>
@@ -291,6 +296,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Усі додатки та сервіси, яким дозволено користуватися вашим мікрофоном, отримають доступ."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Усі додатки та сервіси, яким дозволено користуватися вашою камерою, отримають доступ."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Усі додатки та сервіси, яким дозволено користуватися вашою камерою чи мікрофоном, отримають доступ."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Інший пристрій"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Увімкнути або вимкнути огляд"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Ви отримуватиме звукові та вібросигнали лише для вибраних будильників, нагадувань, подій і абонентів. Однак ви чутимете все, що захочете відтворити, зокрема музику, відео й ігри."</string>
@@ -324,7 +347,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Док-станція для заряджання • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до повного заряду"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Змінити користувача"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Вийти"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"З поверненням!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Продовжити сеанс?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почати знову"</string>
@@ -778,6 +800,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Додати"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Запропоновано додатком <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Пристрій заблоковано"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код містить літери чи символи"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Неправильний PIN-код"</string>
@@ -787,8 +821,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Гортайте, щоб переглянути інші"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Завантаження рекомендацій"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медіа"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Приховати цей елемент керування медіасеансом для <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Поточний медіасеанс не можна приховати."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Приховати"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Відновити"</string>
@@ -828,6 +861,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Щоб транслювати цей сеанс, відкрийте додаток."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невідомий додаток"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Припинити трансляцію"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
<string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string>
@@ -906,7 +953,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активні додатки"</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_copy" msgid="770856373439969178">"Копіювати"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скопійовано"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"З додатка <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрити вікно копіювання"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 0ee6b54905ea..a6d72279cda2 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"سکرین کو خودکار طور پر گھمائیں"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> کو <xliff:g id="USB_DEVICE">%2$s</xliff:g> تک رسائی حاصل کرنے کی اجازت دیں؟"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"‏<xliff:g id="APPLICATION">%1$s</xliff:g> کو <xliff:g id="USB_DEVICE">%2$s</xliff:g> تک رسائی دیں؟\nاس ایپ کو ریکارڈ کی اجازت عطا نہیں کی گئی ہے مگر اس USB آلہ سے کیپچر کر سکتے ہیں۔"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> کو <xliff:g id="USB_DEVICE">%2$s</xliff:g> تک رسائی حاصل کرنے کی اجازت دیں؟"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ہینڈل کرنے کیلئے <xliff:g id="APPLICATION">%1$s</xliff:g> کھولیں؟"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"‏اس ایپ کو ریکارڈ کرنے کی اجازت عطا نہیں کی گئی ہے مگر اس USB آلہ کے ذریعے آڈیو کیپچر کر سکتی ہے۔ اس آلہ پر <xliff:g id="APPLICATION">%1$s</xliff:g> کا استعمال آپ کو کالز، اطلاعات اور الارمز سننے سے روک سکتا ہے۔"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"اس آلہ پر <xliff:g id="APPLICATION">%1$s</xliff:g> کا استعمال آپ کو کالز، اطلاعات اور الارمز سننے سے روک سکتا ہے۔"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> کو <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> تک رسائی حاصل کرنے کی اجازت دیں؟"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ہینڈل کرنے کیلئے <xliff:g id="APPLICATION">%1$s</xliff:g> کھولیں؟"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"‏<xliff:g id="USB_DEVICE">%2$s</xliff:g> کو ہینڈل کرنے کے ليے <xliff:g id="APPLICATION">%1$s</xliff:g> کھولیں؟ \nاس ایپ کو ریکارڈ کی اجازت عطا نہیں کی گئی ہے مگر اس USB آلہ سے کیپچر کر سکتے ہیں۔"</string>
@@ -131,7 +135,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="1597899891472340950">"آپ کے چہرے سے غیر مقفل کیا گیا جاری رکھنے کے لیے دبائیں"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"تصدیق کردہ"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‏PIN استعمال کریں"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"پیٹرن کا استعمال کریں"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"اس سے آپ کا مائیکروفون استعمال کرنے کے لیے اجازت یافتہ سبھی ایپس اور سروسز کے لیے رسائی غیر مسدود ہو جاتی ہے۔"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"اس سے آپ کا کیمرا استعمال کرنے کے لیے اجازت یافتہ سبھی ایپس اور سروسز کے لیے رسائی غیر مسدود ہو جاتی ہے۔"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"اس سے آپ کا کیمرا یا مائیکروفون استعمال کرنے کے لیے اجازت یافتہ سبھی ایپس اور سروسز کے لیے رسائی غیر مسدود ہو جاتی ہے۔"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"دوسرا آلہ"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"مجموعی جائزہ ٹوگل کریں"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"الارمز، یاددہانیوں، ایونٹس اور آپ کے متعین کردہ کالرز کے علاوہ، آپ آوازوں اور وائبریشنز سے ڈسٹرب نہیں ہوں گے۔ موسیقی، ویڈیوز اور گیمز سمیت آپ ابھی بھی ہر وہ چیز سنیں گے جسے چلانے کا آپ انتخاب کرتے ہیں۔"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ڈاک چارج ہو رہا ہے • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> میں مکمل"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"صارف سوئچ کریں"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ہٹائیں"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"مہمان، پھر سے خوش آمدید!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"کیا آپ اپنا سیشن جاری رکھنا چاہتے ہیں؟"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"دوبارہ شروع کریں"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"شامل کریں"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> کی طرف سے تجویز کردہ"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"آلہ مقفل کر دیا گیا"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"‏PIN میں حروف یا علامات شامل ہیں"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"‫<xliff:g id="DEVICE">%s</xliff:g> کی تصدیق کریں"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"‏غلط PIN"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مزید دیکھنے کیلئے سوائپ کریں"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"تجاویز لوڈ ہو رہی ہیں"</string>
<string name="controls_media_title" msgid="1746947284862928133">"میڈیا"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے اس میڈیا کنٹرول کو چھپائیں؟"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"میڈیا کے موجودہ سیشن کو چھپایا نہیں جا سکتا۔"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"چھپائیں"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"اس سیشن کو کاسٹ کرنے کیلئے، براہ کرم ایپ کھولیں۔"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"نامعلوم ایپ"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"کاسٹ کرنا بند کریں"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
<string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"فعال ایپس"</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_copy" msgid="770856373439969178">"کاپی کریں"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"کاپی کر دیا گیا ہے"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> سے"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"‏کاپی شدہ UI کو برخاست کریں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 95111c717cac..d30dab6036e7 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ekranning avtomatik burilishi"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_DEVICE">%2$s</xliff:g> qurilmasidan foydalanishga ruxsat berilsinmi?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_DEVICE">%2$s</xliff:g> qurilmasidan foydalanish uchun ruxsat berilsinmi?\nBu ilovaga yozib olish ruxsati berilmagan, lekin shu USB orqali ovozlarni yozib olishi mumkin."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_DEVICE">%2$s</xliff:g> qurilmasidan foydalanishga ruxsat berilsinmi?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> bilan ishlash uchun <xliff:g id="APPLICATION">%1$s</xliff:g> ochilsinmi?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Bu ilovaga yozib olish ruxsati berilmagan, lekin shu USB orqali ovozlarni yozib olishi mumkin. Bu qurilma <xliff:g id="APPLICATION">%1$s</xliff:g> orqali boshqarilsa, chaqiruv, bildirishnoma va signallar eshitilmay qolishi mumkin."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Bu qurilma <xliff:g id="APPLICATION">%1$s</xliff:g> orqali boshqarilsa, chaqiruv, bildirishnoma va signallar eshitilmay qolishi mumkin."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> qurilmasidan foydalanishga ruxsat berilsinmi?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> bilan ishlash uchun <xliff:g id="APPLICATION">%1$s</xliff:g> ochilsinmi?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_DEVICE">%2$s</xliff:g> qurilmasidan foydalanish uchun ruxsat berilsinmi?\nBu ilovaga yozib olish ruxsati berilmagan, lekin shu USB orqali ovozlarni yozib olishi mumkin."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Yuz bilan ochildi. Davom etish uchun bosing."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Tasdiqlandi"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kod kiritish"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Grafik kalitdan foydalanish"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Mikrofoningizdan foydalanishga ruxsat berilgan barcha ilovalar va xizmatlar uchun ruxsatni blokdan chiqaradi."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Kamerangizdan foydalanishga ruxsat berilgan barcha ilovalar va xizmatlar uchun ruxsatni blokdan chiqaradi."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Kamera va mikrofoningizdan foydalanishga ruxsat berilgan barcha ilovalar va xizmatlar uchun ruxsatni blokdan chiqaradi."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Boshqa qurilma"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Umumiy nazar rejimini almashtirish"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Turli ovoz va tebranishlar endi sizni bezovta qilmaydi. Biroq, signallar, eslatmalar, tadbirlar haqidagi bildirishnomalar va siz tanlagan abonentlardan kelgan chaqiruvlar bundan mustasno. Lekin, ijro etiladigan barcha narsalar, jumladan, musiqa, video va o‘yinlar ovozi eshitiladi."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Dok-stansiya • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> qoldi"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Olib tashlash"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Xush kelibsiz, mehmon!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Seansni davom ettirmoqchimisiz?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Boshidan boshlansin"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Kiritish"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> taklif etgan"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Qurilma qulflandi"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Harflar yoki maxsus belgilardan iborat PIN kod"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Tekshirish: <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN kod xato"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Batafsil axborot olish uchun suring"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tavsiyalar yuklanmoqda"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun media boshqaruvi yashirilsinmi?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Joriy media seansi berkitilmadi."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Berkitish"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu seansni translatsiya qilish uchun ilovani oching."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Notanish ilova"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Toʻxtatish"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
<string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Faol ilovalar"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Toʻxtatildi"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Nusxa olish"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nusxa olindi"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Manba: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI nusxasini bekor qilish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index b88e838c3a13..02d52292ba6b 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Tự động xoay màn hình"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Cho phép <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Cho phép <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập vào <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nỨng dụng này chưa được cấp quyền ghi âm nhưng vẫn có thể ghi âm thông qua thiết bị USB này."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Cho phép <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập vào <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Mở <xliff:g id="APPLICATION">%1$s</xliff:g> để điều khiển <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ứng dụng này chưa được cấp quyền ghi âm nhưng vẫn có thể ghi âm thông qua thiết bị USB này. Việc sử dụng <xliff:g id="APPLICATION">%1$s</xliff:g> cùng với thiết bị này có thể giúp bạn tránh phải nghe cuộc gọi, thông báo và chuông báo."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Việc sử dụng <xliff:g id="APPLICATION">%1$s</xliff:g> cùng với thiết bị này có thể giúp bạn tránh phải nghe cuộc gọi, thông báo và chuông báo."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Cho phép <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Mở <xliff:g id="APPLICATION">%1$s</xliff:g> để điều khiển <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Mở <xliff:g id="APPLICATION">%1$s</xliff:g> để điều khiển <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDù chưa được cấp quyền ghi âm, nhưng ứng dụng có thể ghi âm thông qua thiết bị USB này."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Đã mở khoá bằng khuôn mặt bạn. Hãy nhấn để tiếp tục."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Đã xác thực"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Dùng mã PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Dùng hình mở khóa"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Thao tác này sẽ bỏ chặn quyền truy cập cho mọi ứng dụng và dịch vụ được phép sử dụng micrô của bạn."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Thao tác này sẽ bỏ chặn quyền truy cập cho mọi ứng dụng và dịch vụ được phép sử dụng máy ảnh của bạn."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Thao tác này sẽ bỏ chặn quyền truy cập cho mọi ứng dụng và dịch vụ được phép sử dụng máy ảnh hoặc micrô của bạn."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Thiết bị khác"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Bật/tắt chế độ xem Tổng quan"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Bạn sẽ không bị làm phiền bởi âm thanh và tiếng rung, ngoại trừ báo thức, lời nhắc, sự kiện và người gọi mà bạn chỉ định. Bạn sẽ vẫn nghe thấy mọi thứ bạn chọn phát, bao gồm nhạc, video và trò chơi."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Đế sạc • Sạc đầy sau <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Chuyển đổi người dùng"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Xóa"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Chào mừng bạn trở lại!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Bạn có muốn tiếp tục phiên của mình không?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Bắt đầu lại"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Thêm"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Do <xliff:g id="APP">%s</xliff:g> đề xuất"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Đã khóa thiết bị"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Mã PIN chứa các ký tự hoặc ký hiệu"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Xác minh <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Mã PIN sai"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Vuốt để xem thêm"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Đang tải các đề xuất"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Nội dung nghe nhìn"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Ẩn chế độ điều khiển nội dung nghe nhìn này cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Không thể ẩn phiên phát nội dung nghe nhìn hiện tại."</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ẩn"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Vui lòng mở ứng dụng để truyền phiên này."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ứng dụng không xác định"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dừng truyền"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string>
<string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ứng dụng đang hoạt động"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Dừng"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Đã dừng"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Sao chép"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Đã sao chép"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Từ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Đóng giao diện người dùng sao chép"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 69536f1cba7f..a44f39151190 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自动旋转屏幕"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"要允许<xliff:g id="APPLICATION">%1$s</xliff:g>访问<xliff:g id="USB_DEVICE">%2$s</xliff:g>吗?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"是否允许<xliff:g id="APPLICATION">%1$s</xliff:g>访问<xliff:g id="USB_DEVICE">%2$s</xliff:g>?\n此应用未获得录音权限,但能通过此 USB 设备录制音频。"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"允许“<xliff:g id="APPLICATION">%1$s</xliff:g>”访问<xliff:g id="USB_DEVICE">%2$s</xliff:g>吗?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"打开“<xliff:g id="APPLICATION">%1$s</xliff:g>”来处理<xliff:g id="USB_DEVICE">%2$s</xliff:g>吗?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"此应用未获得录音权限,但能通过此 USB 设备录制音频。在此设备上使用“<xliff:g id="APPLICATION">%1$s</xliff:g>”可能会将来电、通知和闹钟静音。"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"在此设备上使用“<xliff:g id="APPLICATION">%1$s</xliff:g>”可能会将来电、通知和闹钟静音。"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"要允许<xliff:g id="APPLICATION">%1$s</xliff:g>访问<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>吗?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"要打开<xliff:g id="APPLICATION">%1$s</xliff:g>来处理<xliff:g id="USB_DEVICE">%2$s</xliff:g>吗?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"要打开<xliff:g id="APPLICATION">%1$s</xliff:g>来使用<xliff:g id="USB_DEVICE">%2$s</xliff:g>吗?\n此应用未获得录音权限,但能通过此 USB 设备录制音频。"</string>
@@ -131,7 +135,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="1597899891472340950">"已通过面孔识别解锁。点按即可继续。"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已经过身份验证"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN 码"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用图案"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"这将会为所有获准使用您麦克风的应用和服务启用这项权限。"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"这将会为所有获准使用您摄像头的应用和服务启用这项权限。"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"这将会为所有获准使用您的摄像头或麦克风的应用和服务启用这项权限。"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"其他设备"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"切换概览"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"您将不会受到声音和振动的打扰(闹钟、提醒、活动和所指定来电者的相关提示音除外)。您依然可以听到您选择播放的任何内容(包括音乐、视频和游戏)的相关音效。"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在基座上充电 • 将于 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>后充满"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切换用户"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"访客,欢迎回来!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"要继续您的会话吗?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新开始"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"添加"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"来自<xliff:g id="APP">%s</xliff:g>的建议"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"设备已锁定"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 码由字母或符号组成"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"验证<xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN 码错误"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑动可查看更多结构"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在加载推荐内容"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒体"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"要针对“<xliff:g id="APP_NAME">%1$s</xliff:g>”隐藏此媒体控件吗?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"无法隐藏当前的媒体会话。"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"隐藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"继续播放"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如需投射此会话,请打开相关应用。"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"未知应用"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投射"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string>
<string name="basic_status" msgid="2315371112182658176">"开放式对话"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的应用"</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_copy" msgid="770856373439969178">"复制"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已复制"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"来自<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"关闭复制界面"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index ec282c347473..9f2f84f6a069 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自動旋轉螢幕"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?\n此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。如將「<xliff:g id="APPLICATION">%1$s</xliff:g>」與此裝置配合使用,您可能無法聽見來電、通知及鬧鐘的音效。"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"如將「<xliff:g id="APPLICATION">%1$s</xliff:g>」與此裝置配合使用,您可能無法聽見來電、通知及鬧鐘的音效。"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>」嗎?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」應用程式來控制「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?\n此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。"</string>
@@ -131,7 +135,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="1597899891472340950">"您已使用面孔解鎖。按下即可繼續操作。"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"驗證咗"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用圖案"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"解除封鎖後,凡有存取權的應用程式和服務都可使用您的麥克風。"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"解除封鎖後,凡有存取權的應用程式和服務都可使用您的相機。"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"解除封鎖後,凡有存取權的應用程式和服務都可使用您的相機或麥克風。"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"其他裝置"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"切換概覽"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"您不會受到聲音和震動騷擾 (鬧鐘、提醒、活動和您指定的來電者鈴聲除外)。當您選擇播放音樂、影片和遊戲等,仍可以聽到該內容的聲音。"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在插座上充電 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充滿電"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客您好,歡迎回來!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"您要繼續您的工作階段嗎?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"新增"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"由「<xliff:g id="APP">%s</xliff:g>」提供的建議"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"裝置已上鎖"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 含有字母或符號"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"驗證<xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN 錯誤"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動以查看更多"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒體"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"要隱藏此「<xliff:g id="APP_NAME">%1$s</xliff:g>」媒體控制嗎?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放此工作階段,請開啟應用程式。"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明應用程式"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
<string name="basic_status" msgid="2315371112182658176">"開啟對話"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</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_copy" msgid="770856373439969178">"複製"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已複製"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"來自「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"關閉剪貼簿使用者介面"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index e28cb1593c03..202bc4d02245 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自動旋轉螢幕"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?\n這個應用程式未取得錄製權限,但可以透過這部 USB 裝置錄製音訊。"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」以控制「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"這個應用程式未取得錄音的權限,但可以透過這部 USB 裝置錄製音訊。如果將「<xliff:g id="APPLICATION">%1$s</xliff:g>」應用程式與這部裝置搭配使用,可能不會聽見來電、通知和鬧鐘的音效。"</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"如果將「<xliff:g id="APPLICATION">%1$s</xliff:g>」應用程式與這部裝置搭配使用,可能不會聽見來電、通知和鬧鐘的音效。"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>」嗎?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」來使用「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?\n這個應用程式未取得錄製內容的權限,但可以透過這部 USB 裝置錄製音訊。"</string>
@@ -131,7 +135,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="1597899891472340950">"你已用自己的臉解鎖裝置,按下即可繼續操作。"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已通過驗證"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN 碼"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用解鎖圖案"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"這麼做可允許所有應用程式和服務使用麥克風。"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"這麼做可允許所有應用程式和服務使用相機。"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"這麼做可允許所有應用程式和服務使用相機或麥克風。"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"其他裝置"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"切換總覽"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"裝置不會發出音效或震動造成干擾,但是會保留與鬧鐘、提醒、活動和指定來電者有關的設定。如果你選擇播放音樂、影片和遊戲等內容,還是可以聽見相關音訊。"</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在座架上充電 • 將於 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充飽"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會遭到刪除。"</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客你好,歡迎回來!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續這個工作階段嗎?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"新增"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"來自「<xliff:g id="APP">%s</xliff:g>」的建議"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"裝置已鎖定"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 碼含有字母或符號"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"驗證「<xliff:g id="DEVICE">%s</xliff:g>」"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN 碼錯誤"</string>
@@ -775,8 +809,7 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動即可查看其他結構"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議控制項"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒體"</string>
- <!-- no translation found for controls_media_close_session (4780485355795635052) -->
- <skip />
+ <string name="controls_media_close_session" msgid="4780485355795635052">"要隱藏「<xliff:g id="APP_NAME">%1$s</xliff:g>」的這個媒體控制選項嗎?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string>
<string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
@@ -816,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放這個工作階段,請開啟應用程式。"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明的應用程式"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
<string name="basic_status" msgid="2315371112182658176">"開放式對話"</string>
@@ -892,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</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_copy" msgid="770856373439969178">"複製"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已複製"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"來自「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"關閉剪貼簿 UI"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 510a529e31b0..e14a589c2026 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -34,6 +34,10 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ukuzulazula kweskrini okuzenzakalelayo"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vumela i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukufinyelela i-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vumela i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukuthi ifinyelele ku-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nLolu hlelo lokusebenza alunikeziwe imvume yokurekhoda kodwa lingathatha umsindo ngale divayisi ye-USB."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Vumela i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukuze ufinyelele i-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Vula i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukuze ibambe i-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Le app ayinikezwanga imvume yokurekhoda kodwa ingathwebula umsindo ngale divayisi ye-USB. Ukusebenzisa i-<xliff:g id="APPLICATION">%1$s</xliff:g> ngale divayisi kungase kuvimbele ukuzwa amakholi, izaziso nama-alamu."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ukusebenzisa i-<xliff:g id="APPLICATION">%1$s</xliff:g> ngale divayisi kungase kuvimbele ukuzwa amakholi, izaziso nama-alamu."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Vumela i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukufinyelela i-<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Vula i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukuze uphath i-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Vula i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukuze uphathe i-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nLolu hlelo lokusebenza alinikeziwe imvume yokurekhoda kodwa lingathatha umsindo ngale divayisi ye-USB."</string>
@@ -131,7 +135,8 @@
<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="1597899891472340950">"Ivulwe ngobuso bakho. Cindezela ukuze uqhubeke."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (7538145860465755864) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kugunyaziwe"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Sebenzisa iphinikhodi"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Sebenzisa iphethini"</string>
@@ -287,6 +292,24 @@
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Lokhu kuvulela ukufinyelela kwawo wonke ama-app namasevisi avunyelwe ukusebenzisa imakrofoni yakho."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Lokhu kuvulela ukufinyelela kwawo wonke ama-app namasevisi avunyelwe ukusebenzisa ikhamera yakho."</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Lokhu kuvulela ukufinyelela kwawo wonke ama-app namasevisi avunyelwe ukusebenzisa ikhamera yakho noma imakrofoni."</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_title (2640140287496469689) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_title (7398084286822440384) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_title (195236134743281973) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_blocked_dialog_content (2138318880682877747) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_blocked_dialog_content (7216015168047965948) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_mic_camera_blocked_dialog_content (3960837827570483762) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_unblocked_toast_content (306555320557065068) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_camera_unblocked_toast_content (7843105715964332311) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_mic_camera_unblocked_toast_content (7339355093282661115) -->
+ <skip />
<string name="media_seamless_other_device" msgid="4654849800789196737">"Enye idivayisi"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Guqula ukubuka konke"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Ngeke uphazanyiswe imisindo nokudlidliza, ngaphandle kusukela kuma-alamu, izikhumbuzi, imicimbi, nabafonayo obacacisayo. Usazozwa noma yini okhetha ukuyidlala okufaka umculo, amavidiyo, namageyimu."</string>
@@ -320,7 +343,6 @@
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ukushaja Idokhi • Izogcwala ngo-<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Shintsha umsebenzisi"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Zonke izinhlelo zokusebenza nedatha kulesi sikhathi zizosuswa."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Susa"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Siyakwamukela futhi, sivakashi!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Ingabe ufuna ukuqhubeka ngesikhathi sakho?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Qala phansi"</string>
@@ -766,6 +788,18 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Engeza"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Kuphakanyiswe ngu-<xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Idivayisi ikhiyiwe"</string>
+ <!-- no translation found for controls_settings_show_controls_dialog_title (3357852503553809554) -->
+ <skip />
+ <!-- no translation found for controls_settings_show_controls_dialog_message (7666211700524587969) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_title (7593188157655036677) -->
+ <skip />
+ <!-- no translation found for controls_settings_trivial_controls_dialog_message (237183787721917586) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_neutral_button (4514446354793124140) -->
+ <skip />
+ <!-- no translation found for controls_settings_dialog_positive_button (436070672551674863) -->
+ <skip />
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Iphinikhodi iqukethe amaletha namasimbui"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Qinisekisa i-<xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"Iphinikhodi engalungile"</string>
@@ -815,6 +849,20 @@
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ukuze usakaze le seshini, sicela uvule i-app."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"I-app engaziwa"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Misa ukusakaza"</string>
+ <!-- no translation found for media_output_first_broadcast_title (6292237789860753022) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast (3555580945878071543) -->
+ <skip />
+ <!-- no translation found for media_output_first_notify_broadcast_message (6353857724136398494) -->
+ <skip />
+ <!-- no translation found for media_output_broadcasting_message (4150299923404886073) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_name (8786127091542624618) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_code (870795639644728542) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_dialog_save (7910865591430010198) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
<string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string>
@@ -891,7 +939,8 @@
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ama-app asebenzayo"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Misa"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Imisiwe"</string>
- <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Kopisha"</string>
+ <!-- no translation found for clipboard_edit_text_done (4551887727694022409) -->
+ <skip />
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Ikopishiwe"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"Kusukela ku-<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
<string name="clipboard_dismiss_description" msgid="7544573092766945657">"Chitha ukukopisha i-UI"</string>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 62903d5a7b35..3228c3c9d37f 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -188,12 +188,6 @@
<attr name="borderColor" format="color" />
</declare-styleable>
- <declare-styleable name="DualHeightHorizontalLinearLayout">
- <attr name="singleLineHeight" format="dimension" />
- <attr name="singleLineVerticalPadding" format="dimension" />
- <attr name="textViewId" format="reference" />
- </declare-styleable>
-
<attr name="overlayButtonTextColor" format="color" />
<declare-styleable name="DreamOverlayDotImageView">
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 50fdc7bb61bd..24118d256fcc 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -137,9 +137,11 @@
<!-- UDFPS colors -->
<color name="udfps_enroll_icon">#7DA7F1</color>
<color name="udfps_moving_target_fill">#475670</color>
+ <!-- 50% of udfps_moving_target_fill-->
+ <color name="udfps_moving_target_fill_error">#80475670</color>
<color name="udfps_enroll_progress">#7DA7F1</color>
<color name="udfps_enroll_progress_help">#607DA7F1</color>
- <color name="udfps_enroll_progress_help_with_talkback">#ffEE675C</color>
+ <color name="udfps_enroll_progress_help_with_talkback">#FFEE675C</color>
<!-- Floating overlay actions -->
<color name="overlay_button_ripple">#1f000000</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index d5331e8eae7e..f2ddf9e645b6 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -446,6 +446,10 @@
This name is in the ComponentName flattened format (package/class) -->
<string name="config_screenshotEditor" translatable="false"></string>
+ <!-- Remote copy default activity. Must handle REMOTE_COPY_ACTION intents.
+ This name is in the ComponentName flattened format (package/class) -->
+ <string name="config_remoteCopyPackage" translatable="false"></string>
+
<!-- On debuggable builds, alert the user if SystemUI PSS goes over this number (in kb) -->
<integer name="watch_heap_limit">256000</integer>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 7702724cec16..767225106f0d 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -327,23 +327,20 @@
car setting. -->
<dimen name="car_qs_header_system_icons_area_height">54dp</dimen>
- <!-- The height of the quick settings footer that holds the user switcher, settings icon,
- etc. -->
+ <!-- The height of the quick settings footer that holds the pagination dots and edit button -->
<dimen name="qs_footer_height">48dp</dimen>
<!-- 40dp (circles) + 8dp (circle padding) + 8dp (top) + 4dp (bottom) -->
- <dimen name="new_footer_height">60dp</dimen>
+ <dimen name="footer_actions_height">60dp</dimen>
<!-- The size of each of the icon buttons in the QS footer -->
<dimen name="qs_footer_action_button_size">48dp</dimen>
<dimen name="qs_footer_action_corner_radius">20dp</dimen>
- <!-- (48dp - 44dp) / 2 -->
- <dimen name="qs_footer_action_inset">2dp</dimen>
<!-- (48dp - 40dp) / 2 -->
- <dimen name="new_qs_footer_action_inset">4dp</dimen>
- <dimen name="new_qs_footer_action_inset_negative">-4dp</dimen>
+ <dimen name="qs_footer_action_inset">4dp</dimen>
+ <dimen name="qs_footer_action_inset_negative">-4dp</dimen>
<!-- Margins on each side of QS Footer -->
<dimen name="qs_footer_margin">2dp</dimen>
@@ -495,7 +492,7 @@
<dimen name="qs_panel_padding">16dp</dimen>
<dimen name="qs_dual_tile_padding_horizontal">6dp</dimen>
<dimen name="qs_panel_elevation">4dp</dimen>
- <dimen name="qs_panel_padding_bottom">@dimen/new_footer_height</dimen>
+ <dimen name="qs_panel_padding_bottom">@dimen/footer_actions_height</dimen>
<dimen name="qs_panel_padding_top">48dp</dimen>
<dimen name="qs_data_usage_text_size">14sp</dimen>
@@ -1429,6 +1426,8 @@
<!-- The margin applied between complications -->
<dimen name="dream_overlay_complication_margin">0dp</dimen>
+ <dimen name="dream_overlay_y_offset">80dp</dimen>
+
<dimen name="status_view_margin_horizontal">0dp</dimen>
<!-- Media output broadcast dialog QR code picture size -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 898f66d9939b..33ed7b8421db 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -338,7 +338,7 @@
<!-- Message shown when a biometric is authenticated, waiting for the user to confirm authentication [CHAR LIMIT=40]-->
<string name="biometric_dialog_tap_confirm">Tap Confirm to complete</string>
<!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
- <string name="biometric_dialog_tap_confirm_with_face">Unlocked by face. Press to continue.</string>
+ <string name="biometric_dialog_tap_confirm_with_face">Unlocked by face. Press the unlock icon to continue.</string>
<!-- Talkback string when a biometric is authenticated [CHAR LIMIT=NONE] -->
<string name="biometric_dialog_authenticated">Authenticated</string>
@@ -796,8 +796,11 @@
<!-- Message shown when lock screen is tapped or face authentication fails. [CHAR LIMIT=60] -->
<string name="keyguard_unlock">Swipe up to open</string>
- <!-- Message shown when lock screen is tapped or face authentication fails. Provides extra instructions for how the user can enter their device (unlock or proceed to home) [CHAR LIMIT=60] -->
- <string name="keyguard_unlock_press">Press to open</string>
+ <!-- Message shown when lock screen is unlocked (ie: by trust agent) and the user taps the empty space on the lock screen and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
+ <string name="keyguard_unlock_press">Press the unlock icon to open</string>
+
+ <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
+ <string name="keyguard_face_successful_unlock_press">Unlocked by face. Press the unlock icon to open.</string>
<!-- Message shown when face authentication fails and the pin pad is visible. [CHAR LIMIT=60] -->
<string name="keyguard_retry">Swipe up to try again</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 847aefdd67ce..ee77d210add5 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -958,6 +958,16 @@
<item name="android:textAlignment">center</item>
</style>
+ <!-- We explicitly overload this because we don't have control over the style or layout for
+ the cast dialog items, as it's in `@android:layout/media_route_list_item. -->
+ <style name="TextAppearance.CastItem" parent="@android:style/TextAppearance.DeviceDefault.Medium">
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ </style>
+
+ <style name="Theme.SystemUI.Dialog.Cast">
+ <item name="android:textAppearanceMedium">@style/TextAppearance.CastItem</item>
+ </style>
+ <!-- ************************************************************************************* -->
<style name="Widget" />
<style name="Widget.Dialog" />
diff --git a/packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt b/packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
index 497d81f6bdc5..1b2ea3b257ab 100644
--- a/packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
@@ -46,4 +46,24 @@ object BouncerPanelExpansionCalculator {
fun getKeyguardClockScaledExpansion(fraction: Float): Float {
return MathUtils.constrain((fraction - 0.7f) / 0.3f, 0f, 1f)
}
+
+ /**
+ * Scale the position of the dream complications.
+ */
+ @JvmStatic
+ fun getDreamYPositionScaledExpansion(fraction: Float): Float {
+ return when {
+ fraction >= 0.98f -> 1f
+ fraction < 0.93 -> 0f
+ else -> (fraction - 0.93f) / 0.05f
+ }
+ }
+
+ /**
+ * Scale the alpha of the dream complications.
+ */
+ @JvmStatic
+ fun getDreamAlphaScaledExpansion(fraction: Float): Float {
+ return MathUtils.constrain((fraction - 0.94f) / 0.06f, 0f, 1f)
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
index 36fe5ba1a851..5953611b454a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
@@ -21,7 +21,7 @@ data class KeyguardFingerprintListenModel(
override val listening: Boolean,
// keep sorted
val biometricEnabledForUser: Boolean,
- val bouncer: Boolean,
+ val bouncerIsOrWillShow: Boolean,
val canSkipBouncer: Boolean,
val credentialAttempted: Boolean,
val deviceInteractive: Boolean,
@@ -51,9 +51,10 @@ data class KeyguardFaceListenModel(
val authInterruptActive: Boolean,
val becauseCannotSkipBouncer: Boolean,
val biometricSettingEnabledForUser: Boolean,
- val bouncer: Boolean,
+ val bouncerFullyShown: Boolean,
val faceAuthenticated: Boolean,
val faceDisabled: Boolean,
+ val goingToSleep: Boolean,
val keyguardAwake: Boolean,
val keyguardGoingAway: Boolean,
val listeningForFaceAssistant: Boolean,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
index 33d47fe13f38..3aa5ada0794d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
@@ -123,10 +123,10 @@ public class KeyguardSecurityViewFlipperController
private int getLayoutIdFor(SecurityMode securityMode) {
switch (securityMode) {
- case Pattern: return com.android.systemui.R.layout.keyguard_pattern_view;
- case PIN: return com.android.systemui.R.layout.keyguard_pin_view;
- case Password: return com.android.systemui.R.layout.keyguard_password_view;
- case SimPin: return com.android.systemui.R.layout.keyguard_sim_pin_view;
+ case Pattern: return R.layout.keyguard_pattern_view;
+ case PIN: return R.layout.keyguard_pin_view;
+ case Password: return R.layout.keyguard_password_view;
+ case SimPin: return R.layout.keyguard_sim_pin_view;
case SimPuk: return R.layout.keyguard_sim_puk_view;
default:
return 0;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 736e34ead51a..ae9d3dfec3b2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -18,8 +18,13 @@ package com.android.keyguard;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
+import android.widget.ImageView;
+
+import androidx.core.graphics.drawable.DrawableCompat;
import com.android.systemui.R;
@@ -27,6 +32,7 @@ import com.android.systemui.R;
* Displays a PIN pad for unlocking.
*/
public class KeyguardSimPinView extends KeyguardPinBasedInputView {
+ private ImageView mSimImageView;
public static final String TAG = "KeyguardSimPinView";
public KeyguardSimPinView(Context context) {
@@ -62,6 +68,7 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
@Override
protected void onFinishInflate() {
+ mSimImageView = findViewById(R.id.keyguard_sim);
super.onFinishInflate();
if (mEcaView instanceof EmergencyCarrierArea) {
@@ -79,5 +86,17 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
return getContext().getString(
com.android.internal.R.string.keyguard_accessibility_sim_pin_unlock);
}
+
+ @Override
+ public void reloadColors() {
+ super.reloadColors();
+
+ int[] customAttrs = {android.R.attr.textColorSecondary};
+ TypedArray a = getContext().obtainStyledAttributes(customAttrs);
+ int imageColor = a.getColor(0, 0);
+ a.recycle();
+ Drawable wrappedDrawable = DrawableCompat.wrap(mSimImageView.getDrawable());
+ DrawableCompat.setTint(wrappedDrawable, imageColor);
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index 0394e76fc6bf..47df70b522f7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -131,6 +131,12 @@ public class KeyguardSimPinViewController
}
@Override
+ public void reloadColors() {
+ super.reloadColors();
+ mView.reloadColors();
+ }
+
+ @Override
protected void verifyPasswordAndUnlock() {
String entry = mPasswordEntry.getText();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 03b647bebeb0..760c2ccb71b5 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -17,8 +17,13 @@
package com.android.keyguard;
import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
+import android.widget.ImageView;
+
+import androidx.core.graphics.drawable.DrawableCompat;
import com.android.systemui.R;
@@ -27,6 +32,7 @@ import com.android.systemui.R;
* Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
*/
public class KeyguardSimPukView extends KeyguardPinBasedInputView {
+ private ImageView mSimImageView;
private static final boolean DEBUG = KeyguardConstants.DEBUG;
public static final String TAG = "KeyguardSimPukView";
@@ -79,6 +85,7 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
@Override
protected void onFinishInflate() {
+ mSimImageView = findViewById(R.id.keyguard_sim);
super.onFinishInflate();
if (mEcaView instanceof EmergencyCarrierArea) {
@@ -96,6 +103,18 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
return getContext().getString(
com.android.internal.R.string.keyguard_accessibility_sim_puk_unlock);
}
+
+ @Override
+ public void reloadColors() {
+ super.reloadColors();
+
+ int[] customAttrs = {android.R.attr.textColorSecondary};
+ TypedArray a = getContext().obtainStyledAttributes(customAttrs);
+ int imageColor = a.getColor(0, 0);
+ a.recycle();
+ Drawable wrappedDrawable = DrawableCompat.wrap(mSimImageView.getDrawable());
+ DrawableCompat.setTint(wrappedDrawable, imageColor);
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index ea94b190787c..47aa43b86599 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -113,6 +113,12 @@ public class KeyguardSimPukViewController
}
@Override
+ public void reloadColors() {
+ super.reloadColors();
+ mView.reloadColors();
+ }
+
+ @Override
protected void verifyPasswordAndUnlock() {
mStateMachine.next();
}
@@ -252,9 +258,6 @@ public class KeyguardSimPukViewController
return mPinText.equals(mPasswordEntry.getText());
}
-
-
-
private void updateSim() {
getSimUnlockProgressDialog().show();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 3b8a29bfe8c4..1383635a46d1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -21,6 +21,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.ACTION_USER_STOPPED;
import static android.content.Intent.ACTION_USER_UNLOCKED;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_PERMANENT;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_TIMED;
+import static android.hardware.biometrics.BiometricConstants.LockoutMode;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
@@ -61,6 +65,7 @@ import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.CancellationSignal;
@@ -275,7 +280,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private boolean mCredentialAttempted;
private boolean mKeyguardGoingAway;
private boolean mGoingToSleep;
- private boolean mBouncer; // true if bouncerIsOrWillBeShowing
+ private boolean mBouncerFullyShown;
+ private boolean mBouncerIsOrWillBeShowing;
private boolean mAuthInterruptActive;
private boolean mNeedsSlowUnlockTransition;
private boolean mAssistantVisible;
@@ -622,7 +628,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
*/
public void setKeyguardGoingAway(boolean goingAway) {
mKeyguardGoingAway = goingAway;
- updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+ // This is set specifically to stop face authentication from running.
+ updateBiometricListeningState(BIOMETRIC_ACTION_STOP);
}
/**
@@ -864,10 +871,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
- private void handleFingerprintLockoutReset() {
- boolean changed = mFingerprintLockedOut || mFingerprintLockedOutPermanent;
- mFingerprintLockedOut = false;
- mFingerprintLockedOutPermanent = false;
+ private void handleFingerprintLockoutReset(@LockoutMode int mode) {
+ Log.d(TAG, "handleFingerprintLockoutReset: " + mode);
+ final boolean wasLockout = mFingerprintLockedOut;
+ final boolean wasLockoutPermanent = mFingerprintLockedOutPermanent;
+ mFingerprintLockedOut = (mode == BIOMETRIC_LOCKOUT_TIMED)
+ || mode == BIOMETRIC_LOCKOUT_PERMANENT;
+ mFingerprintLockedOutPermanent = (mode == BIOMETRIC_LOCKOUT_PERMANENT);
+ final boolean changed = (mFingerprintLockedOut != wasLockout)
+ || (mFingerprintLockedOutPermanent != wasLockoutPermanent);
if (isUdfpsEnrolled()) {
// TODO(b/194825098): update the reset signal(s)
@@ -877,7 +889,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
// be noticeable.
mHandler.postDelayed(() -> {
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
- }, BIOMETRIC_LOCKOUT_RESET_DELAY_MS);
+ }, getBiometricLockoutDelay());
} else {
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
}
@@ -1075,13 +1087,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
- private void handleFaceLockoutReset() {
- boolean changed = mFaceLockedOutPermanent;
- mFaceLockedOutPermanent = false;
+ private void handleFaceLockoutReset(@LockoutMode int mode) {
+ Log.d(TAG, "handleFaceLockoutReset: " + mode);
+ final boolean wasLockoutPermanent = mFaceLockedOutPermanent;
+ mFaceLockedOutPermanent = (mode == BIOMETRIC_LOCKOUT_PERMANENT);
+ final boolean changed = (mFaceLockedOutPermanent != wasLockoutPermanent);
mHandler.postDelayed(() -> {
updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
- }, BIOMETRIC_LOCKOUT_RESET_DELAY_MS);
+ }, getBiometricLockoutDelay());
if (changed) {
notifyLockedOutStateChanged(BiometricSourceType.FACE);
@@ -1160,7 +1174,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|| isSimPinSecure());
}
- private boolean getIsFaceAuthenticated() {
+ /**
+ * @return whether the current user has been authenticated with face. This may be true
+ * on the lockscreen if the user doesn't have bypass enabled.
+ */
+ public boolean getIsFaceAuthenticated() {
boolean faceAuthenticated = false;
BiometricAuthenticated bioFaceAuthenticated = mUserFaceAuthenticated.get(getCurrentUser());
if (bioFaceAuthenticated != null) {
@@ -1461,7 +1479,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
= new FingerprintManager.LockoutResetCallback() {
@Override
public void onLockoutReset(int sensorId) {
- handleFingerprintLockoutReset();
+ handleFingerprintLockoutReset(BIOMETRIC_LOCKOUT_NONE);
}
};
@@ -1469,7 +1487,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
= new FaceManager.LockoutResetCallback() {
@Override
public void onLockoutReset(int sensorId) {
- handleFaceLockoutReset();
+ handleFaceLockoutReset(BIOMETRIC_LOCKOUT_NONE);
}
};
@@ -1523,6 +1541,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void onUdfpsPointerDown(int sensorId) {
Log.d(TAG, "onUdfpsPointerDown, sensorId: " + sensorId);
+ requestFaceAuth(true);
+ if (isFaceDetectionRunning()) {
+ mKeyguardBypassController.setUserHasDeviceEntryIntent(true);
+ }
}
@Override
@@ -1579,10 +1601,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
};
- private CancellationSignal mFingerprintCancelSignal;
- private CancellationSignal mFaceCancelSignal;
+ @VisibleForTesting
+ CancellationSignal mFingerprintCancelSignal;
+ @VisibleForTesting
+ CancellationSignal mFaceCancelSignal;
private FingerprintManager mFpm;
private FaceManager mFaceManager;
+ private List<FingerprintSensorPropertiesInternal> mFingerprintSensorProperties;
private List<FaceSensorPropertiesInternal> mFaceSensorProperties;
private boolean mFingerprintLockedOut;
private boolean mFingerprintLockedOutPermanent;
@@ -1722,7 +1747,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
cb.onFinishedGoingToSleep(arg1);
}
}
- updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+ // This is set specifically to stop face authentication from running.
+ updateBiometricListeningState(BIOMETRIC_ACTION_STOP);
}
private void handleScreenTurnedOff() {
@@ -1740,7 +1766,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
cb.onDreamingStateChanged(mIsDreaming);
}
}
- updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+ if (mIsDreaming) {
+ updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
+ updateFaceListeningState(BIOMETRIC_ACTION_STOP);
+ } else {
+ updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+ }
}
private void handleUserInfoChanged(int userId) {
@@ -1865,7 +1896,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
handleKeyguardReset();
break;
case MSG_KEYGUARD_BOUNCER_CHANGED:
- handleKeyguardBouncerChanged(msg.arg1);
+ handleKeyguardBouncerChanged(msg.arg1, msg.arg2);
break;
case MSG_USER_INFO_CHANGED:
handleUserInfoChanged(msg.arg1);
@@ -2017,6 +2048,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
+ mFingerprintSensorProperties = mFpm.getSensorPropertiesInternal();
}
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
@@ -2220,7 +2252,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
public void requestFaceAuth(boolean userInitiatedRequest) {
if (DEBUG) Log.d(TAG, "requestFaceAuth() userInitiated=" + userInitiatedRequest);
mIsFaceAuthUserRequested |= userInitiatedRequest;
- updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
+ updateFaceListeningState(BIOMETRIC_ACTION_START);
}
public boolean isFaceAuthUserRequested() {
@@ -2355,7 +2387,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
final boolean shouldListenKeyguardState =
mKeyguardIsVisible
|| !mDeviceInteractive
- || (mBouncer && !mKeyguardGoingAway)
+ || (mBouncerIsOrWillBeShowing && !mKeyguardGoingAway)
|| mGoingToSleep
|| shouldListenForFingerprintAssistant
|| (mKeyguardOccluded && mIsDreaming)
@@ -2375,17 +2407,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& biometricEnabledForUser;
final boolean shouldListenBouncerState =
- !(mFingerprintLockedOut && mBouncer && mCredentialAttempted);
+ !(mFingerprintLockedOut && mBouncerIsOrWillBeShowing && mCredentialAttempted);
final boolean isEncryptedOrLockdownForUser = isEncryptedOrLockdown(user);
final boolean shouldListenUdfpsState = !isUdfps
|| (!userCanSkipBouncer
&& !isEncryptedOrLockdownForUser
- && userDoesNotHaveTrust
- && !mFingerprintLockedOut);
+ && userDoesNotHaveTrust);
final boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
- && shouldListenBouncerState && shouldListenUdfpsState;
+ && shouldListenBouncerState && shouldListenUdfpsState && !isFingerprintLockedOut();
if (DEBUG_FINGERPRINT || DEBUG_SPEW) {
maybeLogListenerModelData(
@@ -2394,7 +2425,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
user,
shouldListen,
biometricEnabledForUser,
- mBouncer,
+ mBouncerIsOrWillBeShowing,
userCanSkipBouncer,
mCredentialAttempted,
mDeviceInteractive,
@@ -2450,11 +2481,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
// Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
// Lock-down mode shouldn't scan, since it is more explicit.
- boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer);
+ boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass
+ && !mBouncerFullyShown);
- // If the device supports face detection (without authentication), allow it to happen
- // if the device is in lockdown mode. Otherwise, prevent scanning.
+ // If the device supports face detection (without authentication) and bypass is enabled,
+ // allow face scanning to happen if the device is in lockdown mode.
+ // Otherwise, prevent scanning.
final boolean supportsDetectOnly = !mFaceSensorProperties.isEmpty()
+ && canBypass
&& mFaceSensorProperties.get(0).supportsFaceDetection;
if (isLockDown && !supportsDetectOnly) {
strongAuthAllowsScanning = false;
@@ -2469,8 +2503,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
final boolean shouldListen =
- (mBouncer || mAuthInterruptActive || mOccludingAppRequestingFace || awakeKeyguard
- || shouldListenForFaceAssistant)
+ (mBouncerFullyShown && !mGoingToSleep
+ || mAuthInterruptActive
+ || mOccludingAppRequestingFace
+ || awakeKeyguard
+ || shouldListenForFaceAssistant
+ || mAuthController.isUdfpsFingerDown())
&& !mSwitchingUser && !faceDisabledForUser && becauseCannotSkipBouncer
&& !mKeyguardGoingAway && biometricEnabledForUser && !mLockIconPressed
&& strongAuthAllowsScanning && mIsPrimaryUser
@@ -2488,9 +2526,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mAuthInterruptActive,
becauseCannotSkipBouncer,
biometricEnabledForUser,
- mBouncer,
+ mBouncerFullyShown,
faceAuthenticated,
faceDisabledForUser,
+ mGoingToSleep,
awakeKeyguard,
mKeyguardGoingAway,
shouldListenForFaceAssistant,
@@ -2771,6 +2810,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
cb.onUserSwitchComplete(userId);
}
}
+
+ if (mFaceManager != null && !mFaceSensorProperties.isEmpty()) {
+ handleFaceLockoutReset(mFaceManager.getLockoutModeForUser(
+ mFaceSensorProperties.get(0).sensorId, userId));
+ }
+ if (mFpm != null && !mFingerprintSensorProperties.isEmpty()) {
+ handleFingerprintLockoutReset(mFpm.getLockoutModeForUser(
+ mFingerprintSensorProperties.get(0).sensorId, userId));
+ }
+
mInteractionJankMonitor.end(InteractionJankMonitor.CUJ_USER_SWITCH);
mLatencyTracker.onActionEnd(LatencyTracker.ACTION_USER_SWITCH);
}
@@ -3050,13 +3099,21 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
/**
* Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
*
- * @see #sendKeyguardBouncerChanged(boolean)
+ * @see #sendKeyguardBouncerChanged(boolean, boolean)
*/
- private void handleKeyguardBouncerChanged(int bouncerVisible) {
+ private void handleKeyguardBouncerChanged(int bouncerIsOrWillBeShowing, int bouncerFullyShown) {
Assert.isMainThread();
- if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncerVisible + ")");
- mBouncer = bouncerVisible == 1;
- if (mBouncer) {
+ final boolean wasBouncerIsOrWillBeShowing = mBouncerIsOrWillBeShowing;
+ final boolean wasBouncerFullyShown = mBouncerFullyShown;
+ mBouncerIsOrWillBeShowing = bouncerIsOrWillBeShowing == 1;
+ mBouncerFullyShown = bouncerFullyShown == 1;
+ if (DEBUG) {
+ Log.d(TAG, "handleKeyguardBouncerChanged"
+ + " bouncerIsOrWillBeShowing=" + mBouncerIsOrWillBeShowing
+ + " bouncerFullyShowing=" + mBouncerFullyShown);
+ }
+
+ if (mBouncerFullyShown) {
// If the bouncer is shown, always clear this flag. This can happen in the following
// situations: 1) Default camera with SHOW_WHEN_LOCKED is not chosen yet. 2) Secure
// camera requests dismiss keyguard (tapping on photos for example). When these happen,
@@ -3066,13 +3123,25 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mCredentialAttempted = false;
}
- for (int i = 0; i < mCallbacks.size(); i++) {
- KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
- if (cb != null) {
- cb.onKeyguardBouncerChanged(mBouncer);
+ if (wasBouncerIsOrWillBeShowing != mBouncerIsOrWillBeShowing) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onKeyguardBouncerStateChanged(mBouncerIsOrWillBeShowing);
+ }
}
+ updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
+ }
+
+ if (wasBouncerFullyShown != mBouncerFullyShown) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onKeyguardBouncerFullyShowingChanged(mBouncerFullyShown);
+ }
+ }
+ updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
}
- updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
}
/**
@@ -3219,12 +3288,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
/**
- * @see #handleKeyguardBouncerChanged(int)
+ * @see #handleKeyguardBouncerChanged(int, int)
*/
- public void sendKeyguardBouncerChanged(boolean bouncerIsOrWillBeShowing) {
- if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + bouncerIsOrWillBeShowing + ")");
+ public void sendKeyguardBouncerChanged(boolean bouncerIsOrWillBeShowing,
+ boolean bouncerFullyShown) {
+ if (DEBUG) {
+ Log.d(TAG, "sendKeyguardBouncerChanged"
+ + " bouncerIsOrWillBeShowing=" + bouncerIsOrWillBeShowing
+ + " bouncerFullyShown=" + bouncerFullyShown);
+ }
Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
message.arg1 = bouncerIsOrWillBeShowing ? 1 : 0;
+ message.arg2 = bouncerFullyShown ? 1 : 0;
message.sendToTarget();
}
@@ -3480,6 +3555,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
+ protected int getBiometricLockoutDelay() {
+ return BIOMETRIC_LOCKOUT_RESET_DELAY_MS;
+ }
+
/**
* Unregister all listeners.
*/
@@ -3561,7 +3640,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (isUdfpsSupported()) {
pw.println(" udfpsEnrolled=" + isUdfpsEnrolled());
pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true));
- pw.println(" bouncerVisible=" + mBouncer);
+ pw.println(" mBouncerIsOrWillBeShowing=" + mBouncerIsOrWillBeShowing);
pw.println(" mStatusBarState=" + StatusBarState.toString(mStatusBarState));
}
}
@@ -3585,6 +3664,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
pw.println(" mFaceLockedOutPermanent=" + mFaceLockedOutPermanent);
pw.println(" enabledByUser=" + mBiometricEnabledForUser.get(userId));
pw.println(" mSecureCameraLaunched=" + mSecureCameraLaunched);
+ pw.println(" mBouncerFullyShown=" + mBouncerFullyShown);
}
mListenModels.print(pw);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 9373ea8f459c..2620195ae8c4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -97,10 +97,16 @@ public class KeyguardUpdateMonitorCallback {
/**
* Called when the keyguard enters or leaves bouncer mode.
- * @param bouncer if true, keyguard is showing the bouncer or transitioning from/to bouncer
- * mode.
+ * @param bouncerIsOrWillBeShowing if true, keyguard is showing the bouncer or transitioning
+ * from/to bouncer mode.
*/
- public void onKeyguardBouncerChanged(boolean bouncer) { }
+ public void onKeyguardBouncerStateChanged(boolean bouncerIsOrWillBeShowing) { }
+
+ /**
+ * Called when the keyguard fully transitions to the bouncer or is no longer the bouncer
+ * @param bouncerIsFullyShowing if true, keyguard is fully showing the bouncer
+ */
+ public void onKeyguardBouncerFullyShowingChanged(boolean bouncerIsFullyShowing) { }
/**
* Called when visibility of lockscreen clock changes, such as when
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index ffded659c2ac..25f185c8a4ed 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -468,7 +468,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
}
@Override
- public void onKeyguardBouncerChanged(boolean bouncer) {
+ public void onKeyguardBouncerStateChanged(boolean bouncer) {
mIsBouncerShowing = bouncer;
updateVisibility();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt b/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
index 705cf6d5df8e..4b7e9a57ef6a 100644
--- a/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
@@ -48,18 +48,6 @@ class ScreenOnCoordinator @Inject constructor(
SysUIUnfoldComponent::getFoldAodAnimationController).getOrNull()
private val pendingTasks = PendingTasksContainer()
- private var wakeAndUnlockingTask: Runnable? = null
- var wakeAndUnlocking = false
- set(value) {
- if (!value && field) {
- // When updating the value back to false, mark the task complete in order to
- // callback onDrawn
- wakeAndUnlockingTask?.run()
- wakeAndUnlockingTask = null
- }
- field = value
- }
-
init {
screenLifecycle.addObserver(this)
}
@@ -76,10 +64,6 @@ class ScreenOnCoordinator @Inject constructor(
unfoldLightRevealAnimation?.onScreenTurningOn(pendingTasks.registerTask("unfold-reveal"))
foldAodAnimationController?.onScreenTurningOn(pendingTasks.registerTask("fold-to-aod"))
- if (wakeAndUnlocking) {
- wakeAndUnlockingTask = pendingTasks.registerTask("wake-and-unlocking")
- }
-
pendingTasks.onTasksComplete { onDrawn.run() }
Trace.endSection()
}
@@ -91,8 +75,4 @@ class ScreenOnCoordinator @Inject constructor(
pendingTasks.reset()
}
-
- override fun onScreenTurnedOff() {
- wakeAndUnlockingTask = null
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 6b6af4c7b52f..b2673e923008 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -126,7 +126,7 @@ public class AuthContainerView extends LinearLayout
int[] mSensorIds;
boolean mSkipIntro;
long mOperationId;
- long mRequestId;
+ long mRequestId = -1;
boolean mSkipAnimation = false;
@BiometricMultiSensorMode int mMultiSensorConfig = BIOMETRIC_MULTI_SENSOR_DEFAULT;
}
@@ -599,6 +599,11 @@ public class AuthContainerView extends LinearLayout
}
@Override
+ public long getRequestId() {
+ return mConfig.mRequestId;
+ }
+
+ @Override
public void animateToCredentialUI() {
mBiometricView.startTransitionToCredentialUI();
}
@@ -678,7 +683,9 @@ public class AuthContainerView extends LinearLayout
return;
}
mContainerState = STATE_GONE;
- mWindowManager.removeView(this);
+ if (isAttachedToWindow()) {
+ mWindowManager.removeView(this);
+ }
}
private void onDialogAnimatedIn() {
@@ -687,6 +694,11 @@ public class AuthContainerView extends LinearLayout
animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
return;
}
+ if (mContainerState == STATE_ANIMATING_OUT || mContainerState == STATE_GONE) {
+ Log.d(TAG, "onDialogAnimatedIn(): ignore, already animating out or gone - state: "
+ + mContainerState);
+ return;
+ }
mContainerState = STATE_SHOWING;
if (mBiometricView != null) {
mConfig.mCallback.onDialogAnimatedIn();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index c100a0744b85..aaf18b309db2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -768,7 +768,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
}
@Override
- public void hideAuthenticationDialog() {
+ public void hideAuthenticationDialog(long requestId) {
if (DEBUG) Log.d(TAG, "hideAuthenticationDialog: " + mCurrentDialog);
if (mCurrentDialog == null) {
@@ -777,6 +777,11 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
if (DEBUG) Log.d(TAG, "dialog already gone");
return;
}
+ if (requestId != mCurrentDialog.getRequestId()) {
+ Log.w(TAG, "ignore - ids do not match: " + requestId + " current: "
+ + mCurrentDialog.getRequestId());
+ return;
+ }
mCurrentDialog.dismissFromSystemServer();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index 59ed156bce33..4ff19f6adc11 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -150,6 +150,9 @@ public interface AuthDialog {
*/
String getOpPackageName();
+ /** The requestId of the underlying operation within the framework. */
+ long getRequestId();
+
/**
* Animate to credential UI. Typically called after biometric is locked out.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 0cde745d2e12..33126b3887da 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -280,7 +280,7 @@ class AuthRippleController @Inject constructor(
}
}
- override fun onKeyguardBouncerChanged(bouncerIsOrWillBeShowing: Boolean) {
+ override fun onKeyguardBouncerStateChanged(bouncerIsOrWillBeShowing: Boolean) {
if (bouncerIsOrWillBeShowing) {
mView.fadeDwellRipple()
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 975e0c5b32cd..63b2b201c498 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -65,7 +65,6 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.SystemUIDialogManager;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
@@ -124,7 +123,6 @@ public class UdfpsController implements DozeReceiver {
@NonNull private final AccessibilityManager mAccessibilityManager;
@NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Nullable private final UdfpsHbmProvider mHbmProvider;
- @NonNull private final KeyguardBypassController mKeyguardBypassController;
@NonNull private final ConfigurationController mConfigurationController;
@NonNull private final SystemClock mSystemClock;
@NonNull private final UnlockedScreenOffAnimationController
@@ -533,7 +531,6 @@ public class UdfpsController implements DozeReceiver {
@NonNull UdfpsHapticsSimulator udfpsHapticsSimulator,
@NonNull Optional<UdfpsHbmProvider> hbmProvider,
@NonNull KeyguardStateController keyguardStateController,
- @NonNull KeyguardBypassController keyguardBypassController,
@NonNull DisplayManager displayManager,
@Main Handler mainHandler,
@NonNull ConfigurationController configurationController,
@@ -565,7 +562,6 @@ public class UdfpsController implements DozeReceiver {
mHbmProvider = hbmProvider.orElse(null);
screenLifecycle.addObserver(mScreenObserver);
mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
- mKeyguardBypassController = keyguardBypassController;
mConfigurationController = configurationController;
mSystemClock = systemClock;
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
@@ -797,11 +793,6 @@ public class UdfpsController implements DozeReceiver {
return;
}
- if (mOverlay.getAnimationViewController() instanceof UdfpsKeyguardViewController
- && !mStatusBarStateController.isDozing()) {
- mKeyguardBypassController.setUserHasDeviceEntryIntent(true);
- }
-
if (!mOnFingerDown) {
playStartHaptic();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
index f3a603f832fa..59c658fa43d2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
@@ -23,6 +23,7 @@ import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.view.accessibility.AccessibilityManager;
+import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
@@ -40,13 +41,15 @@ public class UdfpsEnrollProgressBarDrawable extends Drawable {
private static final long CHECKMARK_ANIMATION_DELAY_MS = 200L;
private static final long CHECKMARK_ANIMATION_DURATION_MS = 300L;
- private static final long FILL_COLOR_ANIMATION_DURATION_MS = 200L;
+ private static final long FILL_COLOR_ANIMATION_DURATION_MS = 350L;
private static final long PROGRESS_ANIMATION_DURATION_MS = 400L;
private static final float STROKE_WIDTH_DP = 12f;
+ private static final Interpolator DEACCEL = new DecelerateInterpolator();
private final float mStrokeWidthPx;
@ColorInt private final int mProgressColor;
@ColorInt private final int mHelpColor;
+ @ColorInt private final int mOnFirstBucketFailedColor;
@NonNull private final Drawable mCheckmarkDrawable;
@NonNull private final Interpolator mCheckmarkInterpolator;
@NonNull private final Paint mBackgroundPaint;
@@ -64,6 +67,9 @@ public class UdfpsEnrollProgressBarDrawable extends Drawable {
@Nullable private ValueAnimator mFillColorAnimator;
@NonNull private final ValueAnimator.AnimatorUpdateListener mFillColorUpdateListener;
+ @Nullable private ValueAnimator mBackgroundColorAnimator;
+ @NonNull private final ValueAnimator.AnimatorUpdateListener mBackgroundColorUpdateListener;
+
private boolean mComplete = false;
private float mCheckmarkScale = 0f;
@Nullable private ValueAnimator mCheckmarkAnimator;
@@ -76,8 +82,10 @@ public class UdfpsEnrollProgressBarDrawable extends Drawable {
final boolean isAccessbilityEnabled = am.isTouchExplorationEnabled();
if (!isAccessbilityEnabled) {
mHelpColor = context.getColor(R.color.udfps_enroll_progress_help);
+ mOnFirstBucketFailedColor = context.getColor(R.color.udfps_moving_target_fill_error);
} else {
mHelpColor = context.getColor(R.color.udfps_enroll_progress_help_with_talkback);
+ mOnFirstBucketFailedColor = mHelpColor;
}
mCheckmarkDrawable = context.getDrawable(R.drawable.udfps_enroll_checkmark);
mCheckmarkDrawable.mutate();
@@ -112,6 +120,11 @@ public class UdfpsEnrollProgressBarDrawable extends Drawable {
mCheckmarkScale = (float) animation.getAnimatedValue();
invalidateSelf();
};
+
+ mBackgroundColorUpdateListener = animation -> {
+ mBackgroundPaint.setColor((int) animation.getAnimatedValue());
+ invalidateSelf();
+ };
}
void onEnrollmentProgress(int remaining, int totalSteps) {
@@ -163,19 +176,38 @@ public class UdfpsEnrollProgressBarDrawable extends Drawable {
}
}
+ private void animateBackgroundColor() {
+ if (mBackgroundColorAnimator != null && mBackgroundColorAnimator.isRunning()) {
+ mBackgroundColorAnimator.end();
+ }
+ mBackgroundColorAnimator = ValueAnimator.ofArgb(mBackgroundPaint.getColor(),
+ mOnFirstBucketFailedColor);
+ mBackgroundColorAnimator.setDuration(FILL_COLOR_ANIMATION_DURATION_MS);
+ mBackgroundColorAnimator.setRepeatCount(1);
+ mBackgroundColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ mBackgroundColorAnimator.setInterpolator(DEACCEL);
+ mBackgroundColorAnimator.addUpdateListener(mBackgroundColorUpdateListener);
+ mBackgroundColorAnimator.start();
+ }
+
private void updateFillColor(boolean showingHelp) {
- if (mShowingHelp == showingHelp) {
+ if (!mAfterFirstTouch && showingHelp) {
+ // If we are on the first touch, animate the background color
+ // instead of the progress color.
+ animateBackgroundColor();
return;
}
- mShowingHelp = showingHelp;
if (mFillColorAnimator != null && mFillColorAnimator.isRunning()) {
- mFillColorAnimator.cancel();
+ mFillColorAnimator.end();
}
@ColorInt final int targetColor = showingHelp ? mHelpColor : mProgressColor;
mFillColorAnimator = ValueAnimator.ofArgb(mFillPaint.getColor(), targetColor);
mFillColorAnimator.setDuration(FILL_COLOR_ANIMATION_DURATION_MS);
+ mFillColorAnimator.setRepeatCount(1);
+ mFillColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ mFillColorAnimator.setInterpolator(DEACCEL);
mFillColorAnimator.addUpdateListener(mFillColorUpdateListener);
mFillColorAnimator.start();
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java
index da24a8f744be..38c937feb941 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java
@@ -17,9 +17,6 @@
package com.android.systemui.biometrics;
import android.annotation.Nullable;
-import android.view.Surface;
-
-import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType;
/**
* Interface for controlling the high-brightness mode (HBM). UdfpsView can use this callback to
@@ -36,24 +33,21 @@ public interface UdfpsHbmProvider {
* This method must be called from the UI thread. The callback, if provided, will also be
* invoked from the UI thread.
*
- * @param hbmType The type of HBM that should be enabled. See {@link UdfpsHbmTypes}.
- * @param surface The surface for which the HBM is requested, in case the HBM implementation
- * needs to set special surface flags to enable the HBM. Can be null.
* @param onHbmEnabled A runnable that will be executed once HBM is enabled.
*/
- void enableHbm(@HbmType int hbmType, @Nullable Surface surface,
- @Nullable Runnable onHbmEnabled);
+ void enableHbm(@Nullable Runnable onHbmEnabled);
/**
- * UdfpsView will call this to disable the HBM when the illumination is not longer needed.
+ * UdfpsView will call this to disable HBM when illumination is no longer needed.
*
- * This method is a no-op when HBM is already disabled. If HBM is enabled, this method will
- * disable HBM for the {@code hbmType} and {@code surface} that were provided to the
- * corresponding {@link #enableHbm(int, Surface, Runnable)}.
+ * This method will disable HBM if HBM is enabled. Otherwise, if HBM is already disabled,
+ * this method is a no-op.
*
* The call must be made from the UI thread. The callback, if provided, will also be invoked
* from the UI thread.
*
+ *
+ *
* @param onHbmDisabled A runnable that will be executed once HBM is disabled.
*/
void disableHbm(@Nullable Runnable onHbmDisabled);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmTypes.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmTypes.java
deleted file mode 100644
index 3ab0bd62eec8..000000000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmTypes.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.annotation.IntDef;
-import android.hardware.fingerprint.IUdfpsHbmListener;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Different high-brightness mode (HBM) types that are relevant to this package.
- */
-public final class UdfpsHbmTypes {
- /** HBM that applies to the whole screen. */
- public static final int GLOBAL_HBM = IUdfpsHbmListener.GLOBAL_HBM;
-
- /** HBM that only applies to a portion of the screen. */
- public static final int LOCAL_HBM = IUdfpsHbmListener.LOCAL_HBM;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({GLOBAL_HBM, LOCAL_HBM})
- public @interface HbmType {
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java
deleted file mode 100644
index 77fad35d32d4..000000000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.RectF;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-/**
- * Surface View for providing the Global High-Brightness Mode (GHBM) illumination for UDFPS.
- */
-public class UdfpsSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
- private static final String TAG = "UdfpsSurfaceView";
-
- /**
- * Notifies {@link UdfpsView} when to enable GHBM illumination.
- */
- interface GhbmIlluminationListener {
- /**
- * @param surface the surface for which GHBM should be enabled.
- * @param onIlluminatedRunnable a runnable that should be run after GHBM is enabled.
- */
- void enableGhbm(@NonNull Surface surface, @Nullable Runnable onIlluminatedRunnable);
- }
-
- @NonNull private final SurfaceHolder mHolder;
- @NonNull private final Paint mSensorPaint;
-
- @Nullable private GhbmIlluminationListener mGhbmIlluminationListener;
- @Nullable private Runnable mOnIlluminatedRunnable;
- boolean mAwaitingSurfaceToStartIllumination;
- boolean mHasValidSurface;
-
- public UdfpsSurfaceView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- // Make this SurfaceView draw on top of everything else in this window. This allows us to
- // 1) Always show the HBM circle on top of everything else, and
- // 2) Properly composite this view with any other animations in the same window no matter
- // what contents are added in which order to this view hierarchy.
- setZOrderOnTop(true);
-
- mHolder = getHolder();
- mHolder.addCallback(this);
- mHolder.setFormat(PixelFormat.RGBA_8888);
-
- mSensorPaint = new Paint(0 /* flags */);
- mSensorPaint.setAntiAlias(true);
- mSensorPaint.setARGB(255, 255, 255, 255);
- mSensorPaint.setStyle(Paint.Style.FILL);
- }
-
- @Override public void surfaceCreated(SurfaceHolder holder) {
- mHasValidSurface = true;
- if (mAwaitingSurfaceToStartIllumination) {
- doIlluminate(mOnIlluminatedRunnable);
- mOnIlluminatedRunnable = null;
- mAwaitingSurfaceToStartIllumination = false;
- }
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- // Unused.
- }
-
- @Override public void surfaceDestroyed(SurfaceHolder holder) {
- mHasValidSurface = false;
- }
-
- void setGhbmIlluminationListener(@Nullable GhbmIlluminationListener listener) {
- mGhbmIlluminationListener = listener;
- }
-
- /**
- * Note: there is no corresponding method to stop GHBM illumination. It is expected that
- * {@link UdfpsView} will hide this view, which would destroy the surface and remove the
- * illumination dot.
- */
- void startGhbmIllumination(@Nullable Runnable onIlluminatedRunnable) {
- if (mGhbmIlluminationListener == null) {
- Log.e(TAG, "startIllumination | mGhbmIlluminationListener is null");
- return;
- }
-
- if (mHasValidSurface) {
- doIlluminate(onIlluminatedRunnable);
- } else {
- mAwaitingSurfaceToStartIllumination = true;
- mOnIlluminatedRunnable = onIlluminatedRunnable;
- }
- }
-
- private void doIlluminate(@Nullable Runnable onIlluminatedRunnable) {
- if (mGhbmIlluminationListener == null) {
- Log.e(TAG, "doIlluminate | mGhbmIlluminationListener is null");
- return;
- }
-
- mGhbmIlluminationListener.enableGhbm(mHolder.getSurface(), onIlluminatedRunnable);
- }
-
- /**
- * Immediately draws the illumination dot on this SurfaceView's surface.
- */
- void drawIlluminationDot(@NonNull RectF sensorRect) {
- if (!mHasValidSurface) {
- Log.e(TAG, "drawIlluminationDot | the surface is destroyed or was never created.");
- return;
- }
- Canvas canvas = null;
- try {
- canvas = mHolder.lockCanvas();
- canvas.drawOval(sensorRect, mSensorPaint);
- } finally {
- // Make sure the surface is never left in a bad state.
- if (canvas != null) {
- mHolder.unlockCanvasAndPost(canvas);
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
index 9fbc458cb082..75e6aa032343 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
@@ -22,26 +22,17 @@ import android.graphics.Paint
import android.graphics.PointF
import android.graphics.RectF
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
-import android.os.Build
-import android.os.UserHandle
-import android.provider.Settings
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
-import android.view.Surface
import android.widget.FrameLayout
import com.android.systemui.R
import com.android.systemui.doze.DozeReceiver
-import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType
private const val TAG = "UdfpsView"
-private const val SETTING_HBM_TYPE = "com.android.systemui.biometrics.UdfpsSurfaceView.hbmType"
-@HbmType
-private const val DEFAULT_HBM_TYPE = UdfpsHbmTypes.LOCAL_HBM
/**
- * A view containing 1) A SurfaceView for HBM, and 2) A normal drawable view for all other
- * animations.
+ * The main view group containing all UDFPS animations.
*/
class UdfpsView(
context: Context,
@@ -68,21 +59,6 @@ class UdfpsView(
com.android.internal.R.integer.config_udfps_illumination_transition_ms
).toLong()
- @HbmType
- private val hbmType = if (Build.IS_ENG || Build.IS_USERDEBUG) {
- Settings.Secure.getIntForUser(
- context.contentResolver,
- SETTING_HBM_TYPE,
- DEFAULT_HBM_TYPE,
- UserHandle.USER_CURRENT
- )
- } else {
- DEFAULT_HBM_TYPE
- }
-
- // Only used for UdfpsHbmTypes.GLOBAL_HBM.
- private var ghbmView: UdfpsSurfaceView? = null
-
/** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */
var animationViewController: UdfpsAnimationViewController<*>? = null
@@ -109,12 +85,6 @@ class UdfpsView(
return (animationViewController == null || !animationViewController!!.shouldPauseAuth())
}
- override fun onFinishInflate() {
- if (hbmType == UdfpsHbmTypes.GLOBAL_HBM) {
- ghbmView = findViewById(R.id.hbm_view)
- }
- }
-
override fun dozeTimeTick() {
animationViewController?.dozeTimeTick()
}
@@ -180,24 +150,11 @@ class UdfpsView(
override fun startIllumination(onIlluminatedRunnable: Runnable?) {
isIlluminationRequested = true
animationViewController?.onIlluminationStarting()
-
- val gView = ghbmView
- if (gView != null) {
- gView.setGhbmIlluminationListener(this::doIlluminate)
- gView.visibility = VISIBLE
- gView.startGhbmIllumination(onIlluminatedRunnable)
- } else {
- doIlluminate(null /* surface */, onIlluminatedRunnable)
- }
+ doIlluminate(onIlluminatedRunnable)
}
- private fun doIlluminate(surface: Surface?, onIlluminatedRunnable: Runnable?) {
- if (ghbmView != null && surface == null) {
- Log.e(TAG, "doIlluminate | surface must be non-null for GHBM")
- }
-
- hbmProvider?.enableHbm(hbmType, surface) {
- ghbmView?.drawIlluminationDot(sensorRect)
+ private fun doIlluminate(onIlluminatedRunnable: Runnable?) {
+ hbmProvider?.enableHbm() {
if (onIlluminatedRunnable != null) {
// No framework API can reliably tell when a frame reaches the panel. A timeout
// is the safest solution.
@@ -211,10 +168,6 @@ class UdfpsView(
override fun stopIllumination() {
isIlluminationRequested = false
animationViewController?.onIlluminationStopped()
- ghbmView?.let { view ->
- view.setGhbmIlluminationListener(null)
- view.visibility = INVISIBLE
- }
hbmProvider?.disableHbm(null /* onHbmDisabled */)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
index 0ff5805ab111..199988257be0 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
@@ -41,7 +41,8 @@ data class ReceiverData(
val receiver: BroadcastReceiver,
val filter: IntentFilter,
val executor: Executor,
- val user: UserHandle
+ val user: UserHandle,
+ val permission: String? = null
)
private const val MSG_ADD_RECEIVER = 0
@@ -96,16 +97,18 @@ open class BroadcastDispatcher constructor (
*
*/
@Deprecated(message = "Replacing Handler for Executor in SystemUI",
- replaceWith = ReplaceWith("registerReceiver(receiver, filter, executor, user)"))
+ replaceWith = ReplaceWith("registerReceiver(receiver, filter, executor, user, permission)")
+ )
@JvmOverloads
open fun registerReceiverWithHandler(
receiver: BroadcastReceiver,
filter: IntentFilter,
handler: Handler,
user: UserHandle = context.user,
- @Context.RegisterReceiverFlags flags: Int = Context.RECEIVER_EXPORTED
+ @Context.RegisterReceiverFlags flags: Int = Context.RECEIVER_EXPORTED,
+ permission: String? = null
) {
- registerReceiver(receiver, filter, HandlerExecutor(handler), user, flags)
+ registerReceiver(receiver, filter, HandlerExecutor(handler), user, flags, permission)
}
/**
@@ -130,15 +133,17 @@ open class BroadcastDispatcher constructor (
filter: IntentFilter,
executor: Executor? = null,
user: UserHandle? = null,
- @Context.RegisterReceiverFlags flags: Int = Context.RECEIVER_EXPORTED
+ @Context.RegisterReceiverFlags flags: Int = Context.RECEIVER_EXPORTED,
+ permission: String? = null,
) {
checkFilter(filter)
val data = ReceiverData(
receiver,
filter,
executor ?: context.mainExecutor,
- user ?: context.user
- )
+ user ?: context.user,
+ permission
+ )
this.handler
.obtainMessage(MSG_ADD_RECEIVER, flags, 0, data)
.sendToTarget()
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
index d4e9416c624b..eb0cf5e9c016 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
@@ -71,9 +71,16 @@ open class UserBroadcastDispatcher(
}
}
+ // Used for key in actionsToActionsReceivers
+ internal data class ReceiverProperties(
+ val action: String,
+ val flags: Int,
+ val permission: String?
+ )
+
// Only modify in BG thread
@VisibleForTesting
- internal val actionsToActionsReceivers = ArrayMap<Pair<String, Int>, ActionReceiver>()
+ internal val actionsToActionsReceivers = ArrayMap<ReceiverProperties, ActionReceiver>()
private val receiverToActions = ArrayMap<BroadcastReceiver, MutableSet<String>>()
@VisibleForTesting
@@ -106,14 +113,20 @@ open class UserBroadcastDispatcher(
.addAll(receiverData.filter.actionsIterator()?.asSequence() ?: emptySequence())
receiverData.filter.actionsIterator().forEach {
actionsToActionsReceivers
- .getOrPut(it to flags, { createActionReceiver(it, flags) })
- .addReceiverData(receiverData)
+ .getOrPut(
+ ReceiverProperties(it, flags, receiverData.permission),
+ { createActionReceiver(it, receiverData.permission, flags) })
+ .addReceiverData(receiverData)
}
logger.logReceiverRegistered(userId, receiverData.receiver, flags)
}
@VisibleForTesting
- internal open fun createActionReceiver(action: String, flags: Int): ActionReceiver {
+ internal open fun createActionReceiver(
+ action: String,
+ permission: String?,
+ flags: Int
+ ): ActionReceiver {
return ActionReceiver(
action,
userId,
@@ -122,7 +135,7 @@ open class UserBroadcastDispatcher(
this,
UserHandle.of(userId),
it,
- null,
+ permission,
bgHandler,
flags
)
@@ -149,7 +162,7 @@ open class UserBroadcastDispatcher(
if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver")
receiverToActions.getOrDefault(receiver, mutableSetOf()).forEach {
actionsToActionsReceivers.forEach { (key, value) ->
- if (key.first == it) {
+ if (key.action == it) {
value.removeReceiver(receiver)
}
}
@@ -160,9 +173,12 @@ open class UserBroadcastDispatcher(
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
pw.indentIfPossible {
- actionsToActionsReceivers.forEach { (actionAndFlags, actionReceiver) ->
- println("(${actionAndFlags.first}: " +
- "${BroadcastDispatcherLogger.flagToString(actionAndFlags.second)}):")
+ actionsToActionsReceivers.forEach { (actionFlagsPerm, actionReceiver) ->
+ println(
+ "(${actionFlagsPerm.action}: " +
+ BroadcastDispatcherLogger.flagToString(actionFlagsPerm.flags) +
+ if (actionFlagsPerm.permission == null) "):"
+ else ":${actionFlagsPerm.permission}):")
actionReceiver.dump(fd, pw, args)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index 9861392ba463..b7c4009a5aed 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -31,6 +31,8 @@ import static java.util.Objects.requireNonNull;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.MainThread;
import android.app.RemoteAction;
@@ -55,6 +57,7 @@ import android.os.Looper;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.MathUtils;
import android.util.Size;
import android.view.Display;
import android.view.DisplayCutout;
@@ -68,6 +71,8 @@ import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.PathInterpolator;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassificationManager;
import android.view.textclassifier.TextClassifier;
@@ -80,6 +85,8 @@ import android.widget.TextView;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.PhoneWindow;
import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.screenshot.DraggableConstraintLayout;
import com.android.systemui.screenshot.FloatingWindowUtil;
import com.android.systemui.screenshot.OverlayActionChip;
@@ -105,6 +112,7 @@ public class ClipboardOverlayController {
private final Context mContext;
private final UiEventLogger mUiEventLogger;
+ private final BroadcastDispatcher mBroadcastDispatcher;
private final DisplayManager mDisplayManager;
private final DisplayMetrics mDisplayMetrics;
private final WindowManager mWindowManager;
@@ -116,6 +124,7 @@ public class ClipboardOverlayController {
private final FrameLayout mContainer;
private final DraggableConstraintLayout mView;
+ private final View mClipboardPreview;
private final ImageView mImagePreview;
private final TextView mTextPreview;
private final View mPreviewBorder;
@@ -137,8 +146,11 @@ public class ClipboardOverlayController {
private boolean mBlockAttach = false;
- public ClipboardOverlayController(
- Context context, TimeoutHandler timeoutHandler, UiEventLogger uiEventLogger) {
+ public ClipboardOverlayController(Context context,
+ BroadcastDispatcher broadcastDispatcher,
+ BroadcastSender broadcastSender,
+ TimeoutHandler timeoutHandler, UiEventLogger uiEventLogger) {
+ mBroadcastDispatcher = broadcastDispatcher;
mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class));
final Context displayContext = context.createDisplayContext(getDefaultDisplay());
mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null);
@@ -171,6 +183,7 @@ public class ClipboardOverlayController {
mActionContainerBackground =
requireNonNull(mView.findViewById(R.id.actions_container_background));
mActionContainer = requireNonNull(mView.findViewById(R.id.actions));
+ mClipboardPreview = requireNonNull(mView.findViewById(R.id.clipboard_preview));
mImagePreview = requireNonNull(mView.findViewById(R.id.image_preview));
mTextPreview = requireNonNull(mView.findViewById(R.id.text_preview));
mPreviewBorder = requireNonNull(mView.findViewById(R.id.preview_border));
@@ -191,7 +204,7 @@ public class ClipboardOverlayController {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
- mContainer.animate().alpha(0).start();
+ mContainer.animate().alpha(0).setDuration(animation.getDuration()).start();
}
});
}
@@ -215,17 +228,6 @@ public class ClipboardOverlayController {
mRemoteCopyChip.setIcon(
Icon.createWithResource(mContext, R.drawable.ic_baseline_devices_24), true);
- // Only show remote copy if it's available.
- PackageManager packageManager = mContext.getPackageManager();
- if (packageManager.resolveActivity(getRemoteCopyIntent(), 0) != null) {
- mRemoteCopyChip.setOnClickListener((v) -> {
- showNearby();
- });
- mRemoteCopyChip.setAlpha(1f);
- } else {
- mRemoteCopyChip.setVisibility(View.GONE);
- }
-
attachWindow();
withWindowAttached(() -> {
mWindow.setContentView(mContainer);
@@ -247,9 +249,9 @@ public class ClipboardOverlayController {
}
}
};
- mContext.registerReceiver(mCloseDialogsReceiver,
- new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS));
+ mBroadcastDispatcher.registerReceiver(mCloseDialogsReceiver,
+ new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS));
mScreenshotReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -258,14 +260,16 @@ public class ClipboardOverlayController {
}
}
};
- mContext.registerReceiver(mScreenshotReceiver, new IntentFilter(SCREENSHOT_ACTION),
- SELF_PERMISSION, null);
+
+ mBroadcastDispatcher.registerReceiver(mScreenshotReceiver,
+ new IntentFilter(SCREENSHOT_ACTION), null, null, Context.RECEIVER_EXPORTED,
+ SELF_PERMISSION);
monitorOutsideTouches();
Intent copyIntent = new Intent(COPY_OVERLAY_ACTION);
// Set package name so the system knows it's safe
copyIntent.setPackage(mContext.getPackageName());
- mContext.sendBroadcast(copyIntent, SELF_PERMISSION);
+ broadcastSender.sendBroadcast(copyIntent, SELF_PERMISSION);
}
void setClipData(ClipData clipData, String clipSource) {
@@ -286,6 +290,21 @@ public class ClipboardOverlayController {
showTextPreview(
mContext.getResources().getString(R.string.clipboard_overlay_text_copied));
}
+ Intent remoteCopyIntent = getRemoteCopyIntent(clipData);
+ // Only show remote copy if it's available.
+ PackageManager packageManager = mContext.getPackageManager();
+ if (remoteCopyIntent != null && packageManager.resolveActivity(
+ remoteCopyIntent, PackageManager.ResolveInfoFlags.of(0)) != null) {
+ mRemoteCopyChip.setOnClickListener((v) -> {
+ mUiEventLogger.log(CLIPBOARD_OVERLAY_REMOTE_COPY_TAPPED);
+ mContext.startActivity(remoteCopyIntent);
+ animateOut();
+ });
+ mRemoteCopyChip.setAlpha(1f);
+ mActionContainerBackground.setVisibility(View.VISIBLE);
+ } else {
+ mRemoteCopyChip.setVisibility(View.GONE);
+ }
mTimeoutHandler.resetTimeout();
}
@@ -389,12 +408,6 @@ public class ClipboardOverlayController {
animateOut();
}
- private void showNearby() {
- mUiEventLogger.log(CLIPBOARD_OVERLAY_REMOTE_COPY_TAPPED);
- mContext.startActivity(getRemoteCopyIntent());
- animateOut();
- }
-
private void showTextPreview(CharSequence text) {
mTextPreview.setVisibility(View.VISIBLE);
mImagePreview.setVisibility(View.GONE);
@@ -405,6 +418,7 @@ public class ClipboardOverlayController {
private void showEditableText(CharSequence text) {
showTextPreview(text);
mEditChip.setVisibility(View.VISIBLE);
+ mActionContainerBackground.setVisibility(View.VISIBLE);
mEditChip.setAlpha(1f);
mEditChip.setContentDescription(
mContext.getString(R.string.clipboard_edit_text_description));
@@ -417,6 +431,7 @@ public class ClipboardOverlayController {
mTextPreview.setVisibility(View.GONE);
mImagePreview.setVisibility(View.VISIBLE);
mEditChip.setAlpha(1f);
+ mActionContainerBackground.setVisibility(View.VISIBLE);
ContentResolver resolver = mContext.getContentResolver();
try {
int size = mContext.getResources().getDimensionPixelSize(R.dimen.overlay_x_scale);
@@ -434,43 +449,89 @@ public class ClipboardOverlayController {
mImagePreview.setOnClickListener(listener);
}
- private Intent getRemoteCopyIntent() {
+ private Intent getRemoteCopyIntent(ClipData clipData) {
+ String remoteCopyPackage = mContext.getString(R.string.config_remoteCopyPackage);
+ if (TextUtils.isEmpty(remoteCopyPackage)) {
+ return null;
+ }
Intent nearbyIntent = new Intent(REMOTE_COPY_ACTION);
+ nearbyIntent.setComponent(ComponentName.unflattenFromString(remoteCopyPackage));
+ nearbyIntent.setClipData(clipData);
+ nearbyIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
return nearbyIntent;
}
private void animateIn() {
+ if (mAccessibilityManager.isEnabled()) {
+ mDismissButton.setVisibility(View.VISIBLE);
+ }
getEnterAnimation().start();
}
private void animateOut() {
- mView.dismiss();
+ Animator anim = getExitAnimation();
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ hideImmediate();
+ }
+ });
+ anim.start();
}
- private ValueAnimator getEnterAnimation() {
- ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ private Animator getEnterAnimation() {
+ TimeInterpolator linearInterpolator = new LinearInterpolator();
+ TimeInterpolator scaleInterpolator = new PathInterpolator(0, 0, 0, 1f);
+ AnimatorSet enterAnim = new AnimatorSet();
- mContainer.setAlpha(0);
- mDismissButton.setVisibility(View.GONE);
- final View previewBorder = requireNonNull(mView.findViewById(R.id.preview_border));
- final View actionBackground = requireNonNull(
- mView.findViewById(R.id.actions_container_background));
- mImagePreview.setVisibility(View.VISIBLE);
- mActionContainerBackground.setVisibility(View.VISIBLE);
- if (mAccessibilityManager.isEnabled()) {
- mDismissButton.setVisibility(View.VISIBLE);
- }
-
- anim.addUpdateListener(animation -> {
+ ValueAnimator rootAnim = ValueAnimator.ofFloat(0, 1);
+ rootAnim.setInterpolator(linearInterpolator);
+ rootAnim.setDuration(66);
+ rootAnim.addUpdateListener(animation -> {
mContainer.setAlpha(animation.getAnimatedFraction());
- float scale = 0.6f + 0.4f * animation.getAnimatedFraction();
- mView.setPivotY(mView.getHeight() - previewBorder.getHeight() / 2f);
- mView.setPivotX(actionBackground.getWidth() / 2f);
- mView.setScaleX(scale);
- mView.setScaleY(scale);
});
- anim.addListener(new AnimatorListenerAdapter() {
+
+ ValueAnimator scaleAnim = ValueAnimator.ofFloat(0, 1);
+ scaleAnim.setInterpolator(scaleInterpolator);
+ scaleAnim.setDuration(333);
+ scaleAnim.addUpdateListener(animation -> {
+ float previewScale = MathUtils.lerp(.9f, 1f, animation.getAnimatedFraction());
+ mClipboardPreview.setScaleX(previewScale);
+ mClipboardPreview.setScaleY(previewScale);
+ mPreviewBorder.setScaleX(previewScale);
+ mPreviewBorder.setScaleY(previewScale);
+
+ float pivotX = mClipboardPreview.getWidth() / 2f + mClipboardPreview.getX();
+ mActionContainerBackground.setPivotX(pivotX - mActionContainerBackground.getX());
+ mActionContainer.setPivotX(pivotX - ((View) mActionContainer.getParent()).getX());
+ float actionsScaleX = MathUtils.lerp(.7f, 1f, animation.getAnimatedFraction());
+ float actionsScaleY = MathUtils.lerp(.9f, 1f, animation.getAnimatedFraction());
+ mActionContainer.setScaleX(actionsScaleX);
+ mActionContainer.setScaleY(actionsScaleY);
+ mActionContainerBackground.setScaleX(actionsScaleX);
+ mActionContainerBackground.setScaleY(actionsScaleY);
+ });
+
+ ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1);
+ alphaAnim.setInterpolator(linearInterpolator);
+ alphaAnim.setDuration(283);
+ alphaAnim.addUpdateListener(animation -> {
+ float alpha = animation.getAnimatedFraction();
+ mClipboardPreview.setAlpha(alpha);
+ mPreviewBorder.setAlpha(alpha);
+ mDismissButton.setAlpha(alpha);
+ mActionContainer.setAlpha(alpha);
+ });
+
+ mActionContainer.setAlpha(0);
+ mPreviewBorder.setAlpha(0);
+ mClipboardPreview.setAlpha(0);
+ enterAnim.play(rootAnim).with(scaleAnim);
+ enterAnim.play(alphaAnim).after(50).after(rootAnim);
+
+ enterAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
@@ -478,7 +539,56 @@ public class ClipboardOverlayController {
mTimeoutHandler.resetTimeout();
}
});
- return anim;
+ return enterAnim;
+ }
+
+ private Animator getExitAnimation() {
+ TimeInterpolator linearInterpolator = new LinearInterpolator();
+ TimeInterpolator scaleInterpolator = new PathInterpolator(.3f, 0, 1f, 1f);
+ AnimatorSet exitAnim = new AnimatorSet();
+
+ ValueAnimator rootAnim = ValueAnimator.ofFloat(0, 1);
+ rootAnim.setInterpolator(linearInterpolator);
+ rootAnim.setDuration(100);
+ rootAnim.addUpdateListener(animation -> {
+ mContainer.setAlpha(1 - animation.getAnimatedFraction());
+ });
+
+ ValueAnimator scaleAnim = ValueAnimator.ofFloat(0, 1);
+ scaleAnim.setInterpolator(scaleInterpolator);
+ scaleAnim.setDuration(250);
+ scaleAnim.addUpdateListener(animation -> {
+ float previewScale = MathUtils.lerp(1f, .9f, animation.getAnimatedFraction());
+ mClipboardPreview.setScaleX(previewScale);
+ mClipboardPreview.setScaleY(previewScale);
+ mPreviewBorder.setScaleX(previewScale);
+ mPreviewBorder.setScaleY(previewScale);
+
+ float pivotX = mClipboardPreview.getWidth() / 2f + mClipboardPreview.getX();
+ mActionContainerBackground.setPivotX(pivotX - mActionContainerBackground.getX());
+ mActionContainer.setPivotX(pivotX - ((View) mActionContainer.getParent()).getX());
+ float actionScaleX = MathUtils.lerp(1f, .8f, animation.getAnimatedFraction());
+ float actionScaleY = MathUtils.lerp(1f, .9f, animation.getAnimatedFraction());
+ mActionContainer.setScaleX(actionScaleX);
+ mActionContainer.setScaleY(actionScaleY);
+ mActionContainerBackground.setScaleX(actionScaleX);
+ mActionContainerBackground.setScaleY(actionScaleY);
+ });
+
+ ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1);
+ alphaAnim.setInterpolator(linearInterpolator);
+ alphaAnim.setDuration(166);
+ alphaAnim.addUpdateListener(animation -> {
+ float alpha = 1 - animation.getAnimatedFraction();
+ mClipboardPreview.setAlpha(alpha);
+ mPreviewBorder.setAlpha(alpha);
+ mDismissButton.setAlpha(alpha);
+ mActionContainer.setAlpha(alpha);
+ });
+
+ exitAnim.play(alphaAnim).with(scaleAnim);
+ exitAnim.play(rootAnim).after(150).after(alphaAnim);
+ return exitAnim;
}
private void hideImmediate() {
@@ -490,11 +600,11 @@ public class ClipboardOverlayController {
mWindowManager.removeViewImmediate(decorView);
}
if (mCloseDialogsReceiver != null) {
- mContext.unregisterReceiver(mCloseDialogsReceiver);
+ mBroadcastDispatcher.unregisterReceiver(mCloseDialogsReceiver);
mCloseDialogsReceiver = null;
}
if (mScreenshotReceiver != null) {
- mContext.unregisterReceiver(mScreenshotReceiver);
+ mBroadcastDispatcher.unregisterReceiver(mScreenshotReceiver);
mScreenshotReceiver = null;
}
if (mInputEventReceiver != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java
index 275d295613f9..8b0b2a59dd92 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java
@@ -19,6 +19,8 @@ package com.android.systemui.clipboardoverlay;
import android.content.Context;
import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.screenshot.TimeoutHandler;
@@ -29,17 +31,24 @@ import javax.inject.Inject;
*/
@SysUISingleton
public class ClipboardOverlayControllerFactory {
+
private final UiEventLogger mUiEventLogger;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+ private final BroadcastSender mBroadcastSender;
@Inject
- public ClipboardOverlayControllerFactory(UiEventLogger uiEventLogger) {
- mUiEventLogger = uiEventLogger;
+ public ClipboardOverlayControllerFactory(BroadcastDispatcher broadcastDispatcher,
+ BroadcastSender broadcastSender, UiEventLogger uiEventLogger) {
+ this.mBroadcastDispatcher = broadcastDispatcher;
+ this.mBroadcastSender = broadcastSender;
+ this.mUiEventLogger = uiEventLogger;
}
/**
* One new ClipboardOverlayController, coming right up!
*/
public ClipboardOverlayController create(Context context) {
- return new ClipboardOverlayController(context, new TimeoutHandler(context), mUiEventLogger);
+ return new ClipboardOverlayController(context, mBroadcastDispatcher, mBroadcastSender,
+ new TimeoutHandler(context), mUiEventLogger);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 041de05aa3d4..fa2384268b15 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -36,7 +36,6 @@ import android.view.IWindowManager;
import android.view.LayoutInflater;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -50,7 +49,6 @@ import com.android.systemui.accessibility.ModeSwitchesController;
import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger;
-import com.android.systemui.clipboardoverlay.ClipboardOverlayControllerFactory;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
@@ -293,12 +291,4 @@ public class DependencyProvider {
public ModeSwitchesController providesModeSwitchesController(Context context) {
return new ModeSwitchesController(context);
}
-
- /***/
- @Provides
- @SysUISingleton
- public ClipboardOverlayControllerFactory provideClipboardOverlayControllerFactory(
- UiEventLogger uiEventLogger) {
- return new ClipboardOverlayControllerFactory(uiEventLogger);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 8e1d645d1e97..f05fc2bb202a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -396,8 +396,8 @@ public class DozeLog implements Dumpable {
}
@Override
- public void onKeyguardBouncerChanged(boolean bouncer) {
- traceKeyguardBouncerChanged(bouncer);
+ public void onKeyguardBouncerFullyShowingChanged(boolean fullyShowing) {
+ traceKeyguardBouncerChanged(fullyShowing);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index dfb27eff722b..0024a460136e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -147,6 +147,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
setLightSensorEnabled(true);
break;
case DOZE:
+ case DOZE_AOD_PAUSED:
setLightSensorEnabled(false);
resetBrightnessToDefault();
break;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 456119068b93..fb1af8b66b91 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -16,14 +16,21 @@
package com.android.systemui.dreams;
+import static com.android.keyguard.BouncerPanelExpansionCalculator.getBackScrimScaledExpansion;
+import static com.android.keyguard.BouncerPanelExpansionCalculator.getDreamAlphaScaledExpansion;
+import static com.android.keyguard.BouncerPanelExpansionCalculator.getDreamYPositionScaledExpansion;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
+import static com.android.systemui.dreams.complication.ComplicationLayoutParams.POSITION_BOTTOM;
+import static com.android.systemui.dreams.complication.ComplicationLayoutParams.POSITION_TOP;
+import android.content.res.Resources;
import android.os.Handler;
import android.util.MathUtils;
import android.view.View;
import android.view.ViewGroup;
-import com.android.keyguard.BouncerPanelExpansionCalculator;
+import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.complication.ComplicationHostViewController;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
@@ -33,6 +40,8 @@ import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.util.ViewController;
+import java.util.Arrays;
+
import javax.inject.Inject;
import javax.inject.Named;
@@ -63,6 +72,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
// Main thread handler used to schedule periodic tasks (e.g. burn-in protection updates).
private final Handler mHandler;
+ private final int mDreamOverlayMaxTranslationY;
private long mJitterStartTimeMillis;
@@ -93,13 +103,9 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
@Override
public void onExpansionChanged(float bouncerHideAmount) {
- if (!mBouncerAnimating) return;
- final float scaledFraction =
- BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(
- bouncerHideAmount);
- final int blurRadius =
- (int) mBlurUtils.blurRadiusOfRatio(1 - scaledFraction);
- updateTransitionState(blurRadius, scaledFraction);
+ if (mBouncerAnimating) {
+ updateTransitionState(bouncerHideAmount);
+ }
}
@Override
@@ -107,7 +113,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
// The bouncer may be hidden abruptly without triggering onExpansionChanged.
// In this case, we should reset the transition state.
if (!isVisible) {
- updateTransitionState(0, 1f);
+ updateTransitionState(1f);
}
}
};
@@ -121,6 +127,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
BlurUtils blurUtils,
@Main Handler handler,
+ @Main Resources resources,
@Named(DreamOverlayModule.MAX_BURN_IN_OFFSET) int maxBurnInOffset,
@Named(DreamOverlayModule.BURN_IN_PROTECTION_UPDATE_INTERVAL) long
burnInProtectionUpdateInterval,
@@ -132,6 +139,8 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
mBlurUtils = blurUtils;
mComplicationHostViewController = complicationHostViewController;
+ mDreamOverlayMaxTranslationY = resources.getDimensionPixelSize(
+ R.dimen.dream_overlay_y_offset);
final View view = mComplicationHostViewController.getView();
mDreamOverlayContentView.addView(view,
@@ -196,8 +205,31 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
mHandler.postDelayed(this::updateBurnInOffsets, mBurnInProtectionUpdateInterval);
}
- private void updateTransitionState(int blurRadiusPixels, float alpha) {
- mBlurUtils.applyBlur(mView.getViewRootImpl(), blurRadiusPixels, false);
- mView.setAlpha(alpha);
+ private void updateTransitionState(float bouncerHideAmount) {
+ for (int position : Arrays.asList(POSITION_TOP, POSITION_BOTTOM)) {
+ final float alpha = getAlpha(position, bouncerHideAmount);
+ final float translationY = getTranslationY(position, bouncerHideAmount);
+ mComplicationHostViewController.getViewsAtPosition(position).forEach(v -> {
+ v.setAlpha(alpha);
+ v.setTranslationY(translationY);
+ });
+ }
+
+ mBlurUtils.applyBlur(mView.getViewRootImpl(),
+ (int) mBlurUtils.blurRadiusOfRatio(
+ 1 - getBackScrimScaledExpansion(bouncerHideAmount)), false);
+ }
+
+ private static float getAlpha(int position, float expansion) {
+ return Interpolators.LINEAR_OUT_SLOW_IN.getInterpolation(
+ position == POSITION_TOP ? getDreamAlphaScaledExpansion(expansion)
+ : getBackScrimScaledExpansion(expansion + 0.03f));
+ }
+
+ private float getTranslationY(int position, float expansion) {
+ final float fraction = Interpolators.LINEAR_OUT_SLOW_IN.getInterpolation(
+ position == POSITION_TOP ? getDreamYPositionScaledExpansion(expansion)
+ : getBackScrimScaledExpansion(expansion + 0.03f));
+ return MathUtils.lerp(-mDreamOverlayMaxTranslationY, 0, fraction);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
index 4e528bbe9386..4c0154faeb5a 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
@@ -31,6 +31,7 @@ import com.android.systemui.util.ViewController;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Inject;
@@ -144,4 +145,11 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay
public View getView() {
return mView;
}
+
+ /**
+ * Gets an unordered list of all the views at a particular position.
+ */
+ public List<View> getViewsAtPosition(@ComplicationLayoutParams.Position int position) {
+ return mLayoutEngine.getViewsAtPosition(position);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
index 4065a25dac80..ded61a8b80d9 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
@@ -32,6 +32,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Constraints;
import com.android.systemui.R;
+import com.android.systemui.dreams.complication.ComplicationLayoutParams.Position;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
import com.android.systemui.touch.TouchInsetManager;
@@ -39,7 +40,9 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
@@ -378,6 +381,14 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
directionGroup.updateViews(head.getView());
}
}
+
+ private ArrayList<ViewEntry> getViews() {
+ final ArrayList<ViewEntry> views = new ArrayList<>();
+ for (DirectionGroup directionGroup : mDirectionGroups.values()) {
+ views.addAll(directionGroup.getViews());
+ }
+ return views;
+ }
}
/**
@@ -454,6 +465,10 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
groupHead = viewEntry.getView();
}
}
+
+ private List<ViewEntry> getViews() {
+ return mViews;
+ }
}
private final ConstraintLayout mLayout;
@@ -551,4 +566,15 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
entry.remove();
return true;
}
+
+ /**
+ * Gets an unordered list of all the views at a particular position.
+ */
+ public List<View> getViewsAtPosition(@Position int position) {
+ return mPositions.entrySet().stream()
+ .filter(entry -> (entry.getKey() & position) == position)
+ .flatMap(entry -> entry.getValue().getViews().stream())
+ .map(ViewEntry::getView)
+ .collect(Collectors.toList());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index 5c99cd1b8722..990f04b58f95 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -117,15 +117,23 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler {
return false;
}
+ // Don't set expansion for downward scroll when the bouncer is hidden.
+ if (!mBouncerInitiallyShowing && (e1.getY() < e2.getY())) {
+ return true;
+ }
+
+ // Don't set expansion for upward scroll when the bouncer is shown.
+ if (mBouncerInitiallyShowing && (e1.getY() > e2.getY())) {
+ return true;
+ }
+
// For consistency, we adopt the expansion definition found in the
// PanelViewController. In this case, expansion refers to the view above the
// bouncer. As that view's expansion shrinks, the bouncer appears. The bouncer
// is fully hidden at full expansion (1) and fully visible when fully collapsed
// (0).
- final float dy = mBouncerInitiallyShowing ? e2.getY() - e1.getY()
- : e1.getY() - e2.getY();
- final float screenTravelPercentage = Math.max(0,
- dy / mCentralSurfaces.getDisplayHeight());
+ final float screenTravelPercentage = Math.abs(e1.getY() - e2.getY())
+ / mCentralSurfaces.getDisplayHeight();
setPanelExpansion(mBouncerInitiallyShowing
? screenTravelPercentage : 1 - screenTravelPercentage);
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpsysTableLogger.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpsysTableLogger.kt
new file mode 100644
index 000000000000..f7e6b98a0f06
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpsysTableLogger.kt
@@ -0,0 +1,125 @@
+/*
+ * 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.systemui.dump
+
+import java.io.PrintWriter
+
+/**
+ * Utility for logging nice table data to be parsed (and pretty printed) in bugreports. The general
+ * idea here is to feed your nice, table-like data to this class, which embeds the schema and rows
+ * into the dumpsys, wrapped in a known start and stop tags. Later, one can build a simple parser
+ * and pretty-print this data in a table
+ *
+ * Note: Something should be said here about silently eating errors by filtering out malformed
+ * lines. Because this class is expected to be utilized only during a dumpsys, it doesn't feel
+ * most correct to throw an exception here (since an exception can often be the reason that this
+ * class is created). Because of this, [DumpsysTableLogger] will simply filter out invalid lines
+ * based solely on line length. This behavior might need to be revisited in the future.
+ *
+ * USAGE:
+ * Assuming we have some data that would be logged to dumpsys like so:
+ *
+ * ```
+ * 1: field1=val1, field2=val2..., fieldN=valN
+ * //...
+ * M: field1M=val1M, ..., fieldNM
+ * ```
+ *
+ * You can break the `field<n>` values out into a columns spec:
+ * ```
+ * val cols = [field1, field2,...,fieldN]
+ * ```
+ * And then take all of the historical data lines (1 through M), and break them out into their own
+ * lists:
+ * ```
+ * val rows = [
+ * [field10, field20,..., fieldN0],
+ * //...
+ * [field1M, field2M,..., fieldNM]
+ * ]
+ * ```
+ *
+ * Lastly, create a bugreport-unique section name, and use the table logger to write the data to
+ * dumpsys:
+ * ```
+ * val logger = DumpsysTableLogger(uniqueName, cols, rows)
+ * logger.printTableData(pw)
+ * ```
+ *
+ * The expected output in the dumpsys would be:
+ * ```
+ * SystemUI TableSection START: <SectionName>
+ * version 1
+ * col1|col2|...|colN
+ * field10|field20|...|fieldN0
+ * //...
+ * field1M|field2M|...|fieldNM
+ * SystemUI TableSection END: <SectionName>
+ * ```
+ *
+ * @param sectionName A name for the table data section. Should be unique in the bugreport
+ * @param columns Definition for the columns of the table. This should be the same length as all
+ * data rows
+ * @param rows List of rows to be displayed in the table
+ */
+class DumpsysTableLogger(
+ private val sectionName: String,
+ private val columns: List<String>,
+ private val rows: List<Row>
+) {
+
+ fun printTableData(pw: PrintWriter) {
+ printSectionStart(pw)
+ printSchema(pw)
+ printData(pw)
+ printSectionEnd(pw)
+ }
+
+ private fun printSectionStart(pw: PrintWriter) {
+ pw.println(HEADER_PREFIX + sectionName)
+ pw.println("version $VERSION")
+ }
+
+ private fun printSectionEnd(pw: PrintWriter) {
+ pw.println(FOOTER_PREFIX + sectionName)
+ }
+
+ private fun printSchema(pw: PrintWriter) {
+ pw.println(columns.joinToString(separator = SEPARATOR))
+ }
+
+ private fun printData(pw: PrintWriter) {
+ val count = columns.size
+ rows
+ .filter { it.size == count }
+ .forEach { dataLine ->
+ pw.println(dataLine.joinToString(separator = SEPARATOR))
+ }
+ }
+}
+
+typealias Row = List<String>
+
+/**
+ * DO NOT CHANGE! (but if you must...)
+ * 1. Update the version number
+ * 2. Update any consumers to parse the new version
+ */
+private const val HEADER_PREFIX = "SystemUI TableSection START: "
+private const val FOOTER_PREFIX = "SystemUI TableSection END: "
+private const val SEPARATOR = "|" // TBD
+private const val VERSION = "1" \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 9356b16806f1..c9a61a8a09df 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -112,6 +112,10 @@ public class Flags {
public static final ResourceBooleanFlag QS_USER_DETAIL_SHORTCUT =
new ResourceBooleanFlag(503, R.bool.flag_lockscreen_qs_user_detail_shortcut);
+ /**
+ * @deprecated Not needed anymore
+ */
+ @Deprecated
public static final BooleanFlag NEW_FOOTER = new BooleanFlag(504, true);
public static final BooleanFlag NEW_HEADER = new BooleanFlag(505, false);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 890ddf0d6cac..47763170d1ea 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -318,6 +318,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
// true if the keyguard is hidden by another window
private boolean mOccluded = false;
+ private boolean mWakeAndUnlocking = false;
+
/**
* Helps remember whether the screen has turned on since the last time
* it turned off due to timeout. see {@link #onScreenTurnedOff(int)}
@@ -452,7 +454,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
private boolean mLockLater;
private boolean mShowHomeOverLockscreen;
private boolean mInGestureNavigationMode;
-
private CharSequence mCustomMessage;
/**
@@ -1218,7 +1219,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
doKeyguardLaterLocked(timeout);
mLockLater = true;
} else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
- mPendingLock = true;
+ setPendingLock(true);
}
if (mPendingLock) {
@@ -1248,7 +1249,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
synchronized (this) {
mDeviceInteractive = false;
mGoingToSleep = false;
- mScreenOnCoordinator.setWakeAndUnlocking(false);
+ mWakeAndUnlocking = false;
mAnimatingScreenOff = mDozeParameters.shouldAnimateDozingChange();
resetKeyguardDonePendingLocked();
@@ -1262,7 +1263,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_CAMERA_LAUNCH,
"com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
- mPendingLock = false;
+ setPendingLock(false);
mPendingReset = false;
}
@@ -1332,7 +1333,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}
doKeyguardLocked(null);
- mPendingLock = false;
+ setPendingLock(false);
}
}
@@ -2133,6 +2134,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
return;
}
+ setPendingLock(false); // user may have authenticated during the screen off animation
if (mExitSecureCallback != null) {
try {
mExitSecureCallback.onKeyguardExitResult(true /* authenciated */);
@@ -2262,8 +2264,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mHiding = false;
mKeyguardExitAnimationRunner = null;
- mScreenOnCoordinator.setWakeAndUnlocking(false);
- mPendingLock = false;
+ mWakeAndUnlocking = false;
+ setPendingLock(false);
setShowingLocked(true);
mKeyguardViewControllerLazy.get().show(options);
resetKeyguardDonePendingLocked();
@@ -2294,14 +2296,12 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
int flags = 0;
if (mKeyguardViewControllerLazy.get().shouldDisableWindowAnimationsForUnlock()
- || mScreenOnCoordinator.getWakeAndUnlocking()
- && !mWallpaperSupportsAmbientMode) {
+ || mWakeAndUnlocking && !mWallpaperSupportsAmbientMode) {
flags |= WindowManagerPolicyConstants
.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
}
if (mKeyguardViewControllerLazy.get().isGoingToNotificationShade()
- || mScreenOnCoordinator.getWakeAndUnlocking()
- && mWallpaperSupportsAmbientMode) {
+ || mWakeAndUnlocking && mWallpaperSupportsAmbientMode) {
// When the wallpaper supports ambient mode, the scrim isn't fully opaque during
// wake and unlock, and we should fade in the app on top of the wallpaper
flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
@@ -2414,16 +2414,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
IRemoteAnimationRunner runner = mKeyguardExitAnimationRunner;
mKeyguardExitAnimationRunner = null;
- if (mScreenOnCoordinator.getWakeAndUnlocking()) {
-
- // Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
- // the next draw from here, so we don't have to wait for window manager to signal
- // this to our ViewRootImpl.
- mKeyguardViewControllerLazy.get().getViewRootImpl().setReportNextDraw(
- false /* syncBuffer */);
- mScreenOnCoordinator.setWakeAndUnlocking(false);
- }
-
LatencyTracker.getInstance(mContext)
.onActionEnd(LatencyTracker.ACTION_LOCKSCREEN_UNLOCK);
@@ -2546,7 +2536,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}
setShowingLocked(false);
- mScreenOnCoordinator.setWakeAndUnlocking(false);
+ mWakeAndUnlocking = false;
mDismissCallbackRegistry.notifyDismissSucceeded();
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
@@ -2790,7 +2780,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
public void onWakeAndUnlocking() {
Trace.beginSection("KeyguardViewMediator#onWakeAndUnlocking");
- mScreenOnCoordinator.setWakeAndUnlocking(true);
+ mWakeAndUnlocking = true;
keyguardDone();
Trace.endSection();
}
@@ -2926,7 +2916,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
pw.print(" mHideAnimationRun: "); pw.println(mHideAnimationRun);
pw.print(" mPendingReset: "); pw.println(mPendingReset);
pw.print(" mPendingLock: "); pw.println(mPendingLock);
- pw.print(" wakeAndUnlocking: "); pw.println(mScreenOnCoordinator.getWakeAndUnlocking());
+ pw.print(" wakeAndUnlocking: "); pw.println(mWakeAndUnlocking);
}
/**
@@ -3000,7 +2990,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}
private void setShowingLocked(boolean showing, boolean forceCallbacks) {
- final boolean aodShowing = mDozing && !mScreenOnCoordinator.getWakeAndUnlocking();
+ final boolean aodShowing = mDozing && !mWakeAndUnlocking;
final boolean notifyDefaultDisplayCallbacks = showing != mShowing || forceCallbacks;
final boolean updateActivityLockScreenState = showing != mShowing
|| aodShowing != mAodShowing || forceCallbacks;
@@ -3051,6 +3041,11 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}
}
+ private void setPendingLock(boolean hasPendingLock) {
+ mPendingLock = hasPendingLock;
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "pendingLock", mPendingLock ? 1 : 0);
+ }
+
public void addStateMonitorCallback(IKeyguardStateCallback callback) {
synchronized (this) {
mKeyguardStateCallbacks.add(callback);
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index d4e2214f8b38..d674b2b85db4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -217,17 +217,17 @@ class MediaCarouselController @Inject constructor(
oldKey: String?,
data: MediaData,
immediately: Boolean,
- receivedSmartspaceCardLatency: Int
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
) {
- if (addOrUpdatePlayer(key, oldKey, data)) {
+ if (addOrUpdatePlayer(key, oldKey, data, isSsReactivated)) {
// Log card received if a new resumable media card is added
MediaPlayerData.getMediaPlayer(key)?.let {
/* ktlint-disable max-line-length */
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
it.mSmartspaceId,
it.mUid,
- /* isRecommendationCard */ false,
- intArrayOf(
+ surfaces = intArrayOf(
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN),
rank = MediaPlayerData.getMediaPlayerIndex(key))
@@ -250,8 +250,7 @@ class MediaCarouselController @Inject constructor(
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
it.mSmartspaceId,
it.mUid,
- /* isRecommendationCard */ false,
- intArrayOf(
+ surfaces = intArrayOf(
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN),
rank = index,
@@ -285,12 +284,17 @@ class MediaCarouselController @Inject constructor(
override fun onSmartspaceMediaDataLoaded(
key: String,
data: SmartspaceMediaData,
- shouldPrioritize: Boolean,
- isSsReactivated: Boolean
+ shouldPrioritize: Boolean
) {
if (DEBUG) Log.d(TAG, "Loading Smartspace media update")
+ // Log the case where the hidden media carousel with the existed inactive resume
+ // media is shown by the Smartspace signal.
if (data.isActive) {
- if (isSsReactivated && shouldPrioritize) {
+ val hasActivatedExistedResumeMedia =
+ !mediaManager.hasActiveMedia() &&
+ mediaManager.hasAnyMedia() &&
+ shouldPrioritize
+ if (hasActivatedExistedResumeMedia) {
// Log resume card received if resumable media card is reactivated and
// recommendation card is valid and ranked first
MediaPlayerData.players().forEachIndexed { index, it ->
@@ -302,8 +306,7 @@ class MediaCarouselController @Inject constructor(
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
it.mSmartspaceId,
it.mUid,
- /* isRecommendationCard */ false,
- intArrayOf(
+ surfaces = intArrayOf(
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN),
rank = index,
@@ -318,8 +321,7 @@ class MediaCarouselController @Inject constructor(
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
it.mSmartspaceId,
it.mUid,
- /* isRecommendationCard */ true,
- intArrayOf(
+ surfaces = intArrayOf(
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN),
rank = MediaPlayerData.getMediaPlayerIndex(key),
@@ -417,7 +419,12 @@ class MediaCarouselController @Inject constructor(
}
// Returns true if new player is added
- private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData): Boolean {
+ private fun addOrUpdatePlayer(
+ key: String,
+ oldKey: String?,
+ data: MediaData,
+ isSsReactivated: Boolean
+ ): Boolean {
MediaPlayerData.moveIfExists(oldKey, key)
val existingPlayer = MediaPlayerData.getMediaPlayer(key)
val curVisibleMediaKey = MediaPlayerData.playerKeys()
@@ -432,12 +439,12 @@ class MediaCarouselController @Inject constructor(
newPlayer.mediaViewHolder?.player?.setLayoutParams(lp)
newPlayer.bindPlayer(data, key)
newPlayer.setListening(currentlyExpanded)
- MediaPlayerData.addMediaPlayer(key, data, newPlayer, systemClock)
+ MediaPlayerData.addMediaPlayer(key, data, newPlayer, systemClock, isSsReactivated)
updatePlayerToState(newPlayer, noAnimation = true)
reorderAllPlayers(curVisibleMediaKey)
} else {
existingPlayer.bindPlayer(data, key)
- MediaPlayerData.addMediaPlayer(key, data, existingPlayer, systemClock)
+ MediaPlayerData.addMediaPlayer(key, data, existingPlayer, systemClock, isSsReactivated)
if (isReorderingAllowed || shouldScrollToActivePlayer) {
reorderAllPlayers(curVisibleMediaKey)
} else {
@@ -531,8 +538,10 @@ class MediaCarouselController @Inject constructor(
it.targetId, it, MediaPlayerData.shouldPrioritizeSs)
}
} else {
+ val isSsReactivated = MediaPlayerData.isSsReactivated(key)
removePlayer(key, dismissMediaData = false, dismissRecommendation = false)
- addOrUpdatePlayer(key = key, oldKey = null, data = data)
+ addOrUpdatePlayer(
+ key = key, oldKey = null, data = data, isSsReactivated = isSsReactivated)
}
}
}
@@ -681,12 +690,18 @@ class MediaCarouselController @Inject constructor(
startDelay: Long = 0
) {
desiredHostState?.let {
+ if (this.desiredLocation != desiredLocation) {
+ // Only log an event when location changes
+ logger.logCarouselPosition(desiredLocation)
+ }
+
// This is a hosting view, let's remeasure our players
this.desiredLocation = desiredLocation
this.desiredHostState = it
currentlyExpanded = it.expansion > 0
- val shouldCloseGuts = !currentlyExpanded && !mediaManager.hasActiveMedia() &&
+ val shouldCloseGuts = !currentlyExpanded &&
+ !mediaManager.hasActiveMediaOrRecommendation() &&
desiredHostState.showsOnlyActiveMedia
for (mediaPlayer in MediaPlayerData.players()) {
@@ -751,7 +766,6 @@ class MediaCarouselController @Inject constructor(
val mediaControlPanel = MediaPlayerData.players().elementAt(visibleMediaIndex)
val hasActiveMediaOrRecommendationCard =
MediaPlayerData.hasActiveMediaOrRecommendationCard()
- val isRecommendationCard = mediaControlPanel.recommendationViewHolder != null
if (!hasActiveMediaOrRecommendationCard && !qsExpanded) {
// Skip logging if on LS or QQS, and there is no active media card
return
@@ -759,7 +773,6 @@ class MediaCarouselController @Inject constructor(
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
mediaControlPanel.mSmartspaceId,
mediaControlPanel.mUid,
- isRecommendationCard,
intArrayOf(mediaControlPanel.surfaceForSmartspaceLogging))
mediaControlPanel.mIsImpressed = true
}
@@ -773,7 +786,6 @@ class MediaCarouselController @Inject constructor(
* @param instanceId id to uniquely identify a card, e.g. each headphone generates a new
* instanceId
* @param uid uid for the application that media comes from
- * @param isRecommendationCard whether the card is media recommendation
* @param surfaces list of display surfaces the media card is on (e.g. lockscreen, shade) when
* the event happened
* @param interactedSubcardRank the rank for interacted media item for recommendation card, -1
@@ -783,21 +795,27 @@ class MediaCarouselController @Inject constructor(
* @param rank the rank for media card in the media carousel, starting from 0
* @param receivedLatencyMillis latency in milliseconds for card received events. E.g. latency
* between headphone connection to sysUI displays media recommendation card
+ * @param isSwipeToDismiss whether is to log swipe-to-dismiss event
*
*/
fun logSmartspaceCardReported(
eventId: Int,
instanceId: Int,
uid: Int,
- isRecommendationCard: Boolean,
surfaces: IntArray,
interactedSubcardRank: Int = 0,
interactedSubcardCardinality: Int = 0,
rank: Int = mediaCarouselScrollHandler.visibleMediaIndex,
- receivedLatencyMillis: Int = 0
+ receivedLatencyMillis: Int = 0,
+ isSwipeToDismiss: Boolean = false
) {
+ if (MediaPlayerData.players().size <= rank) {
+ return
+ }
+
+ val mediaControlKey = MediaPlayerData.playerKeys().elementAt(rank)
// Only log media resume card when Smartspace data is available
- if (!isRecommendationCard &&
+ if (!mediaControlKey.isSsMediaRec &&
!mediaManager.smartspaceMediaData.isActive &&
MediaPlayerData.smartspaceMediaData == null) {
return
@@ -813,10 +831,13 @@ class MediaCarouselController @Inject constructor(
// card type for each new feature.
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__UNKNOWN_CARD,
surface,
- rank,
+ // Use -1 as rank value to indicate user swipe to dismiss the card
+ if (isSwipeToDismiss) -1 else rank,
cardinality,
- if (isRecommendationCard)
+ if (mediaControlKey.isSsMediaRec)
15 // MEDIA_RECOMMENDATION
+ else if (mediaControlKey.isSsReactivated)
+ 43 // MEDIA_RESUME_SS_ACTIVATED
else
31, // MEDIA_RESUME
uid,
@@ -828,7 +849,9 @@ class MediaCarouselController @Inject constructor(
if (DEBUG) {
Log.d(TAG, "Log Smartspace card event id: $eventId instance id: $instanceId" +
" surface: $surface rank: $rank cardinality: $cardinality " +
- "isRecommendationCard: $isRecommendationCard uid: $uid " +
+ "isRecommendationCard: ${mediaControlKey.isSsMediaRec} " +
+ "isSsReactivated: ${mediaControlKey.isSsReactivated}" +
+ "uid: $uid " +
"interactedSubcardRank: $interactedSubcardRank " +
"interactedSubcardCardinality: $interactedSubcardCardinality " +
"received_latency_millis: $receivedLatencyMillis")
@@ -843,10 +866,9 @@ class MediaCarouselController @Inject constructor(
logSmartspaceCardReported(SMARTSPACE_CARD_DISMISS_EVENT,
it.mSmartspaceId,
it.mUid,
- it.recommendationViewHolder != null,
intArrayOf(it.surfaceForSmartspaceLogging),
- // Use -1 as rank value to indicate user swipe to dismiss the card
- rank = -1)
+ rank = index,
+ isSwipeToDismiss = true)
// Reset card impressed state when swipe to dismissed
it.mIsImpressed = false
}
@@ -897,29 +919,37 @@ internal object MediaPlayerData {
private set
data class MediaSortKey(
- // Whether the item represents a Smartspace media recommendation.
- val isSsMediaRec: Boolean,
+ val isSsMediaRec: Boolean, // Whether the item represents a Smartspace media recommendation.
val data: MediaData,
- val updateTime: Long = 0
+ val updateTime: Long = 0,
+ val isSsReactivated: Boolean = false
)
private val comparator =
compareByDescending<MediaSortKey> { it.data.isPlaying == true &&
it.data.playbackLocation == MediaData.PLAYBACK_LOCAL }
- .thenByDescending { it.data.isPlaying == true &&
- it.data.playbackLocation == MediaData.PLAYBACK_CAST_LOCAL }
- .thenByDescending { if (shouldPrioritizeSs) it.isSsMediaRec else !it.isSsMediaRec }
- .thenByDescending { !it.data.resumption }
- .thenByDescending { it.data.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE }
- .thenByDescending { it.updateTime }
- .thenByDescending { it.data.notificationKey }
+ .thenByDescending { it.data.isPlaying == true &&
+ it.data.playbackLocation == MediaData.PLAYBACK_CAST_LOCAL
+ }
+ .thenByDescending { if (shouldPrioritizeSs) it.isSsMediaRec else !it.isSsMediaRec }
+ .thenByDescending { !it.data.resumption }
+ .thenByDescending { it.data.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE }
+ .thenByDescending { it.updateTime }
+ .thenByDescending { it.data.notificationKey }
private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator)
private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf()
- fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel, clock: SystemClock) {
+ fun addMediaPlayer(
+ key: String,
+ data: MediaData,
+ player: MediaControlPanel,
+ clock: SystemClock,
+ isSsReactivated: Boolean
+ ) {
removeMediaPlayer(key)
- val sortKey = MediaSortKey(isSsMediaRec = false, data, clock.currentTimeMillis())
+ val sortKey = MediaSortKey(isSsMediaRec = false,
+ data, clock.currentTimeMillis(), isSsReactivated = isSsReactivated)
mediaData.put(key, sortKey)
mediaPlayers.put(sortKey, player)
}
@@ -933,8 +963,8 @@ internal object MediaPlayerData {
) {
shouldPrioritizeSs = shouldPrioritize
removeMediaPlayer(key)
- val sortKey = MediaSortKey(/* isSsMediaRec= */ true,
- EMPTY.copy(isPlaying = false), clock.currentTimeMillis())
+ val sortKey = MediaSortKey(isSsMediaRec = true,
+ EMPTY.copy(isPlaying = false), clock.currentTimeMillis(), isSsReactivated = true)
mediaData.put(key, sortKey)
mediaPlayers.put(sortKey, player)
smartspaceMediaData = data
@@ -1014,4 +1044,8 @@ internal object MediaPlayerData {
}
return false
}
+
+ fun isSsReactivated(key: String): Boolean = mediaData.get(key)?.let {
+ it.isSsReactivated
+ } ?: false
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 7ac70bd78953..fffb30720af6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -178,8 +178,7 @@ public class MediaControlPanel {
if (mPackageName != null && mInstanceId != null) {
mLogger.logSeek(mUid, mPackageName, mInstanceId);
}
- logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT,
- /* isRecommendationCard */ false);
+ logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT);
return Unit.INSTANCE;
});
}
@@ -334,9 +333,8 @@ public class MediaControlPanel {
mMediaViewHolder.getPlayer().setOnClickListener(v -> {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
if (mMediaViewController.isGutsVisible()) return;
-
- logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT,
- /* isRecommendationCard */ false);
+ mLogger.logTapContentView(mUid, mPackageName, mInstanceId);
+ logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT);
mActivityStarter.postStartActivityDismissingKeyguard(clickIntent,
buildLaunchAnimatorController(mMediaViewHolder.getPlayer()));
});
@@ -440,9 +438,7 @@ public class MediaControlPanel {
mMediaViewHolder.getDismiss().setEnabled(isDismissible);
mMediaViewHolder.getDismiss().setOnClickListener(v -> {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
-
- logSmartspaceCardReported(SMARTSPACE_CARD_DISMISS_EVENT,
- /* isRecommendationCard */ false);
+ logSmartspaceCardReported(SMARTSPACE_CARD_DISMISS_EVENT);
mLogger.logLongPressDismiss(mUid, mPackageName, mInstanceId);
if (mKey != null) {
@@ -683,8 +679,7 @@ public class MediaControlPanel {
button.setOnClickListener(v -> {
if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
mLogger.logTapAction(button.getId(), mUid, mPackageName, mInstanceId);
- logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT,
- /* isRecommendationCard */ false);
+ logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT);
action.run();
if (icon instanceof Animatable) {
@@ -932,8 +927,9 @@ public class MediaControlPanel {
mRecommendationViewHolder.getDismiss().setOnClickListener(v -> {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
- logSmartspaceCardReported(SMARTSPACE_CARD_DISMISS_EVENT,
- /* isRecommendationCard */ true);
+ logSmartspaceCardReported(
+ 761 // SMARTSPACE_CARD_DISMISS
+ );
closeGuts();
mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
data.getTargetId(), MediaViewController.GUTS_ANIMATION_DURATION + 100L);
@@ -1068,7 +1064,6 @@ public class MediaControlPanel {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT,
- /* isRecommendationCard */ true,
interactedSubcardRank,
getSmartspaceSubCardCardinality());
@@ -1138,18 +1133,17 @@ public class MediaControlPanel {
return SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__DEFAULT_SURFACE;
}
- private void logSmartspaceCardReported(int eventId, boolean isRecommendationCard) {
- logSmartspaceCardReported(eventId, isRecommendationCard,
+ private void logSmartspaceCardReported(int eventId) {
+ logSmartspaceCardReported(eventId,
/* interactedSubcardRank */ 0,
/* interactedSubcardCardinality */ 0);
}
- private void logSmartspaceCardReported(int eventId, boolean isRecommendationCard,
+ private void logSmartspaceCardReported(int eventId,
int interactedSubcardRank, int interactedSubcardCardinality) {
mMediaCarouselController.logSmartspaceCardReported(eventId,
mSmartspaceId,
mUid,
- isRecommendationCard,
new int[]{getSurfaceForSmartspaceLogging()},
interactedSubcardRank,
interactedSubcardCardinality);
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
index b68f2a7654f0..311973ad5af0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
@@ -32,7 +32,8 @@ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
oldKey: String?,
data: MediaData,
immediately: Boolean,
- receivedSmartspaceCardLatency: Int
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
) {
if (oldKey != null && oldKey != key && entries.contains(oldKey)) {
entries[key] = data to entries.remove(oldKey)?.second
@@ -46,8 +47,7 @@ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
override fun onSmartspaceMediaDataLoaded(
key: String,
data: SmartspaceMediaData,
- shouldPrioritize: Boolean,
- isSsReactivated: Boolean
+ shouldPrioritize: Boolean
) {
listeners.toSet().forEach { it.onSmartspaceMediaDataLoaded(key, data) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
index de44a9c46963..80a407b9d90f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
@@ -89,7 +89,8 @@ class MediaDataFilter @Inject constructor(
oldKey: String?,
data: MediaData,
immediately: Boolean,
- receivedSmartspaceCardLatency: Int
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
) {
if (oldKey != null && oldKey != key) {
allEntries.remove(oldKey)
@@ -114,8 +115,7 @@ class MediaDataFilter @Inject constructor(
override fun onSmartspaceMediaDataLoaded(
key: String,
data: SmartspaceMediaData,
- shouldPrioritize: Boolean,
- isSsReactivated: Boolean
+ shouldPrioritize: Boolean
) {
if (!data.isActive) {
Log.d(TAG, "Inactive recommendation data. Skip triggering.")
@@ -140,13 +140,12 @@ class MediaDataFilter @Inject constructor(
}
}
- val activeMedia = userEntries.filter { (key, value) -> value.active }
- var isSsReactivatedMutable = activeMedia.isEmpty() && userEntries.isNotEmpty()
+ val shouldReactivate = !hasActiveMedia() && hasAnyMedia()
if (timeSinceActive < smartspaceMaxAgeMillis) {
// It could happen there are existing active media resume cards, then we don't need to
// reactivate.
- if (isSsReactivatedMutable) {
+ if (shouldReactivate) {
val lastActiveKey = sorted.lastKey() // most recently active
// Notify listeners to consider this media active
Log.d(TAG, "reactivating $lastActiveKey instead of smartspace")
@@ -156,7 +155,7 @@ class MediaDataFilter @Inject constructor(
it.onMediaDataLoaded(lastActiveKey, lastActiveKey, mediaData,
receivedSmartspaceCardLatency =
(systemClock.currentTimeMillis() - data.headphoneConnectionTimeMillis)
- .toInt())
+ .toInt(), isSsReactivated = true)
}
}
} else {
@@ -168,8 +167,7 @@ class MediaDataFilter @Inject constructor(
Log.d(TAG, "Invalid recommendation data. Skip showing the rec card")
return
}
- listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data, shouldPrioritizeMutable,
- isSsReactivatedMutable) }
+ listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data, shouldPrioritizeMutable) }
}
override fun onMediaDataRemoved(key: String) {
@@ -260,14 +258,27 @@ class MediaDataFilter @Inject constructor(
}
/**
- * Are there any media notifications active?
+ * Are there any media notifications active, including the recommendation?
*/
- fun hasActiveMedia() = userEntries.any { it.value.active } || smartspaceMediaData.isActive
+ fun hasActiveMediaOrRecommendation() =
+ userEntries.any { it.value.active } ||
+ (smartspaceMediaData.isActive && smartspaceMediaData.isValid)
/**
* Are there any media entries we should display?
*/
- fun hasAnyMedia() = userEntries.isNotEmpty() || smartspaceMediaData.isActive
+ fun hasAnyMediaOrRecommendation() = userEntries.isNotEmpty() ||
+ (smartspaceMediaData.isActive && smartspaceMediaData.isValid)
+
+ /**
+ * Are there any media notifications active (excluding the recommendation)?
+ */
+ fun hasActiveMedia() = userEntries.any { it.value.active }
+
+ /**
+ * Are there any media entries we should display (excluding the recommendation)?
+ */
+ fun hasAnyMedia() = userEntries.isNotEmpty()
/**
* Add a listener for filtered [MediaData] changes
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 08c3395b4528..908aef41034e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -1079,15 +1079,27 @@ class MediaDataManager(
fun onSwipeToDismiss() = mediaDataFilter.onSwipeToDismiss()
/**
- * Are there any media notifications active?
+ * Are there any media notifications active, including the recommendations?
*/
- fun hasActiveMedia() = mediaDataFilter.hasActiveMedia()
+ fun hasActiveMediaOrRecommendation() = mediaDataFilter.hasActiveMediaOrRecommendation()
/**
- * Are there any media entries we should display?
+ * Are there any media entries we should display, including the recommendations?
* If resumption is enabled, this will include inactive players
* If resumption is disabled, we only want to show active players
*/
+ fun hasAnyMediaOrRecommendation() = mediaDataFilter.hasAnyMediaOrRecommendation()
+
+ /**
+ * Are there any resume media notifications active, excluding the recommendations?
+ */
+ fun hasActiveMedia() = mediaDataFilter.hasActiveMedia()
+
+ /**
+ * Are there any resume media notifications active, excluding the recommendations?
+ * If resumption is enabled, this will include inactive players
+ * If resumption is disabled, we only want to show active players
+ */
fun hasAnyMedia() = mediaDataFilter.hasAnyMedia()
interface Listener {
@@ -1106,13 +1118,17 @@ class MediaDataManager(
* @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI
* displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace
* signal.
+ *
+ * @param isSsReactivated indicates resume media card is reactivated by Smartspace
+ * recommendation signal
*/
fun onMediaDataLoaded(
key: String,
oldKey: String?,
data: MediaData,
immediately: Boolean = true,
- receivedSmartspaceCardLatency: Int = 0
+ receivedSmartspaceCardLatency: Int = 0,
+ isSsReactivated: Boolean = false
) {}
/**
@@ -1121,15 +1137,11 @@ class MediaDataManager(
* @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true,
* it will be prioritized as the first card. Otherwise, it will show up as the last card as
* default.
- *
- * @param isSsReactivated indicates resume media card is reactivated by Smartspace
- * recommendation signal
*/
fun onSmartspaceMediaDataLoaded(
key: String,
data: SmartspaceMediaData,
- shouldPrioritize: Boolean = false,
- isSsReactivated: Boolean = false
+ shouldPrioritize: Boolean = false
) {}
/** Called whenever a previously existing Media notification was removed. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index ffae898d07fa..824a6fd9d96e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -72,7 +72,8 @@ class MediaDeviceManager @Inject constructor(
oldKey: String?,
data: MediaData,
immediately: Boolean,
- receivedSmartspaceCardLatency: Int
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
) {
if (oldKey != null && oldKey != key) {
val oldEntry = entries.remove(oldKey)
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 3d9f933b3a05..30771c728e86 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -1146,7 +1146,10 @@ private val EMPTY_RECT = Rect()
@Retention(AnnotationRetention.SOURCE)
private annotation class TransformationType
-@IntDef(prefix = ["LOCATION_"], value = [MediaHierarchyManager.LOCATION_QS,
- MediaHierarchyManager.LOCATION_QQS, MediaHierarchyManager.LOCATION_LOCKSCREEN])
+@IntDef(prefix = ["LOCATION_"], value = [
+ MediaHierarchyManager.LOCATION_QS,
+ MediaHierarchyManager.LOCATION_QQS,
+ MediaHierarchyManager.LOCATION_LOCKSCREEN,
+ MediaHierarchyManager.LOCATION_DREAM_OVERLAY])
@Retention(AnnotationRetention.SOURCE)
annotation class MediaLocation
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
index d08b6f825f41..de2b5c9a4739 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
@@ -68,7 +68,8 @@ class MediaHost constructor(
oldKey: String?,
data: MediaData,
immediately: Boolean,
- receivedSmartspaceCardLatency: Int
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
) {
if (immediately) {
updateViewVisibility()
@@ -78,8 +79,7 @@ class MediaHost constructor(
override fun onSmartspaceMediaDataLoaded(
key: String,
data: SmartspaceMediaData,
- shouldPrioritize: Boolean,
- isSsReactivated: Boolean
+ shouldPrioritize: Boolean
) {
updateViewVisibility()
}
@@ -169,9 +169,9 @@ class MediaHost constructor(
private fun updateViewVisibility() {
state.visible = if (showsOnlyActiveMedia) {
- mediaDataManager.hasActiveMedia()
+ mediaDataManager.hasActiveMediaOrRecommendation()
} else {
- mediaDataManager.hasAnyMedia()
+ mediaDataManager.hasAnyMediaOrRecommendation()
}
val newVisibility = if (visible) View.VISIBLE else View.GONE
if (newVisibility != hostView.visibility) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
index 35f95dd27c1f..61d0b41e9bb6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
@@ -184,7 +184,8 @@ class MediaResumeListener @Inject constructor(
oldKey: String?,
data: MediaData,
immediately: Boolean,
- receivedSmartspaceCardLatency: Int
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
) {
if (useMediaResumption) {
// If this had been started from a resume state, disconnect now that it's live
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
index 1c448a2ff8c4..31792967899d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
@@ -96,7 +96,8 @@ class MediaSessionBasedFilter @Inject constructor(
oldKey: String?,
data: MediaData,
immediately: Boolean,
- receivedSmartspaceCardLatency: Int
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
) {
backgroundExecutor.execute {
data.token?.let {
@@ -143,8 +144,7 @@ class MediaSessionBasedFilter @Inject constructor(
override fun onSmartspaceMediaDataLoaded(
key: String,
data: SmartspaceMediaData,
- shouldPrioritize: Boolean,
- isSsReactivated: Boolean
+ shouldPrioritize: Boolean
) {
backgroundExecutor.execute {
dispatchSmartspaceMediaDataLoaded(key, data)
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
index 9581a633a8c5..51755065d4b6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
@@ -63,7 +63,8 @@ class MediaTimeoutListener @Inject constructor(
oldKey: String?,
data: MediaData,
immediately: Boolean,
- receivedSmartspaceCardLatency: Int
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
) {
var reusedListener: PlaybackStateListener? = null
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
index 862b2797b77c..0fc58132b4d7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
@@ -134,6 +134,23 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
fun logOpenOutputSwitcher(uid: Int, packageName: String, instanceId: InstanceId) {
logger.logWithInstanceId(MediaUiEvent.OPEN_OUTPUT_SWITCHER, uid, packageName, instanceId)
}
+
+ fun logTapContentView(uid: Int, packageName: String, instanceId: InstanceId) {
+ logger.logWithInstanceId(MediaUiEvent.MEDIA_TAP_CONTENT_VIEW, uid, packageName, instanceId)
+ }
+
+ fun logCarouselPosition(@MediaLocation location: Int) {
+ val event = when (location) {
+ MediaHierarchyManager.LOCATION_QQS -> MediaUiEvent.MEDIA_CAROUSEL_LOCATION_QQS
+ MediaHierarchyManager.LOCATION_QS -> MediaUiEvent.MEDIA_CAROUSEL_LOCATION_QS
+ MediaHierarchyManager.LOCATION_LOCKSCREEN ->
+ MediaUiEvent.MEDIA_CAROUSEL_LOCATION_LOCKSCREEN
+ MediaHierarchyManager.LOCATION_DREAM_OVERLAY ->
+ MediaUiEvent.MEDIA_CAROUSEL_LOCATION_DREAM
+ else -> throw IllegalArgumentException("Unknown media carousel location $location")
+ }
+ logger.log(event)
+ }
}
enum class MediaUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
@@ -201,7 +218,22 @@ enum class MediaUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
ACTION_SEEK(1027),
@UiEvent(doc = "The user opened the output switcher from a media control")
- OPEN_OUTPUT_SWITCHER(1028);
+ OPEN_OUTPUT_SWITCHER(1028),
+
+ @UiEvent(doc = "The user tapped on a media control view")
+ MEDIA_TAP_CONTENT_VIEW(1036),
+
+ @UiEvent(doc = "The media carousel moved to QQS")
+ MEDIA_CAROUSEL_LOCATION_QQS(1037),
+
+ @UiEvent(doc = "THe media carousel moved to QS")
+ MEDIA_CAROUSEL_LOCATION_QS(1038),
+
+ @UiEvent(doc = "The media carousel moved to the lockscreen")
+ MEDIA_CAROUSEL_LOCATION_LOCKSCREEN(1039),
+
+ @UiEvent(doc = "The media carousel moved to the dream state")
+ MEDIA_CAROUSEL_LOCATION_DREAM(1040);
override fun getId() = metricId
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java
index 8934cd1085b8..e077fed7805d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java
@@ -56,13 +56,13 @@ public class MediaDreamSentinel extends CoreStartable {
@Override
public void onSmartspaceMediaDataLoaded(@NonNull String key,
- @NonNull SmartspaceMediaData data, boolean shouldPrioritize,
- boolean isSsReactivated) {
+ @NonNull SmartspaceMediaData data, boolean shouldPrioritize) {
}
@Override
public void onMediaDataLoaded(@NonNull String key, @Nullable String oldKey,
- @NonNull MediaData data, boolean immediately, int receivedSmartspaceCardLatency) {
+ @NonNull MediaData data, boolean immediately, int receivedSmartspaceCardLatency,
+ boolean isSsReactivated) {
if (mAdded) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
index 03652412c129..e5dc0ec54676 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
@@ -360,9 +360,7 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
.getDimension(R.dimen.navigation_edge_action_drag_threshold);
mSwipeProgressThreshold = context.getResources()
.getDimension(R.dimen.navigation_edge_action_progress_threshold);
- if (mBackAnimation != null) {
- mBackAnimation.setSwipeThresholds(mSwipeTriggerThreshold, mSwipeProgressThreshold);
- }
+ initializeBackAnimation();
setVisibility(GONE);
Executor backgroundExecutor = Dependency.get(Dependency.BACKGROUND_EXECUTOR);
@@ -391,6 +389,13 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
public void setBackAnimation(BackAnimation backAnimation) {
mBackAnimation = backAnimation;
+ initializeBackAnimation();
+ }
+
+ private void initializeBackAnimation() {
+ if (mBackAnimation != null) {
+ mBackAnimation.setSwipeThresholds(mSwipeTriggerThreshold, mSwipeProgressThreshold);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index e0d158cd7db6..2ffbf5418583 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -50,6 +50,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
+import com.android.systemui.shared.system.SysUiStatsLog
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.util.DeviceConfigProxy
import com.android.systemui.util.indentIfPossible
@@ -283,6 +284,7 @@ class FgsManagerController @Inject constructor(
runningApps[it] = RunningApp(it.userId, it.packageName,
runningServiceTokens[it]!!.startTime, it.uiControl,
ai.loadLabel(packageManager), ai.loadIcon(packageManager))
+ logEvent(stopped = false, it.packageName, it.userId, runningApps[it]!!.timeStarted)
}
removedPackages.forEach { pkg ->
@@ -301,10 +303,25 @@ class FgsManagerController @Inject constructor(
}
}
- private fun stopPackage(userId: Int, packageName: String) {
+ private fun stopPackage(userId: Int, packageName: String, timeStarted: Long) {
+ logEvent(stopped = true, packageName, userId, timeStarted)
activityManager.stopAppForUser(packageName, userId)
}
+ private fun logEvent(stopped: Boolean, packageName: String, userId: Int, timeStarted: Long) {
+ val timeLogged = systemClock.elapsedRealtime()
+ val event = if (stopped) {
+ SysUiStatsLog.TASK_MANAGER_EVENT_REPORTED__EVENT__STOPPED
+ } else {
+ SysUiStatsLog.TASK_MANAGER_EVENT_REPORTED__EVENT__VIEWED
+ }
+ backgroundExecutor.execute {
+ val uid = packageManager.getPackageUidAsUser(packageName, userId)
+ SysUiStatsLog.write(SysUiStatsLog.TASK_MANAGER_EVENT_REPORTED, uid, event,
+ timeLogged - timeStarted)
+ }
+ }
+
private inner class AppListAdapter : RecyclerView.Adapter<AppItemViewHolder>() {
private val lock = Any()
@@ -329,7 +346,7 @@ class FgsManagerController @Inject constructor(
DateUtils.LENGTH_MEDIUM)
stopButton.setOnClickListener {
stopButton.setText(R.string.fgs_manager_app_item_stop_button_stopped_label)
- stopPackage(runningApp.userId, runningApp.packageName)
+ stopPackage(runningApp.userId, runningApp.packageName, runningApp.timeStarted)
}
if (runningApp.uiControl == UIControl.HIDE_BUTTON) {
stopButton.visibility = View.INVISIBLE
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
index 842a1b92f690..3f394e7b5309 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
@@ -23,7 +23,6 @@ import android.provider.Settings
import android.provider.Settings.Global.USER_SWITCHER_ENABLED
import android.view.View
import android.view.ViewGroup
-import android.widget.LinearLayout
import androidx.annotation.VisibleForTesting
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.MetricsLogger
@@ -32,8 +31,6 @@ import com.android.internal.logging.nano.MetricsProto
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
import com.android.systemui.globalactions.GlobalActionsDialogLite
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
@@ -45,7 +42,6 @@ import com.android.systemui.statusbar.phone.SettingsButton
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.statusbar.policy.UserInfoController
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener
-import com.android.systemui.util.DualHeightHorizontalLinearLayout
import com.android.systemui.util.ViewController
import com.android.systemui.util.settings.GlobalSettings
import javax.inject.Inject
@@ -74,8 +70,7 @@ internal class FooterActionsController @Inject constructor(
private val uiEventLogger: UiEventLogger,
@Named(PM_LITE_ENABLED) private val showPMLiteButton: Boolean,
private val globalSetting: GlobalSettings,
- private val handler: Handler,
- private val featureFlags: FeatureFlags
+ private val handler: Handler
) : ViewController<FooterActionsView>(view) {
private var globalActionsDialog: GlobalActionsDialogLite? = null
@@ -100,7 +95,9 @@ internal class FooterActionsController @Inject constructor(
view.findViewById(R.id.security_footers_container)
private val powerMenuLite: View = view.findViewById(R.id.pm_lite)
private val multiUserSwitchController = multiUserSwitchControllerFactory.create(view)
- private val securityFootersSeparator = View(context).apply {
+
+ @VisibleForTesting
+ internal val securityFootersSeparator = View(context).apply {
visibility = View.GONE
}
@@ -140,6 +137,7 @@ internal class FooterActionsController @Inject constructor(
override fun onInit() {
multiUserSwitchController.init()
+ securityFooterController.init()
fgsManagerFooterController.init()
}
@@ -170,48 +168,30 @@ internal class FooterActionsController @Inject constructor(
}
settingsButton.setOnClickListener(onClickListener)
multiUserSetting.isListening = true
- if (featureFlags.isEnabled(Flags.NEW_FOOTER)) {
- val securityFooter = securityFooterController.view as DualHeightHorizontalLinearLayout
- securityFootersContainer?.addView(securityFooter)
- val separatorWidth = resources.getDimensionPixelSize(R.dimen.new_qs_footer_action_inset)
- securityFootersContainer?.addView(securityFootersSeparator, separatorWidth, 1)
- reformatForNewFooter(securityFooter)
- val fgsFooter = fgsManagerFooterController.view
- securityFootersContainer?.addView(fgsFooter)
- (fgsFooter.layoutParams as LinearLayout.LayoutParams).apply {
- width = 0
- weight = 1f
- }
- val visibilityListener =
- VisibilityChangedDispatcher.OnVisibilityChangedListener { visibility ->
- if (visibility == View.GONE) {
- securityFootersSeparator.visibility = View.GONE
- } else if (securityFooter.visibility == View.VISIBLE &&
- fgsFooter.visibility == View.VISIBLE) {
- securityFootersSeparator.visibility = View.VISIBLE
- } else {
- securityFootersSeparator.visibility = View.GONE
- }
- fgsManagerFooterController
- .setCollapsed(securityFooter.visibility == View.VISIBLE)
+ val securityFooter = securityFooterController.view
+ securityFootersContainer?.addView(securityFooter)
+ val separatorWidth = resources.getDimensionPixelSize(R.dimen.qs_footer_action_inset)
+ securityFootersContainer?.addView(securityFootersSeparator, separatorWidth, 1)
+
+ val fgsFooter = fgsManagerFooterController.view
+ securityFootersContainer?.addView(fgsFooter)
+
+ val visibilityListener =
+ VisibilityChangedDispatcher.OnVisibilityChangedListener { visibility ->
+ if (securityFooter.visibility == View.VISIBLE &&
+ fgsFooter.visibility == View.VISIBLE) {
+ securityFootersSeparator.visibility = View.VISIBLE
+ } else {
+ securityFootersSeparator.visibility = View.GONE
}
- securityFooterController.setOnVisibilityChangedListener(visibilityListener)
- fgsManagerFooterController.setOnVisibilityChangedListener(visibilityListener)
- }
- updateView()
- }
+ fgsManagerFooterController
+ .setCollapsed(securityFooter.visibility == View.VISIBLE)
+ }
+ securityFooterController.setOnVisibilityChangedListener(visibilityListener)
+ fgsManagerFooterController.setOnVisibilityChangedListener(visibilityListener)
- private fun reformatForNewFooter(view: DualHeightHorizontalLinearLayout) {
- // This is only necessary while things are flagged as the view could be attached in two
- // different locations.
- (view.layoutParams as LinearLayout.LayoutParams).apply {
- bottomMargin = 0
- width = 0
- weight = 1f
- marginEnd = resources.getDimensionPixelSize(R.dimen.new_qs_footer_action_inset)
- }
- view.alwaysSingleLine = true
+ updateView()
}
private fun updateView() {
@@ -236,10 +216,9 @@ internal class FooterActionsController @Inject constructor(
} else {
userInfoController.removeCallback(onUserInfoChangedListener)
}
- if (featureFlags.isEnabled(Flags.NEW_FOOTER)) {
- fgsManagerFooterController.setListening(listening)
- securityFooterController.setListening(listening)
- }
+
+ fgsManagerFooterController.setListening(listening)
+ securityFooterController.setListening(listening)
}
fun disable(state2: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index d20141b33838..34f771ce0431 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -15,6 +15,7 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.Scroller;
@@ -552,6 +553,51 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
postInvalidateOnAnimation();
}
+ private int sanitizePageAction(int action) {
+ int pageLeftId = AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT.getId();
+ int pageRightId = AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT.getId();
+ if (action == pageLeftId || action == pageRightId) {
+ if (!isLayoutRtl()) {
+ if (action == pageLeftId) {
+ return AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD;
+ } else {
+ return AccessibilityNodeInfo.ACTION_SCROLL_FORWARD;
+ }
+ } else {
+ if (action == pageLeftId) {
+ return AccessibilityNodeInfo.ACTION_SCROLL_FORWARD;
+ } else {
+ return AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD;
+ }
+ }
+ }
+ return action;
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ action = sanitizePageAction(action);
+ boolean performed = super.performAccessibilityAction(action, arguments);
+ if (performed && (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
+ || action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)) {
+ requestAccessibilityFocus();
+ }
+ return performed;
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfoInternal(info);
+ // getCurrentItem does not respect RTL, so it works well together with page actions that
+ // use left/right positioning.
+ if (getCurrentItem() != 0) {
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT);
+ }
+ if (getCurrentItem() != mPages.size() - 1) {
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT);
+ }
+ }
+
private static Animator setupBounceAnimator(View view, int ordinal) {
view.setAlpha(0f);
view.setScaleX(0f);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 4640205c82f5..56298fa155fa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -81,8 +81,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private final QSPanelController mQsPanelController;
private final QuickQSPanelController mQuickQSPanelController;
private final QuickStatusBarHeader mQuickStatusBarHeader;
- private final QSFgsManagerFooter mFgsManagerFooter;
- private final QSSecurityFooter mSecurityFooter;
private final QS mQs;
@Nullable
@@ -105,7 +103,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private TouchAnimator mNonfirstPageAlphaAnimator;
// TranslatesY the QS Tile layout using QS.getHeightDiff()
private TouchAnimator mQSTileLayoutTranslatorAnimator;
- // This animates fading of SecurityFooter and media divider
+ // This animates fading of media player
private TouchAnimator mAllPagesDelayedAnimator;
// Animator for brightness slider(s)
@Nullable
@@ -146,7 +144,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
public QSAnimator(QS qs, QuickQSPanel quickPanel, QuickStatusBarHeader quickStatusBarHeader,
QSPanelController qsPanelController,
QuickQSPanelController quickQSPanelController, QSTileHost qsTileHost,
- QSFgsManagerFooter fgsManagerFooter, QSSecurityFooter securityFooter,
@Main Executor executor, TunerService tunerService,
QSExpansionPathInterpolator qsExpansionPathInterpolator) {
mQs = qs;
@@ -154,8 +151,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
mQsPanelController = qsPanelController;
mQuickQSPanelController = quickQSPanelController;
mQuickStatusBarHeader = quickStatusBarHeader;
- mFgsManagerFooter = fgsManagerFooter;
- mSecurityFooter = securityFooter;
mHost = qsTileHost;
mExecutor = executor;
mTunerService = tunerService;
@@ -472,10 +467,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
.setListener(this)
.build();
- // Fade in the security footer and the divider as we reach the final position
+ // Fade in the media player as we reach the final position
Builder builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY);
- builder.addFloat(mFgsManagerFooter.getView(), "alpha", 0, 1);
- builder.addFloat(mSecurityFooter.getView(), "alpha", 0, 1);
if (mQsPanelController.shouldUseHorizontalLayout()
&& mQsPanelController.mMediaHost.hostView != null) {
builder.addFloat(mQsPanelController.mMediaHost.hostView, "alpha", 0, 1);
@@ -484,8 +477,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
mQsPanelController.mMediaHost.hostView.setAlpha(1.0f);
}
mAllPagesDelayedAnimator = builder.build();
- mAllViews.add(mFgsManagerFooter.getView());
- mAllViews.add(mSecurityFooter.getView());
translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
qqsTranslationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
translationXBuilder.setInterpolator(mQSExpansionPathInterpolator.getXInterpolator());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 519ed5ceeab4..66584414e291 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -138,12 +138,8 @@ public class QSContainerImpl extends FrameLayout implements Dumpable {
}
void updateResources(QSPanelController qsPanelController,
- QuickStatusBarHeaderController quickStatusBarHeaderController,
- boolean newFooter) {
- int bottomPadding = 0;
- if (newFooter) {
- bottomPadding = getResources().getDimensionPixelSize(R.dimen.qs_panel_padding_bottom);
- }
+ QuickStatusBarHeaderController quickStatusBarHeaderController) {
+ int bottomPadding = getResources().getDimensionPixelSize(R.dimen.qs_panel_padding_bottom);
mQSPanelContainer.setPaddingRelative(
mQSPanelContainer.getPaddingStart(),
QSUtils.getQsHeaderSystemIconsAreaHeight(mContext),
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
index 61da18224023..7d61991c910a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
@@ -18,8 +18,6 @@ package com.android.systemui.qs;
import android.content.res.Configuration;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.ViewController;
@@ -32,26 +30,23 @@ public class QSContainerImplController extends ViewController<QSContainerImpl> {
private final QSPanelController mQsPanelController;
private final QuickStatusBarHeaderController mQuickStatusBarHeaderController;
private final ConfigurationController mConfigurationController;
- private final boolean mNewFooter;
private final ConfigurationController.ConfigurationListener mConfigurationListener =
new ConfigurationController.ConfigurationListener() {
@Override
public void onConfigChanged(Configuration newConfig) {
- mView.updateResources(mQsPanelController, mQuickStatusBarHeaderController, mNewFooter);
+ mView.updateResources(mQsPanelController, mQuickStatusBarHeaderController);
}
};
@Inject
QSContainerImplController(QSContainerImpl view, QSPanelController qsPanelController,
QuickStatusBarHeaderController quickStatusBarHeaderController,
- ConfigurationController configurationController,
- FeatureFlags featureFlags) {
+ ConfigurationController configurationController) {
super(view);
mQsPanelController = qsPanelController;
mQuickStatusBarHeaderController = quickStatusBarHeaderController;
mConfigurationController = configurationController;
- mNewFooter = featureFlags.isEnabled(Flags.NEW_FOOTER);
}
@Override
@@ -65,7 +60,7 @@ public class QSContainerImplController extends ViewController<QSContainerImpl> {
@Override
protected void onViewAttached() {
- mView.updateResources(mQsPanelController, mQuickStatusBarHeaderController, mNewFooter);
+ mView.updateResources(mQsPanelController, mQuickStatusBarHeaderController);
mConfigurationController.addCallback(mConfigurationListener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index aac5672aa3f9..bcf60d1c1f4f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -48,10 +48,5 @@ public interface QSFooter {
*/
void setKeyguardShowing(boolean keyguardShowing);
- /**
- * Sets the {@link android.view.View.OnClickListener to be used on elements that expend QS.
- */
- void setExpandClickListener(View.OnClickListener onClickListener);
-
default void disable(int state1, int state2, boolean animate) {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
index 6c0ca49c81a8..61905ae00be8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
@@ -23,13 +23,11 @@ import android.content.res.Configuration;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Build;
-import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
@@ -168,23 +166,6 @@ public class QSFooterView extends FrameLayout {
super.onDetachedFromWindow();
}
- @Override
- public boolean performAccessibilityAction(int action, Bundle arguments) {
- if (action == AccessibilityNodeInfo.ACTION_EXPAND) {
- if (mExpandClickListener != null) {
- mExpandClickListener.onClick(null);
- return true;
- }
- }
- return super.performAccessibilityAction(action, arguments);
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
- }
-
void disable(int state2) {
final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
if (disabled == mQsDisabled) return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index bef4f43b9d11..0d29a1abca9f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -114,12 +114,6 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
mView.setKeyguardShowing();
}
- /** */
- @Override
- public void setExpandClickListener(View.OnClickListener onClickListener) {
- mView.setExpandClickListener(onClickListener);
- }
-
@Override
public void disable(int state1, int state2, boolean animate) {
mView.disable(state2);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index b5e1c5ee1a3e..4fa05c833f53 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -31,7 +31,6 @@ import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -212,7 +211,6 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
});
mHeader = view.findViewById(R.id.header);
- mQSPanelController.setHeaderContainer(view.findViewById(R.id.header_text_container));
mFooter = qsFragmentComponent.getQSFooter();
mQSContainerImplController = qsFragmentComponent.getQSContainerImplController();
@@ -717,8 +715,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
@Override
- public void setExpandClickListener(OnClickListener onClickListener) {
- mFooter.setExpandClickListener(onClickListener);
+ public void setCollapseExpandAction(Runnable action) {
+ mQSPanelController.setCollapseExpandAction(action);
+ mQuickQSPanelController.setCollapseExpandAction(action);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 11a36ada4e36..9fbdd3c873e2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -34,6 +34,7 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.LinearLayout;
import androidx.annotation.VisibleForTesting;
@@ -62,6 +63,8 @@ public class QSPanel extends LinearLayout implements Tunable {
private final int mMediaTopMargin;
private final int mMediaTotalBottomMargin;
+ private Runnable mCollapseExpandAction;
+
/**
* The index where the content starts that needs to be moved between parents
*/
@@ -72,7 +75,6 @@ public class QSPanel extends LinearLayout implements Tunable {
@Nullable
protected BrightnessSliderController mToggleSliderController;
- private final H mHandler = new H();
/** Whether or not the QS media player feature is enabled. */
protected boolean mUsingMediaPlayer;
@@ -84,16 +86,9 @@ public class QSPanel extends LinearLayout implements Tunable {
new ArrayList<>();
@Nullable
- protected View mFgsManagerFooter;
- @Nullable
- protected View mSecurityFooter;
-
- @Nullable
protected View mFooter;
@Nullable
- private ViewGroup mHeaderContainer;
- @Nullable
private PageIndicator mFooterPageIndicator;
private int mContentMarginStart;
private int mContentMarginEnd;
@@ -109,7 +104,6 @@ public class QSPanel extends LinearLayout implements Tunable {
private float mSquishinessFraction = 1f;
private final ArrayMap<View, Integer> mChildrenLayoutTop = new ArrayMap<>();
private final Rect mClippingRect = new Rect();
- private boolean mUseNewFooter = false;
private ViewGroup mMediaHostView;
private boolean mShouldMoveMediaOnExpansion = true;
@@ -153,10 +147,6 @@ public class QSPanel extends LinearLayout implements Tunable {
}
}
- void setUseNewFooter(boolean useNewFooter) {
- mUseNewFooter = useNewFooter;
- }
-
protected void setHorizontalContentContainerClipping() {
mHorizontalContentContainer.setClipChildren(true);
mHorizontalContentContainer.setClipToPadding(false);
@@ -441,27 +431,6 @@ public class QSPanel extends LinearLayout implements Tunable {
}
}
- /** Switch the security footer between top and bottom of QS depending on orientation. */
- public void switchSecurityFooter(boolean shouldUseSplitNotificationShade) {
- if (mSecurityFooter == null) return;
-
- if (!shouldUseSplitNotificationShade
- && mContext.getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE && mHeaderContainer != null) {
- // Adding the security view to the header, that enables us to avoid scrolling
- switchToParent(mSecurityFooter, mHeaderContainer, 0);
- } else {
- // Add after the footer
- int index;
- if (mFgsManagerFooter != null) {
- index = indexOfChild(mFgsManagerFooter);
- } else {
- index = indexOfChild(mFooter);
- }
- switchToParent(mSecurityFooter, this, index + 1);
- }
- }
-
private void switchToParent(View child, ViewGroup parent, int index) {
switchToParent(child, parent, index, getDumpableTag());
}
@@ -606,38 +575,10 @@ public class QSPanel extends LinearLayout implements Tunable {
}
}
- /**
- * Set the header container of quick settings.
- */
- public void setHeaderContainer(@NonNull ViewGroup headerContainer) {
- mHeaderContainer = headerContainer;
- }
-
public boolean isListening() {
return mListening;
}
- /**
- * Set the security footer view and switch it into the right place
- * @param view the view in question
- * @param shouldUseSplitNotificationShade if QS is in split shade mode
- */
- public void setSecurityFooter(View view, boolean shouldUseSplitNotificationShade) {
- mSecurityFooter = view;
- switchSecurityFooter(shouldUseSplitNotificationShade);
- }
-
- /**
- * Set the fgs manager footer view and switch it into the right place
- * @param view the view in question
- */
- public void setFgsManagerFooter(View view) {
- mFgsManagerFooter = view;
- // Add after the footer
- int index = indexOfChild(mFooter);
- switchToParent(mFgsManagerFooter, this, index + 1);
- }
-
protected void setPageMargin(int pageMargin) {
if (mTileLayout instanceof PagedTileLayout) {
((PagedTileLayout) mTileLayout).setPageMargin(pageMargin);
@@ -678,6 +619,28 @@ public class QSPanel extends LinearLayout implements Tunable {
mShouldMoveMediaOnExpansion = shouldMoveMediaOnExpansion;
}
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ if (action == AccessibilityNodeInfo.ACTION_EXPAND
+ || action == AccessibilityNodeInfo.ACTION_COLLAPSE) {
+ if (mCollapseExpandAction != null) {
+ mCollapseExpandAction.run();
+ return true;
+ }
+ }
+ return super.performAccessibilityAction(action, arguments);
+ }
+
+ public void setCollapseExpandAction(Runnable action) {
+ mCollapseExpandAction = action;
+ }
+
private class H extends Handler {
private static final int ANNOUNCE_FOR_ACCESSIBILITY = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 10d792098608..5670836566ab 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -21,18 +21,14 @@ import static com.android.systemui.media.dagger.MediaModule.QS_PANEL;
import static com.android.systemui.qs.QSPanel.QS_SHOW_BRIGHTNESS;
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_USING_MEDIA_PLAYER;
-import android.annotation.NonNull;
import android.content.res.Configuration;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.media.MediaHostState;
@@ -56,8 +52,6 @@ import javax.inject.Named;
@QSScope
public class QSPanelController extends QSPanelControllerBase<QSPanel> {
- private final QSFgsManagerFooter mQSFgsManagerFooter;
- private final QSSecurityFooter mQsSecurityFooter;
private final TunerService mTunerService;
private final QSCustomizerController mQsCustomizerController;
private final QSTileRevealController.Factory mQsTileRevealControllerFactory;
@@ -65,7 +59,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
private final BrightnessController mBrightnessController;
private final BrightnessSliderController mBrightnessSliderController;
private final BrightnessMirrorHandler mBrightnessMirrorHandler;
- private final FeatureFlags mFeatureFlags;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private boolean mGridContentVisible = true;
@@ -75,11 +68,9 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
@Override
public void onConfigurationChange(Configuration newConfig) {
mView.updateResources();
- mQsSecurityFooter.onConfigurationChanged();
if (mView.isListening()) {
refreshAllTiles();
}
- mView.switchSecurityFooter(mShouldUseSplitNotificationShade);
}
};
@@ -94,8 +85,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
};
@Inject
- QSPanelController(QSPanel view, QSFgsManagerFooter qsFgsManagerFooter,
- QSSecurityFooter qsSecurityFooter, TunerService tunerService,
+ QSPanelController(QSPanel view, TunerService tunerService,
QSTileHost qstileHost, QSCustomizerController qsCustomizerController,
@Named(QS_USING_MEDIA_PLAYER) boolean usingMediaPlayer,
@Named(QS_PANEL) MediaHost mediaHost,
@@ -103,12 +93,10 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
DumpManager dumpManager, MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
QSLogger qsLogger, BrightnessController.Factory brightnessControllerFactory,
BrightnessSliderController.Factory brightnessSliderFactory,
- FalsingManager falsingManager, FeatureFlags featureFlags,
+ FalsingManager falsingManager,
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost,
metricsLogger, uiEventLogger, qsLogger, dumpManager);
- mQSFgsManagerFooter = qsFgsManagerFooter;
- mQsSecurityFooter = qsSecurityFooter;
mTunerService = tunerService;
mQsCustomizerController = qsCustomizerController;
mQsTileRevealControllerFactory = qsTileRevealControllerFactory;
@@ -119,9 +107,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
mBrightnessController = brightnessControllerFactory.create(mBrightnessSliderController);
mBrightnessMirrorHandler = new BrightnessMirrorHandler(mBrightnessController);
- mFeatureFlags = featureFlags;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
- view.setUseNewFooter(featureFlags.isEnabled(Flags.NEW_FOOTER));
}
@Override
@@ -132,7 +118,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
mMediaHost.init(MediaHierarchyManager.LOCATION_QS);
mQsCustomizerController.init();
mBrightnessSliderController.init();
- mQSFgsManagerFooter.init();
}
@Override
@@ -147,10 +132,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
refreshAllTiles();
}
mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
- if (!mFeatureFlags.isEnabled(Flags.NEW_FOOTER)) {
- mView.setSecurityFooter(mQsSecurityFooter.getView(), mShouldUseSplitNotificationShade);
- mView.setFgsManagerFooter(mQSFgsManagerFooter.getView());
- }
switchTileLayout(true);
mBrightnessMirrorHandler.onQsPanelAttached();
@@ -172,13 +153,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
super.onViewDetached();
}
- /**
- * Set the header container of quick settings.
- */
- public void setHeaderContainer(@NonNull ViewGroup headerContainer) {
- mView.setHeaderContainer(headerContainer);
- }
-
/** */
public void setVisibility(int visibility) {
mView.setVisibility(visibility);
@@ -191,11 +165,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
refreshAllTiles();
}
- if (!mFeatureFlags.isEnabled(Flags.NEW_FOOTER)) {
- mQSFgsManagerFooter.setListening(listening);
- mQsSecurityFooter.setListening(listening);
- }
-
// Set the listening as soon as the QS fragment starts listening regardless of the
//expansion, so it will update the current brightness before the slider is visible.
if (listening) {
@@ -214,10 +183,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
return mHost;
}
- /** Show the device monitoring dialog. */
- public void showDeviceMonitoringDialog() {
- mQsSecurityFooter.showDeviceMonitoringDialog();
- }
/** Update appearance of QSPanel. */
public void updateResources() {
@@ -228,8 +193,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
public void refreshAllTiles() {
mBrightnessController.checkRestrictionAndSetEnabled();
super.refreshAllTiles();
- mQSFgsManagerFooter.refreshState();
- mQsSecurityFooter.refreshState();
}
/** Start customizing the Quick Settings. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 74d1a3d43ab3..9c8fc4761f98 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -424,6 +424,14 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
return mView.getBrightnessView();
}
+ /**
+ * Set a listener to collapse/expand QS.
+ * @param action
+ */
+ public void setCollapseExpandAction(Runnable action) {
+ mView.setCollapseExpandAction(action);
+ }
+
/** Sets whether we are currently on lock screen. */
public void setIsOnKeyguard(boolean isOnKeyguard) {
boolean isOnSplitShadeLockscreen = mShouldUseSplitNotificationShade && isOnKeyguard;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index ea9bc6946ffe..7e0410c0674b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -41,25 +41,26 @@ import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_PE
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_MONITORING;
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_NAMED_VPN;
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_NETWORK;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_SECURITY_FOOTER_VIEW;
import android.app.AlertDialog;
+import android.app.Dialog;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.UserInfo;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.SpannableStringBuilder;
@@ -69,7 +70,6 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
@@ -81,15 +81,15 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.SecurityController;
+import com.android.systemui.util.ViewController;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -97,13 +97,13 @@ import javax.inject.Inject;
import javax.inject.Named;
@QSScope
-class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListener,
+class QSSecurityFooter extends ViewController<View>
+ implements OnClickListener, DialogInterface.OnClickListener,
VisibilityChangedDispatcher {
protected static final String TAG = "QSSecurityFooter";
protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final boolean DEBUG_FORCE_VISIBLE = false;
- private final View mRootView;
private final TextView mFooterText;
private final ImageView mPrimaryFooterIcon;
private final Context mContext;
@@ -114,15 +114,13 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
private final Handler mMainHandler;
private final UserTracker mUserTracker;
private final DialogLaunchAnimator mDialogLaunchAnimator;
+ private final BroadcastDispatcher mBroadcastDispatcher;
private final AtomicBoolean mShouldUseSettingsButton = new AtomicBoolean(false);
private AlertDialog mDialog;
protected H mHandler;
- // Does it move between footer and header? Remove this once all the flagging is removed
- private final boolean mNewQsFooter;
-
private boolean mIsVisible;
@Nullable
private CharSequence mFooterTextContent = null;
@@ -133,15 +131,24 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
@Nullable
private VisibilityChangedDispatcher.OnVisibilityChangedListener mVisibilityChangedListener;
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(
+ DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG)) {
+ showDeviceMonitoringDialog();
+ }
+ }
+ };
+
@Inject
QSSecurityFooter(@Named(QS_SECURITY_FOOTER_VIEW) View rootView,
UserTracker userTracker, @Main Handler mainHandler, ActivityStarter activityStarter,
SecurityController securityController, DialogLaunchAnimator dialogLaunchAnimator,
- @Background Looper bgLooper, FeatureFlags featureFlags) {
- mRootView = rootView;
- mRootView.setOnClickListener(this);
- mFooterText = mRootView.findViewById(R.id.footer_text);
- mPrimaryFooterIcon = mRootView.findViewById(R.id.primary_footer_icon);
+ @Background Looper bgLooper, BroadcastDispatcher broadcastDispatcher) {
+ super(rootView);
+ mFooterText = mView.findViewById(R.id.footer_text);
+ mPrimaryFooterIcon = mView.findViewById(R.id.primary_footer_icon);
mFooterIconId = R.drawable.ic_info_outline;
mContext = rootView.getContext();
mDpm = rootView.getContext().getSystemService(DevicePolicyManager.class);
@@ -151,7 +158,22 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
mHandler = new H(bgLooper);
mUserTracker = userTracker;
mDialogLaunchAnimator = dialogLaunchAnimator;
- mNewQsFooter = featureFlags.isEnabled(Flags.NEW_FOOTER);
+ mBroadcastDispatcher = broadcastDispatcher;
+ }
+
+ @Override
+ protected void onViewAttached() {
+ // Use background handler, as it's the same thread that handleClick is called on.
+ mBroadcastDispatcher.registerReceiverWithHandler(mReceiver,
+ new IntentFilter(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG),
+ mHandler, UserHandle.ALL);
+ mView.setOnClickListener(this);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mBroadcastDispatcher.unregisterReceiver(mReceiver);
+ mView.setOnClickListener(null);
}
public void setListening(boolean listening) {
@@ -173,29 +195,17 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
FontSizeUtils.updateFontSize(mFooterText, R.dimen.qs_tile_text_size);
Resources r = mContext.getResources();
- if (!mNewQsFooter) {
- mFooterText.setMaxLines(r.getInteger(R.integer.qs_security_footer_maxLines));
-
- int bottomMargin = r.getDimensionPixelSize(R.dimen.qs_footers_margin_bottom);
- ViewGroup.MarginLayoutParams lp =
- (ViewGroup.MarginLayoutParams) mRootView.getLayoutParams();
- lp.bottomMargin = bottomMargin;
- lp.width = r.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT
- ? MATCH_PARENT : WRAP_CONTENT;
- mRootView.setLayoutParams(lp);
- }
-
int padding = r.getDimensionPixelSize(R.dimen.qs_footer_padding);
- mRootView.setPaddingRelative(padding, padding, padding, padding);
- mRootView.setBackground(mContext.getDrawable(R.drawable.qs_security_footer_background));
+ mView.setPaddingRelative(padding, 0, padding, 0);
+ mView.setBackground(mContext.getDrawable(R.drawable.qs_security_footer_background));
}
public View getView() {
- return mRootView;
+ return mView;
}
public boolean hasFooter() {
- return mRootView.getVisibility() != View.GONE;
+ return mView.getVisibility() != View.GONE;
}
@Override
@@ -252,11 +262,11 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
// b) a specific work policy set but the work profile is turned off.
if (mIsVisible && isProfileOwnerOfOrganizationOwnedDevice
&& (!hasDisclosableWorkProfilePolicy || !isWorkProfileOn)) {
- mRootView.setClickable(false);
- mRootView.findViewById(R.id.footer_icon).setVisibility(View.GONE);
+ mView.setClickable(false);
+ mView.findViewById(R.id.footer_icon).setVisibility(View.GONE);
} else {
- mRootView.setClickable(true);
- mRootView.findViewById(R.id.footer_icon).setVisibility(View.VISIBLE);
+ mView.setClickable(true);
+ mView.findViewById(R.id.footer_icon).setVisibility(View.VISIBLE);
}
// Update the string
mFooterTextContent = getFooterText(isDeviceManaged, hasWorkProfile,
@@ -493,12 +503,20 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
this);
mDialog.setView(view);
-
- mDialogLaunchAnimator.showFromView(mDialog, mRootView);
+ if (mView.isAggregatedVisible()) {
+ mDialogLaunchAnimator.showFromView(mDialog, mView);
+ } else {
+ mDialog.show();
+ }
});
}
@VisibleForTesting
+ Dialog getDialog() {
+ return mDialog;
+ }
+
+ @VisibleForTesting
View createDialogView() {
if (mSecurityController.isParentalControlsEnabled()) {
return createParentalControlsDialogView();
@@ -805,9 +823,9 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
if (mFooterTextContent != null) {
mFooterText.setText(mFooterTextContent);
}
- mRootView.setVisibility(mIsVisible || DEBUG_FORCE_VISIBLE ? View.VISIBLE : View.GONE);
+ mView.setVisibility(mIsVisible || DEBUG_FORCE_VISIBLE ? View.VISIBLE : View.GONE);
if (mVisibilityChangedListener != null) {
- mVisibilityChangedListener.onVisibilityChanged(mRootView.getVisibility());
+ mVisibilityChangedListener.onVisibilityChanged(mView.getVisibility());
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index f5ae019c20ab..3c95da873273 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.LinearLayout;
import com.android.internal.logging.UiEventLogger;
@@ -167,6 +168,14 @@ public class QuickQSPanel extends QSPanel {
return QSEvent.QQS_TILE_VISIBLE;
}
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ // Remove the collapse action from QSPanel
+ info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
+ }
+
static class QQSSideLabelTileLayout extends SideLabelTileLayout {
private boolean mLastSelected;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index c5ca285aa312..264edb1ec9e4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -70,7 +70,6 @@ public class QuickStatusBarHeader extends FrameLayout {
private View mDateView;
// DateView next to clock. Visible on QQS
private VariableDateView mClockDateView;
- private View mSecurityHeaderView;
private View mStatusIconsView;
private View mContainer;
@@ -137,7 +136,6 @@ public class QuickStatusBarHeader extends FrameLayout {
mPrivacyChip = findViewById(R.id.privacy_chip);
mDateView = findViewById(R.id.date);
mClockDateView = findViewById(R.id.date_clock);
- mSecurityHeaderView = findViewById(R.id.header_text_container);
mClockIconsSeparator = findViewById(R.id.separator);
mRightLayout = findViewById(R.id.rightLayout);
mDateContainer = findViewById(R.id.date_container);
@@ -152,8 +150,6 @@ public class QuickStatusBarHeader extends FrameLayout {
updateResources();
Configuration config = mContext.getResources().getConfiguration();
setDatePrivacyContainersWidth(config.orientation == Configuration.ORIENTATION_LANDSCAPE);
- setSecurityHeaderContainerVisibility(
- config.orientation == Configuration.ORIENTATION_LANDSCAPE);
// QS will always show the estimate, and BatteryMeterView handles the case where
// it's unavailable or charging
@@ -207,8 +203,6 @@ public class QuickStatusBarHeader extends FrameLayout {
super.onConfigurationChanged(newConfig);
updateResources();
setDatePrivacyContainersWidth(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE);
- setSecurityHeaderContainerVisibility(
- newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE);
}
@Override
@@ -229,10 +223,6 @@ public class QuickStatusBarHeader extends FrameLayout {
mPrivacyContainer.setLayoutParams(lp);
}
- private void setSecurityHeaderContainerVisibility(boolean landscape) {
- mSecurityHeaderView.setVisibility(landscape ? VISIBLE : GONE);
- }
-
private void updateBatteryMode() {
if (mConfigShowBatteryEstimate && !mHasCenterCutout) {
mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
@@ -337,7 +327,6 @@ public class QuickStatusBarHeader extends FrameLayout {
return;
}
TouchAnimator.Builder builder = new TouchAnimator.Builder()
- .addFloat(mSecurityHeaderView, "alpha", 0, 1)
// These views appear on expanding down
.addFloat(mDateView, "alpha", 0, 0, 1)
.addFloat(mClockDateView, "alpha", 1, 0, 0)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index da82d2cb7e8d..9ef90ecf50a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -8,6 +8,7 @@ import android.provider.Settings;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.Nullable;
@@ -240,6 +241,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
} else {
record.tileView.setLeftTopRightBottom(left, top, right, bottom);
}
+ record.tileView.setPosition(i);
mLastTileBottom = bottom;
}
}
@@ -296,4 +298,11 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
}
}
}
+
+ @Override
+ public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfoInternal(info);
+ info.setCollectionInfo(
+ new AccessibilityNodeInfo.CollectionInfo(mRecords.size(), 1, false));
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
index 2780b163e5ca..aa505fb0b6bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -22,13 +22,10 @@ import static com.android.systemui.util.Utils.useQsMediaPlayer;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewStub;
import com.android.systemui.R;
import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.dagger.qualifiers.RootView;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.privacy.OngoingPrivacyChip;
import com.android.systemui.qs.FooterActionsView;
@@ -128,15 +125,7 @@ public interface QSFragmentModule {
* This will replace a ViewStub either in {@link QSFooterView} or in {@link QSContainerImpl}.
*/
@Provides
- static FooterActionsView providesQSFooterActionsView(@RootView View view,
- FeatureFlags featureFlags) {
- ViewStub stub;
- if (featureFlags.isEnabled(Flags.NEW_FOOTER)) {
- stub = view.requireViewById(R.id.container_stub);
- } else {
- stub = view.requireViewById(R.id.footer_stub);
- }
- stub.inflate();
+ static FooterActionsView providesQSFooterActionsView(@RootView View view) {
return view.findViewById(R.id.qs_footer_actions);
}
@@ -161,9 +150,10 @@ public interface QSFragmentModule {
@Named(QS_SECURITY_FOOTER_VIEW)
static View providesQSSecurityFooterView(
@QSThemedContext LayoutInflater layoutInflater,
- QSPanel qsPanel
+ FooterActionsView footerActionsView
) {
- return layoutInflater.inflate(R.layout.quick_settings_security_footer, qsPanel, false);
+ return layoutInflater.inflate(R.layout.quick_settings_security_footer, footerActionsView,
+ false);
}
/** */
@@ -200,8 +190,8 @@ public interface QSFragmentModule {
@Named(QS_FGS_MANAGER_FOOTER_VIEW)
static View providesQSFgsManagerFooterView(
@QSThemedContext LayoutInflater layoutInflater,
- QSPanel qsPanel
+ FooterActionsView footerActionsView
) {
- return layoutInflater.inflate(R.layout.fgs_footer, qsPanel, false);
+ return layoutInflater.inflate(R.layout.fgs_footer, footerActionsView, false);
}
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index a712ce2e6394..72dad0608a3a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -69,6 +69,12 @@ open class QSTileViewImpl @JvmOverloads constructor(
internal const val TILE_STATE_RES_PREFIX = "tile_states_"
}
+ private var _position: Int = INVALID
+
+ override fun setPosition(position: Int) {
+ _position = position
+ }
+
override var heightOverride: Int = HeightOverrideable.NO_OVERRIDE
set(value) {
if (field == value) return
@@ -404,6 +410,10 @@ open class QSTileViewImpl @JvmOverloads constructor(
}
}
}
+ if (_position != INVALID) {
+ info.collectionItemInfo =
+ AccessibilityNodeInfo.CollectionItemInfo(_position, 1, 0, 1, false)
+ }
}
override fun toString(): String {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 5d6bbae1f14a..4afd39e36ce3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -202,7 +202,7 @@ public class CastTile extends QSTileImpl<BooleanState> {
mActivityStarter
.postStartActivityDismissingKeyguard(getLongClickIntent(), 0,
controller);
- }, R.style.Theme_SystemUI_Dialog, false /* showProgressBarWhenEmpty */);
+ }, R.style.Theme_SystemUI_Dialog_Cast, false /* showProgressBarWhenEmpty */);
holder.init(dialog);
SystemUIDialog.setShowForAllUsers(dialog, true);
SystemUIDialog.registerDismissListener(dialog);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 53a27ff4e08b..cfb32d3c8a45 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -507,6 +507,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
backAnimation.createExternalInterface().asBinder()));
try {
+ Log.d(TAG_OPS, "OverviewProxyService connected, initializing overview proxy");
mOverviewProxy.onInitialize(params);
} catch (RemoteException e) {
mCurrentBoundedUserId = -1;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
index 4f0455d3de72..f3c87d08e381 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
@@ -49,6 +49,7 @@ public class DraggableConstraintLayout extends ConstraintLayout
private final SwipeDismissHandler mSwipeDismissHandler;
private final GestureDetector mSwipeDetector;
private View mActionsContainer;
+ private View mActionsContainerBackground;
private SwipeDismissCallbacks mCallbacks;
private final DisplayMetrics mDisplayMetrics;
@@ -118,7 +119,8 @@ public class DraggableConstraintLayout extends ConstraintLayout
@Override // View
protected void onFinishInflate() {
- mActionsContainer = findViewById(R.id.actions_container_background);
+ mActionsContainer = findViewById(R.id.actions_container);
+ mActionsContainerBackground = findViewById(R.id.actions_container_background);
}
@Override
@@ -129,10 +131,6 @@ public class DraggableConstraintLayout extends ConstraintLayout
return mSwipeDetector.onTouchEvent(ev);
}
- public int getVisibleRight() {
- return mActionsContainer.getRight();
- }
-
/**
* Cancel current dismissal animation, if any
*/
@@ -331,7 +329,7 @@ public class DraggableConstraintLayout extends ConstraintLayout
if (startX > 0 || (startX == 0 && layoutDir == LAYOUT_DIRECTION_RTL)) {
finalX = mDisplayMetrics.widthPixels;
} else {
- finalX = -1 * mActionsContainer.getRight();
+ finalX = -1 * mActionsContainerBackground.getRight();
}
float distance = Math.abs(finalX - startX);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index 04f33c1f9a91..41e468d382a3 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -237,7 +237,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
String subjectDate = DateFormat.getDateTimeInstance().format(new Date(mImageTime));
String subject = String.format(SCREENSHOT_SHARE_SUBJECT_TEMPLATE, subjectDate);
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
- sharingIntent.setType("image/png");
+ sharingIntent.setDataAndType(uri, "image/png");
sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
// Include URI in ClipData also, so that grantPermission picks it up.
// We don't use setData here because some apps interpret this as "to:".
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
new file mode 100644
index 000000000000..189f38422dcb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
@@ -0,0 +1,61 @@
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.content.res.Configuration
+import android.util.IndentingPrintWriter
+import com.android.systemui.Dumpable
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.LargeScreenUtils
+import java.io.FileDescriptor
+import java.io.PrintWriter
+
+/** An abstract implementation of a class that controls the lockscreen to shade transition. */
+abstract class AbstractLockscreenShadeTransitionController(
+ protected val context: Context,
+ configurationController: ConfigurationController,
+ dumpManager: DumpManager
+) : Dumpable {
+
+ protected var useSplitShade = false
+
+ /**
+ * The amount of pixels that the user has dragged down during the shade transition on
+ * lockscreen.
+ */
+ var dragDownAmount = 0f
+ set(value) {
+ if (value == field) {
+ return
+ }
+ field = value
+ onDragDownAmountChanged(value)
+ }
+
+ init {
+ updateResourcesInternal()
+ configurationController.addCallback(
+ object : ConfigurationController.ConfigurationListener {
+ override fun onConfigChanged(newConfig: Configuration?) {
+ updateResourcesInternal()
+ }
+ })
+ @Suppress("LeakingThis")
+ dumpManager.registerDumpable(this)
+ }
+
+ private fun updateResourcesInternal() {
+ useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ updateResources()
+ }
+
+ protected abstract fun updateResources()
+
+ protected abstract fun onDragDownAmountChanged(dragDownAmount: Float)
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
+ dump(IndentingPrintWriter(pw, /* singleIndent= */ " "))
+ }
+
+ abstract fun dump(pw: IndentingPrintWriter)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index d9a98b165795..5585cde528fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -323,7 +323,7 @@ public class CommandQueue extends IStatusBar.Stub implements
default void onBiometricError(@Modality int modality, int error, int vendorCode) {
}
- default void hideAuthenticationDialog() {
+ default void hideAuthenticationDialog(long requestId) {
}
/**
@@ -999,9 +999,11 @@ public class CommandQueue extends IStatusBar.Stub implements
}
@Override
- public void hideAuthenticationDialog() {
+ public void hideAuthenticationDialog(long requestId) {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_BIOMETRIC_HIDE).sendToTarget();
+ final SomeArgs args = SomeArgs.obtain();
+ args.argl1 = requestId;
+ mHandler.obtainMessage(MSG_BIOMETRIC_HIDE, args).sendToTarget();
}
}
@@ -1508,11 +1510,14 @@ public class CommandQueue extends IStatusBar.Stub implements
someArgs.recycle();
break;
}
- case MSG_BIOMETRIC_HIDE:
+ case MSG_BIOMETRIC_HIDE: {
+ final SomeArgs someArgs = (SomeArgs) msg.obj;
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).hideAuthenticationDialog();
+ mCallbacks.get(i).hideAuthenticationDialog(someArgs.argl1 /* requestId */);
}
+ someArgs.recycle();
break;
+ }
case MSG_SET_BIOMETRICS_LISTENER:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).setBiometicContextListener(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 55ca8f3fd634..b07a898e356b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -887,7 +887,10 @@ public class KeyguardIndicationController {
if (mKeyguardUpdateMonitor.isUdfpsSupported()
&& mKeyguardUpdateMonitor.getUserCanSkipBouncer(
KeyguardUpdateMonitor.getCurrentUser())) {
- showBiometricMessage(mContext.getString(R.string.keyguard_unlock_press));
+ final int stringId = mKeyguardUpdateMonitor.getIsFaceAuthenticated()
+ ? R.string.keyguard_face_successful_unlock_press
+ : R.string.keyguard_unlock_press;
+ showBiometricMessage(mContext.getString(stringId));
} else {
showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
new file mode 100644
index 000000000000..01eb4446ea8e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
@@ -0,0 +1,120 @@
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.util.IndentingPrintWriter
+import android.util.MathUtils
+import com.android.systemui.R
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.media.MediaHierarchyManager
+import com.android.systemui.statusbar.phone.NotificationPanelViewController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+/** Controls the lockscreen to shade transition for the keyguard elements. */
+class LockscreenShadeKeyguardTransitionController
+@AssistedInject
+constructor(
+ private val mediaHierarchyManager: MediaHierarchyManager,
+ @Assisted private val notificationPanelController: NotificationPanelViewController,
+ context: Context,
+ configurationController: ConfigurationController,
+ dumpManager: DumpManager
+) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {
+
+ /**
+ * Distance that the full shade transition takes in order for the keyguard content on
+ * NotificationPanelViewController to fully fade (e.g. Clock & Smartspace).
+ */
+ private var alphaTransitionDistance = 0
+
+ /**
+ * Distance that the full shade transition takes in order for the keyguard elements to fully
+ * translate into their final position
+ */
+ private var keyguardTransitionDistance = 0
+
+ /** The amount of vertical offset for the keyguard during the full shade transition. */
+ private var keyguardTransitionOffset = 0
+
+ /** The amount of alpha that was last set on the keyguard elements. */
+ private var alpha = 0f
+
+ /** The latest progress [0,1] of the alpha transition. */
+ private var alphaProgress = 0f
+
+ /** The amount of alpha that was last set on the keyguard status bar. */
+ private var statusBarAlpha = 0f
+
+ /** The amount of translationY that was last set on the keyguard elements. */
+ private var translationY = 0
+
+ /** The latest progress [0,1] of the translationY progress. */
+ private var translationYProgress = 0f
+
+ override fun updateResources() {
+ alphaTransitionDistance =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
+ keyguardTransitionDistance =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_keyguard_transition_distance)
+ keyguardTransitionOffset =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
+ }
+
+ override fun onDragDownAmountChanged(dragDownAmount: Float) {
+ alphaProgress = MathUtils.saturate(dragDownAmount / alphaTransitionDistance)
+ alpha = 1f - alphaProgress
+ translationY = calculateKeyguardTranslationY(dragDownAmount)
+ notificationPanelController.setKeyguardTransitionProgress(alpha, translationY)
+
+ statusBarAlpha = if (useSplitShade) alpha else -1f
+ notificationPanelController.setKeyguardStatusBarAlpha(statusBarAlpha)
+ }
+
+ private fun calculateKeyguardTranslationY(dragDownAmount: Float): Int {
+ if (!useSplitShade) {
+ return 0
+ }
+ // On split-shade, the translationY of the keyguard should stay in sync with the
+ // translation of media.
+ if (mediaHierarchyManager.isCurrentlyInGuidedTransformation()) {
+ return mediaHierarchyManager.getGuidedTransformationTranslationY()
+ }
+ // When media is not showing, apply the default distance
+ translationYProgress = MathUtils.saturate(dragDownAmount / keyguardTransitionDistance)
+ val translationY = translationYProgress * keyguardTransitionOffset
+ return translationY.toInt()
+ }
+
+ override fun dump(indentingPrintWriter: IndentingPrintWriter) {
+ indentingPrintWriter.let {
+ it.println("LockscreenShadeKeyguardTransitionController:")
+ it.increaseIndent()
+ it.println("Resources:")
+ it.increaseIndent()
+ it.println("alphaTransitionDistance: $alphaTransitionDistance")
+ it.println("keyguardTransitionDistance: $keyguardTransitionDistance")
+ it.println("keyguardTransitionOffset: $keyguardTransitionOffset")
+ it.decreaseIndent()
+ it.println("State:")
+ it.increaseIndent()
+ it.println("dragDownAmount: $dragDownAmount")
+ it.println("alpha: $alpha")
+ it.println("alphaProgress: $alphaProgress")
+ it.println("statusBarAlpha: $statusBarAlpha")
+ it.println("translationProgress: $translationYProgress")
+ it.println("translationY: $translationY")
+ }
+ }
+
+ @AssistedFactory
+ fun interface Factory {
+ fun create(
+ notificationPanelController: NotificationPanelViewController
+ ): LockscreenShadeKeyguardTransitionController
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
new file mode 100644
index 000000000000..00d3701a0cc7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
@@ -0,0 +1,86 @@
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.util.IndentingPrintWriter
+import android.util.MathUtils
+import com.android.systemui.R
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import javax.inject.Inject
+
+/** Controls the lockscreen to shade transition for scrims. */
+class LockscreenShadeScrimTransitionController
+@Inject
+constructor(
+ private val scrimController: ScrimController,
+ context: Context,
+ configurationController: ConfigurationController,
+ dumpManager: DumpManager
+) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {
+
+ /**
+ * Distance that the full shade transition takes in order for scrim to fully transition to the
+ * shade (in alpha)
+ */
+ private var scrimTransitionDistance = 0
+
+ /** Distance it takes in order for the notifications scrim fade in to start. */
+ private var notificationsScrimTransitionDelay = 0
+
+ /** Distance it takes for the notifications scrim to fully fade if after it started. */
+ private var notificationsScrimTransitionDistance = 0
+
+ /** The latest progress [0,1] the scrims transition. */
+ var scrimProgress = 0f
+
+ /** The latest progress [0,1] specifically of the notifications scrim transition. */
+ var notificationsScrimProgress = 0f
+
+ /**
+ * The last drag amount specifically for the notifications scrim. It is different to the normal
+ * [dragDownAmount] as the notifications scrim transition starts relative to the other scrims'
+ * progress.
+ */
+ var notificationsScrimDragAmount = 0f
+
+ override fun updateResources() {
+ scrimTransitionDistance =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_scrim_transition_distance)
+ notificationsScrimTransitionDelay =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_notifications_scrim_transition_delay)
+ notificationsScrimTransitionDistance =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_notifications_scrim_transition_distance)
+ }
+
+ override fun onDragDownAmountChanged(dragDownAmount: Float) {
+ scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
+ notificationsScrimDragAmount = dragDownAmount - notificationsScrimTransitionDelay
+ notificationsScrimProgress =
+ MathUtils.saturate(notificationsScrimDragAmount / notificationsScrimTransitionDistance)
+ scrimController.setTransitionToFullShadeProgress(scrimProgress, notificationsScrimProgress)
+ }
+
+ override fun dump(indentingPrintWriter: IndentingPrintWriter) {
+ indentingPrintWriter.let {
+ it.println("LockscreenShadeScrimTransitionController:")
+ it.increaseIndent()
+ it.println("Resources:")
+ it.increaseIndent()
+ it.println("scrimTransitionDistance: $scrimTransitionDistance")
+ it.println("notificationsScrimTransitionDelay: $notificationsScrimTransitionDelay")
+ it.println(
+ "notificationsScrimTransitionDistance: $notificationsScrimTransitionDistance")
+ it.decreaseIndent()
+ it.println("State")
+ it.increaseIndent()
+ it.println("dragDownAmount: $dragDownAmount")
+ it.println("scrimProgress: $scrimProgress")
+ it.println("notificationsScrimProgress: $notificationsScrimProgress")
+ it.println("notificationsScrimDragAmount: $notificationsScrimDragAmount")
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 63ab3de14d24..b7d82c3e8f89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -38,7 +38,6 @@ import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
import com.android.systemui.statusbar.phone.NotificationPanelViewController
-import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.LargeScreenUtils
import java.io.FileDescriptor
@@ -61,7 +60,9 @@ class LockscreenShadeTransitionController @Inject constructor(
private val falsingCollector: FalsingCollector,
private val ambientState: AmbientState,
private val mediaHierarchyManager: MediaHierarchyManager,
- private val scrimController: ScrimController,
+ private val scrimTransitionController: LockscreenShadeScrimTransitionController,
+ private val keyguardTransitionControllerFactory:
+ LockscreenShadeKeyguardTransitionController.Factory,
private val depthController: NotificationShadeDepthController,
private val context: Context,
private val splitShadeOverScrollerFactory: SplitShadeLockScreenOverScroller.Factory,
@@ -112,22 +113,6 @@ class LockscreenShadeTransitionController @Inject constructor(
private var fullTransitionDistanceByTap = 0
/**
- * Distance that the full shade transition takes in order for scrim to fully transition to the
- * shade (in alpha)
- */
- private var scrimTransitionDistance = 0
-
- /**
- * Distance that it takes in order for the notifications scrim fade in to start.
- */
- private var notificationsScrimTransitionDelay = 0
-
- /**
- * Distance that it takes for the notifications scrim to fully fade if after it started.
- */
- private var notificationsScrimTransitionDistance = 0
-
- /**
* Distance that the full shade transition takes in order for the notification shelf to fully
* expand.
*/
@@ -140,12 +125,6 @@ class LockscreenShadeTransitionController @Inject constructor(
private var qsTransitionDistance = 0
/**
- * Distance that the full shade transition takes in order for the keyguard content on
- * NotificationPanelViewController to fully fade (e.g. Clock & Smartspace).
- */
- private var npvcKeyguardContentAlphaTransitionDistance = 0
-
- /**
* Distance that the full shade transition takes in order for depth of the wallpaper to fully
* change.
*/
@@ -164,17 +143,6 @@ class LockscreenShadeTransitionController @Inject constructor(
private var statusBarTransitionDistance = 0
/**
- * Distance that the full shade transition takes in order for the keyguard elements to fully
- * translate into their final position
- */
- private var keyguardTransitionDistance = 0
-
- /**
- * The amount of vertical offset for the keyguard during the full shade transition.
- */
- private var keyguardTransitionOffset = 0
-
- /**
* Flag to make sure that the dragDownAmount is applied to the listeners even when in the
* locked down shade.
*/
@@ -215,6 +183,10 @@ class LockscreenShadeTransitionController @Inject constructor(
singleShadeOverScrollerFactory.create(nsslController)
}
+ private val keyguardTransitionController by lazy {
+ keyguardTransitionControllerFactory.create(notificationPanelController)
+ }
+
/**
* [LockScreenShadeOverScroller] property that delegates to either
* [SingleShadeLockScreenOverScroller] or [SplitShadeLockScreenOverScroller].
@@ -267,18 +239,10 @@ class LockscreenShadeTransitionController @Inject constructor(
R.dimen.lockscreen_shade_full_transition_distance)
fullTransitionDistanceByTap = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_transition_by_tap_distance)
- scrimTransitionDistance = context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_scrim_transition_distance)
- notificationsScrimTransitionDelay = context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_notifications_scrim_transition_delay)
- notificationsScrimTransitionDistance = context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_notifications_scrim_transition_distance)
notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_notif_shelf_transition_distance)
qsTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_qs_transition_distance)
- npvcKeyguardContentAlphaTransitionDistance = context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
depthControllerTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_depth_controller_transition_distance)
udfpsTransitionDistance = context.resources.getDimensionPixelSize(
@@ -286,10 +250,6 @@ class LockscreenShadeTransitionController @Inject constructor(
statusBarTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_status_bar_transition_distance)
useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
- keyguardTransitionDistance = context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_keyguard_transition_distance)
- keyguardTransitionOffset = context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
}
fun setStackScroller(nsslController: NotificationStackScrollLayoutController) {
@@ -457,9 +417,9 @@ class LockscreenShadeTransitionController @Inject constructor(
false /* animate */, 0 /* delay */)
mediaHierarchyManager.setTransitionToFullShadeAmount(field)
- transitionToShadeAmountScrim(field)
+ scrimTransitionController.dragDownAmount = value
transitionToShadeAmountCommon(field)
- transitionToShadeAmountKeyguard(field)
+ keyguardTransitionController.dragDownAmount = value
shadeOverScroller.expansionDragDownAmount = dragDownAmount
}
}
@@ -471,14 +431,6 @@ class LockscreenShadeTransitionController @Inject constructor(
var qSDragProgress = 0f
private set
- private fun transitionToShadeAmountScrim(dragDownAmount: Float) {
- val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
- val notificationsScrimDragAmount = dragDownAmount - notificationsScrimTransitionDelay
- val notificationsScrimProgress = MathUtils.saturate(
- notificationsScrimDragAmount / notificationsScrimTransitionDistance)
- scrimController.setTransitionToFullShadeProgress(scrimProgress, notificationsScrimProgress)
- }
-
private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
if (depthControllerTransitionDistance == 0) { // split shade
depthController.transitionToFullShadeProgress = 0f
@@ -495,34 +447,6 @@ class LockscreenShadeTransitionController @Inject constructor(
centralSurfaces.setTransitionToFullShadeProgress(statusBarProgress)
}
- private fun transitionToShadeAmountKeyguard(dragDownAmount: Float) {
- // Fade out all content only visible on the lockscreen
- val keyguardAlphaProgress =
- MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance)
- val keyguardAlpha = 1f - keyguardAlphaProgress
- val keyguardTranslationY = calculateKeyguardTranslationY(dragDownAmount)
- notificationPanelController
- .setKeyguardTransitionProgress(keyguardAlpha, keyguardTranslationY)
-
- val statusBarAlpha = if (useSplitShade) keyguardAlpha else -1f
- notificationPanelController.setKeyguardStatusBarAlpha(statusBarAlpha)
- }
-
- private fun calculateKeyguardTranslationY(dragDownAmount: Float): Int {
- if (!useSplitShade) {
- return 0
- }
- // On split-shade, the translationY of the keyguard should stay in sync with the
- // translation of media.
- if (mediaHierarchyManager.isCurrentlyInGuidedTransformation()) {
- return mediaHierarchyManager.getGuidedTransformationTranslationY()
- }
- // When media is not showing, apply the default distance
- val translationProgress = MathUtils.saturate(dragDownAmount / keyguardTransitionDistance)
- val translationY = translationProgress * keyguardTransitionOffset
- return translationY.toInt()
- }
-
private fun setDragDownAmountAnimated(
target: Float,
delay: Long = 0,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 052c57e768fe..7239d0cc361b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -245,13 +245,12 @@ public class NotificationMediaManager implements Dumpable {
@Override
public void onMediaDataLoaded(@NonNull String key,
@Nullable String oldKey, @NonNull MediaData data, boolean immediately,
- int receivedSmartspaceCardLatency) {
+ int receivedSmartspaceCardLatency, boolean isSsReactivated) {
}
@Override
public void onSmartspaceMediaDataLoaded(@NonNull String key,
- @NonNull SmartspaceMediaData data, boolean shouldPrioritize,
- boolean isSsReactivated) {
+ @NonNull SmartspaceMediaData data, boolean shouldPrioritize) {
}
@Override
@@ -320,13 +319,12 @@ public class NotificationMediaManager implements Dumpable {
@Override
public void onMediaDataLoaded(@NonNull String key,
@Nullable String oldKey, @NonNull MediaData data, boolean immediately,
- int receivedSmartspaceCardLatency) {
+ int receivedSmartspaceCardLatency, boolean isSsReactivated) {
}
@Override
public void onSmartspaceMediaDataLoaded(@NonNull String key,
- @NonNull SmartspaceMediaData data, boolean shouldPrioritize,
- boolean isSsReactivated) {
+ @NonNull SmartspaceMediaData data, boolean shouldPrioritize) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 93103e2c3f49..e026c1973197 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -205,7 +205,7 @@ public class StatusBarStateControllerImpl implements
}
mLastState = mState;
mState = state;
- mUpcomingState = state;
+ updateUpcomingState(mState);
mUiEventLogger.log(StatusBarStateEvent.fromState(mState));
Trace.instantForTrack(Trace.TRACE_TAG_APP, "UI Events", "StatusBarState " + tag);
for (RankedListener rl : new ArrayList<>(mListeners)) {
@@ -223,8 +223,18 @@ public class StatusBarStateControllerImpl implements
@Override
public void setUpcomingState(int nextState) {
- mUpcomingState = nextState;
- recordHistoricalState(mUpcomingState /* newState */, mState /* lastState */, true);
+ recordHistoricalState(nextState /* newState */, mState /* lastState */, true);
+ updateUpcomingState(nextState);
+
+ }
+
+ private void updateUpcomingState(int upcomingState) {
+ if (mUpcomingState != upcomingState) {
+ mUpcomingState = upcomingState;
+ for (RankedListener rl : new ArrayList<>(mListeners)) {
+ rl.mListener.onUpcomingStateChanged(mUpcomingState);
+ }
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityState.kt
index 9c3c10c9219b..b66e17588c10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityState.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityState.kt
@@ -46,6 +46,34 @@ open class ConnectivityState {
}
}
+ protected open fun tableColumns(): List<String> {
+ return listOf(
+ "connected",
+ "enabled",
+ "activityIn",
+ "activityOut",
+ "level",
+ "iconGroup",
+ "inetCondition",
+ "rssi",
+ "time")
+ }
+
+ protected open fun tableData(): List<String> {
+ return listOf(
+ connected,
+ enabled,
+ activityIn,
+ activityOut,
+ level,
+ iconGroup,
+ inetCondition,
+ rssi,
+ sSDF.format(time)).map {
+ it.toString()
+ }
+ }
+
protected open fun copyFrom(other: ConnectivityState) {
connected = other.connected
enabled = other.enabled
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
index 41d2b655d805..9d8667a3ccb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
@@ -828,6 +828,8 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
+ (mMobileStatusHistoryIndex + STATUS_HISTORY_SIZE - i) + "): "
+ mMobileStatusHistory[i & (STATUS_HISTORY_SIZE - 1)]);
}
+
+ dumpTableData(pw);
}
/** Box for QS icon info */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt
index 8a3b00662900..f20d20631c95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt
@@ -162,6 +162,52 @@ internal class MobileState(
builder.append("displayInfo=$telephonyDisplayInfo")
}
+ override fun tableColumns(): List<String> {
+ val columns = listOf("dataSim",
+ "networkName",
+ "networkNameData",
+ "dataConnected",
+ "roaming",
+ "isDefault",
+ "isEmergency",
+ "airplaneMode",
+ "carrierNetworkChangeMode",
+ "userSetup",
+ "dataState",
+ "defaultDataOff",
+ "showQuickSettingsRatIcon",
+ "voiceServiceState",
+ "isInService",
+ "serviceState",
+ "signalStrength",
+ "displayInfo")
+
+ return super.tableColumns() + columns
+ }
+
+ override fun tableData(): List<String> {
+ val columns = listOf(dataSim,
+ networkName,
+ networkNameData,
+ dataConnected,
+ roaming,
+ isDefault,
+ isEmergency,
+ airplaneMode,
+ carrierNetworkChangeMode,
+ userSetup,
+ dataState,
+ defaultDataOff,
+ showQuickSettingsRatIcon(),
+ getVoiceServiceState(),
+ isInService(),
+ serviceState?.minLog() ?: "(null)",
+ signalStrength?.minLog() ?: "(null)",
+ telephonyDisplayInfo).map { it.toString() }
+
+ return super.tableData() + columns
+ }
+
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalController.java
index cd2006899cfc..e2806a39130f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalController.java
@@ -22,9 +22,12 @@ import android.content.Context;
import android.util.Log;
import com.android.settingslib.SignalIcon.IconGroup;
+import com.android.systemui.dump.DumpsysTableLogger;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.BitSet;
+import java.util.List;
/**
@@ -193,20 +196,68 @@ public abstract class SignalController<T extends ConnectivityState, I extends Ic
pw.println(" - " + mTag + " -----");
pw.println(" Current State: " + mCurrentState);
if (RECORD_HISTORY) {
- // Count up the states that actually contain time stamps, and only display those.
- int size = 0;
- for (int i = 0; i < HISTORY_SIZE; i++) {
- if (mHistory[i].time != 0) size++;
- }
- // Print out the previous states in ordered number.
- for (int i = mHistoryIndex + HISTORY_SIZE - 1;
- i >= mHistoryIndex + HISTORY_SIZE - size; i--) {
- pw.println(" Previous State(" + (mHistoryIndex + HISTORY_SIZE - i) + "): "
- + mHistory[i & (HISTORY_SIZE - 1)]);
+ List<ConnectivityState> history = getOrderedHistoryExcludingCurrentState();
+ for (int i = 0; i < history.size(); i++) {
+ pw.println(" Previous State(" + (i + 1) + "): " + mHistory[i]);
}
}
}
+ /**
+ * mHistory is a ring, so use this method to get the time-ordered (from youngest to oldest)
+ * list of historical states. Filters out any state whose `time` is `0`.
+ *
+ * For ease of compatibility, this list returns JUST the historical states, not the current
+ * state which has yet to be copied into the history
+ *
+ * @see #getOrderedHistory()
+ * @return historical states, ordered from newest to oldest
+ */
+ List<ConnectivityState> getOrderedHistoryExcludingCurrentState() {
+ ArrayList<ConnectivityState> history = new ArrayList<>();
+
+ // Count up the states that actually contain time stamps, and only display those.
+ int size = 0;
+ for (int i = 0; i < HISTORY_SIZE; i++) {
+ if (mHistory[i].time != 0) size++;
+ }
+ // Print out the previous states in ordered number.
+ for (int i = mHistoryIndex + HISTORY_SIZE - 1;
+ i >= mHistoryIndex + HISTORY_SIZE - size; i--) {
+ history.add(mHistory[i & (HISTORY_SIZE - 1)]);
+ }
+
+ return history;
+ }
+
+ /**
+ * Get the ordered history states, including the current yet-to-be-copied state. Useful for
+ * logging
+ *
+ * @see #getOrderedHistoryExcludingCurrentState()
+ * @return [currentState, historicalState...] array
+ */
+ List<ConnectivityState> getOrderedHistory() {
+ ArrayList<ConnectivityState> history = new ArrayList<>();
+ // Start with the current state
+ history.add(mCurrentState);
+ history.addAll(getOrderedHistoryExcludingCurrentState());
+ return history;
+ }
+
+ void dumpTableData(PrintWriter pw) {
+ List<List<String>> tableData = new ArrayList<List<String>>();
+ List<ConnectivityState> history = getOrderedHistory();
+ for (int i = 0; i < history.size(); i++) {
+ tableData.add(history.get(i).tableData());
+ }
+
+ DumpsysTableLogger logger =
+ new DumpsysTableLogger(mTag, mCurrentState.tableColumns(), tableData);
+
+ logger.printTableData(pw);
+ }
+
final void notifyListeners() {
notifyListeners(mCallbackHandler);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
index b80df4ab394a..a4589c8dd6d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
@@ -241,6 +241,7 @@ public class WifiSignalController extends SignalController<WifiState, IconGroup>
public void dump(PrintWriter pw) {
super.dump(pw);
mWifiTracker.dump(pw);
+ dumpTableData(pw);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt
index ac15f78191f6..d32e34915c61 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt
@@ -48,6 +48,30 @@ internal class WifiState(
.append(",subId=").append(subId)
}
+ override fun tableColumns(): List<String> {
+ val columns = listOf("ssid",
+ "isTransient",
+ "isDefault",
+ "statusLabel",
+ "isCarrierMerged",
+ "subId")
+
+ return super.tableColumns() + columns
+ }
+
+ override fun tableData(): List<String> {
+ val data = listOf(ssid,
+ isTransient,
+ isDefault,
+ statusLabel,
+ isCarrierMerged,
+ subId).map {
+ it.toString()
+ }
+
+ return super.tableData() + data
+ }
+
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index b74140da99d2..7800b4cf4aa6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -32,6 +32,7 @@ import android.widget.FrameLayout
import com.android.systemui.R
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.systemui.util.animation.AnimationUtil.Companion.frames
import javax.inject.Inject
import kotlin.math.roundToInt
@@ -109,14 +110,14 @@ class SystemEventChipAnimationController @Inject constructor(
initializeAnimRect()
val alphaIn = ValueAnimator.ofFloat(0f, 1f).apply {
- startDelay = 117
- duration = 83
+ startDelay = 7.frames
+ duration = 5.frames
interpolator = null
addUpdateListener { currentAnimatedView?.view?.alpha = animatedValue as Float }
}
val moveIn = ValueAnimator.ofInt(chipMinWidth, chipWidth).apply {
- startDelay = 117
- duration = 383
+ startDelay = 7.frames
+ duration = 23.frames
interpolator = STATUS_BAR_X_MOVE_IN
addUpdateListener {
updateAnimatedViewBoundsWidth(animatedValue as Int)
@@ -146,7 +147,7 @@ class SystemEventChipAnimationController @Inject constructor(
private fun createMoveOutAnimationForDot(): Animator {
val width1 = ValueAnimator.ofInt(chipWidth, chipMinWidth).apply {
- duration = 150
+ duration = 9.frames
interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_1
addUpdateListener {
updateAnimatedViewBoundsWidth(it.animatedValue as Int)
@@ -154,8 +155,8 @@ class SystemEventChipAnimationController @Inject constructor(
}
val width2 = ValueAnimator.ofInt(chipMinWidth, dotSize).apply {
- startDelay = 150
- duration = 333
+ startDelay = 9.frames
+ duration = 20.frames
interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2
addUpdateListener {
updateAnimatedViewBoundsWidth(it.animatedValue as Int)
@@ -167,8 +168,8 @@ class SystemEventChipAnimationController @Inject constructor(
val chipVerticalCenter = v.top + v.measuredHeight / 2
val height1 = ValueAnimator.ofInt(
currentAnimatedView!!.view.measuredHeight, keyFrame1Height).apply {
- startDelay = 133
- duration = 100
+ startDelay = 8.frames
+ duration = 6.frames
interpolator = STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_1
addUpdateListener {
updateAnimatedViewBoundsHeight(it.animatedValue as Int, chipVerticalCenter)
@@ -176,8 +177,8 @@ class SystemEventChipAnimationController @Inject constructor(
}
val height2 = ValueAnimator.ofInt(keyFrame1Height, dotSize).apply {
- startDelay = 233
- duration = 250
+ startDelay = 14.frames
+ duration = 15.frames
interpolator = STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2
addUpdateListener {
updateAnimatedViewBoundsHeight(it.animatedValue as Int, chipVerticalCenter)
@@ -187,8 +188,8 @@ class SystemEventChipAnimationController @Inject constructor(
// Move the chip view to overlap exactly with the privacy dot. The chip displays by default
// exactly adjacent to the dot, so we can just move over by the diameter of the dot itself
val moveOut = ValueAnimator.ofInt(0, dotSize).apply {
- startDelay = 50
- duration = 183
+ startDelay = 3.frames
+ duration = 11.frames
interpolator = STATUS_CHIP_MOVE_TO_DOT
addUpdateListener {
// If RTL, we can just invert the move
@@ -208,7 +209,7 @@ class SystemEventChipAnimationController @Inject constructor(
private fun createMoveOutAnimationDefault(): Animator {
val moveOut = ValueAnimator.ofInt(chipWidth, chipMinWidth).apply {
- duration = 383
+ duration = 23.frames
addUpdateListener {
currentAnimatedView?.apply {
updateAnimatedViewBoundsWidth(it.animatedValue as Int)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 3b22f2a86bfc..2f1022a904e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -83,7 +83,6 @@ public class AmbientState {
private Runnable mOnPulseHeightChangedListener;
private ExpandableNotificationRow mTrackedHeadsUpRow;
private float mAppearFraction;
- private boolean mIsShadeOpening;
private float mOverExpansion;
private int mStackTopMargin;
@@ -219,14 +218,6 @@ public class AmbientState {
mBaseZHeight = getBaseHeight(mZDistanceBetweenElements);
}
- public void setIsShadeOpening(boolean isOpening) {
- mIsShadeOpening = isOpening;
- }
-
- public boolean isShadeOpening() {
- return mIsShadeOpening;
- }
-
void setOverExpansion(float overExpansion) {
mOverExpansion = overExpansion;
}
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 c0553b5c3c2d..8271a8894014 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
@@ -427,6 +427,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private boolean mInHeadsUpPinnedMode;
private boolean mHeadsUpAnimatingAway;
private int mStatusBarState;
+ private int mUpcomingStatusBarState;
private int mCachedBackgroundColor;
private boolean mHeadsUpGoingAwayAnimationsAllowed = true;
private Runnable mReflingAndAnimateScroll = () -> {
@@ -690,7 +691,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mController.hasActiveClearableNotifications(ROWS_ALL);
boolean showFooterView = (showDismissView || mController.getVisibleNotificationCount() > 0)
&& mIsCurrentUserSetup // see: b/193149550
- && mStatusBarState != StatusBarState.KEYGUARD
+ && !onKeyguard()
+ && mUpcomingStatusBarState != StatusBarState.KEYGUARD
// quick settings don't affect notifications when not in full screen
&& (mQsExpansionFraction != 1 || !mQsFullScreen)
&& !mScreenOffAnimationController.shouldHideNotificationsFooter()
@@ -1317,14 +1319,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
if (mOnStackYChanged != null) {
mOnStackYChanged.accept(listenerNeedsAnimation);
}
- if ((mQsExpansionFraction <= 0 || !mQsFullScreen) && !shouldSkipHeightUpdate()) {
- final float endHeight = updateStackEndHeight();
+ if (mQsExpansionFraction <= 0 && !shouldSkipHeightUpdate()) {
+ final float endHeight = updateStackEndHeight(
+ getHeight(), getEmptyBottomMargin(), mTopPadding);
updateStackHeight(endHeight, fraction);
}
}
- private float updateStackEndHeight() {
- final float stackEndHeight = Math.max(0f, mIntrinsicContentHeight);
+ private float updateStackEndHeight(float height, float bottomMargin, float topPadding) {
+ final float stackEndHeight = Math.max(0f, height - bottomMargin - topPadding);
mAmbientState.setStackEndHeight(stackEndHeight);
return stackEndHeight;
}
@@ -4959,6 +4962,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
updateDismissBehavior();
}
+ void setUpcomingStatusBarState(int upcomingStatusBarState) {
+ mUpcomingStatusBarState = upcomingStatusBarState;
+ if (mUpcomingStatusBarState != mStatusBarState) {
+ updateFooter();
+ }
+ }
+
void onStatePostChange(boolean fromShadeLocked) {
boolean onKeyguard = onKeyguard();
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 3e630cdf8f97..6d7c95f96de6 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
@@ -310,6 +310,11 @@ public class NotificationStackScrollLayoutController {
}
@Override
+ public void onUpcomingStateChanged(int newState) {
+ mView.setUpcomingStatusBarState(newState);
+ }
+
+ @Override
public void onStatePostChange() {
mView.updateSensitiveness(mStatusBarStateController.goingToFullShade(),
mLockscreenUserManager.isAnyProfilePublicMode());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index aab5ff8d92e6..f95093ef8ba4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -166,7 +166,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
private final NotificationShadeWindowController mNotificationShadeWindowController;
private final SessionTracker mSessionTracker;
private final int mConsecutiveFpFailureThreshold;
- private final int mWakeUpDelay;
private int mMode;
private BiometricSourceType mBiometricType;
private KeyguardViewController mKeyguardViewController;
@@ -266,6 +265,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
}
private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+ private final ScreenOffAnimationController mScreenOffAnimationController;
@Inject
public BiometricUnlockController(DozeScrimController dozeScrimController,
@@ -285,7 +285,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
StatusBarStateController statusBarStateController,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
SessionTracker sessionTracker,
- LatencyTracker latencyTracker) {
+ LatencyTracker latencyTracker,
+ ScreenOffAnimationController screenOffAnimationController) {
mPowerManager = powerManager;
mShadeController = shadeController;
mUpdateMonitor = keyguardUpdateMonitor;
@@ -302,7 +303,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
mScrimController = scrimController;
mKeyguardStateController = keyguardStateController;
mHandler = handler;
- mWakeUpDelay = resources.getInteger(com.android.internal.R.integer.config_wakeUpDelayDoze);
mConsecutiveFpFailureThreshold = resources.getInteger(
R.integer.fp_consecutive_failure_time_ms);
mKeyguardBypassController = keyguardBypassController;
@@ -312,6 +312,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
mStatusBarStateController = statusBarStateController;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mSessionTracker = sessionTracker;
+ mScreenOffAnimationController = screenOffAnimationController;
dumpManager.registerDumpable(getClass().getName(), this);
}
@@ -433,7 +434,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
// During wake and unlock, we need to draw black before waking up to avoid abrupt
// brightness changes due to display state transitions.
boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
- boolean delayWakeUp = mode == MODE_WAKE_AND_UNLOCK && alwaysOnEnabled && mWakeUpDelay > 0;
Runnable wakeUp = ()-> {
if (!wasDeviceInteractive) {
if (DEBUG_BIO_WAKELOCK) {
@@ -442,15 +442,12 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
"android.policy:BIOMETRIC");
}
- if (delayWakeUp) {
- mKeyguardViewMediator.onWakeAndUnlocking();
- }
Trace.beginSection("release wake-and-unlock");
releaseBiometricWakeLock();
Trace.endSection();
};
- if (!delayWakeUp && mMode != MODE_NONE) {
+ if (mMode != MODE_NONE) {
wakeUp.run();
}
switch (mMode) {
@@ -504,11 +501,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
mUpdateMonitor.awakenFromDream();
}
mNotificationShadeWindowController.setNotificationShadeFocusable(false);
- if (delayWakeUp) {
- mHandler.postDelayed(wakeUp, mWakeUpDelay);
- } else {
- mKeyguardViewMediator.onWakeAndUnlocking();
- }
+ mKeyguardViewMediator.onWakeAndUnlocking();
Trace.endSection();
break;
case MODE_ONLY_WAKE:
@@ -564,7 +557,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
boolean deviceDreaming = mUpdateMonitor.isDreaming();
if (!mUpdateMonitor.isDeviceInteractive()) {
- if (!mKeyguardViewController.isShowing()) {
+ if (!mKeyguardViewController.isShowing()
+ && !mScreenOffAnimationController.isKeyguardShowDelayed()) {
return MODE_ONLY_WAKE;
} else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
return MODE_WAKE_AND_UNLOCK_PULSING;
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 ffe4d4f11819..1625d9b7f486 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -1388,8 +1388,11 @@ public class CentralSurfaces extends CoreStartable implements
* keyguard.
*/
private void dispatchPanelExpansionForKeyguardDismiss(float fraction, boolean trackingTouch) {
- // Things that mean we're not dismissing the keyguard, and should ignore this expansion:
+ // Things that mean we're not swiping to dismiss the keyguard, and should ignore this
+ // expansion:
// - Keyguard isn't even visible.
+ // - Keyguard is occluded. Expansion changes here are the shade being expanded over the
+ // occluding activity.
// - Keyguard is visible, but can't be dismissed (swiping up will show PIN/password prompt).
// - The SIM is locked, you can't swipe to unlock. If the SIM is locked but there is no
// device lock set, canDismissLockScreen returns true even though you should not be able
@@ -1397,6 +1400,7 @@ public class CentralSurfaces extends CoreStartable implements
// - QS is expanded and we're swiping - swiping up now will hide QS, not dismiss the
// keyguard.
if (!isKeyguardShowing()
+ || isOccluded()
|| !mKeyguardStateController.canDismissLockScreen()
|| mKeyguardViewMediator.isAnySimPinSecure()
|| (mNotificationPanelViewController.isQsExpanded() && trackingTouch)) {
@@ -1438,7 +1442,6 @@ public class CentralSurfaces extends CoreStartable implements
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}
@@ -2628,8 +2631,6 @@ public class CentralSurfaces extends CoreStartable implements
}
finishBarAnimations();
resetUserExpandedStates();
- } else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
- mQSPanelController.showDeviceMonitoringDialog();
}
Trace.endSection();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index ebe91c7dc5d0..8b25c2bc20b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -292,20 +292,11 @@ public class DozeParameters implements
}
public void updateControlScreenOff() {
- final boolean controlScreenOff = shouldControlUnlockedScreenOff()
- || (!getDisplayNeedsBlanking() && getAlwaysOn() && mKeyguardShowing);
- setControlScreenOffAnimation(controlScreenOff);
- }
-
- /**
- * Whether we're capable of controlling the screen off animation if we want to. This isn't
- * possible if AOD isn't even enabled or if the flag is disabled, or if the display needs
- * blanking.
- */
- public boolean canControlUnlockedScreenOff() {
- return getAlwaysOn()
- && mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
- && !getDisplayNeedsBlanking();
+ if (!getDisplayNeedsBlanking()) {
+ final boolean controlScreenOff =
+ getAlwaysOn() && (mKeyguardShowing || shouldControlUnlockedScreenOff());
+ setControlScreenOffAnimation(controlScreenOff);
+ }
}
/**
@@ -318,7 +309,8 @@ public class DozeParameters implements
* disabled for a11y.
*/
public boolean shouldControlUnlockedScreenOff() {
- return mUnlockedScreenOffAnimationController.shouldPlayUnlockedScreenOffAnimation();
+ return canControlUnlockedScreenOff()
+ && mUnlockedScreenOffAnimationController.shouldPlayUnlockedScreenOffAnimation();
}
public boolean shouldDelayKeyguardShow() {
@@ -350,6 +342,16 @@ public class DozeParameters implements
return getAlwaysOn() && mKeyguardShowing;
}
+ /**
+ * Whether we're capable of controlling the screen off animation if we want to. This isn't
+ * possible if AOD isn't even enabled or if the flag is disabled.
+ */
+ public boolean canControlUnlockedScreenOff() {
+ return getAlwaysOn()
+ && mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
+ && !getDisplayNeedsBlanking();
+ }
+
private boolean getBoolean(String propName, int resId) {
return SystemProperties.getBoolean(propName, mResources.getBoolean(resId));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
index 64b0b4e2909f..280e75cc7381 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -77,7 +77,7 @@ class KeyguardLiftController @Inject constructor(
}
private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
- override fun onKeyguardBouncerChanged(bouncer: Boolean) {
+ override fun onKeyguardBouncerFullyShowingChanged(bouncer: Boolean) {
bouncerVisible = bouncer
updateListeningState()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 11628cb75e87..600732373cae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -239,7 +239,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final DozeParameters mDozeParameters;
private final OnHeightChangedListener mOnHeightChangedListener = new OnHeightChangedListener();
- private final OnClickListener mOnClickListener = new OnClickListener();
+ private final Runnable mCollapseExpandAction = new CollapseExpandAction();
private final OnOverscrollTopChangedListener
mOnOverscrollTopChangedListener =
new OnOverscrollTopChangedListener();
@@ -1355,9 +1355,11 @@ public class NotificationPanelViewController extends PanelViewController {
int userSwitcherPreferredY = mStatusBarHeaderHeightKeyguard;
boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
final boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
- .getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
+ .getVisibleNotificationCount() != 0
+ || mMediaDataManager.hasActiveMediaOrRecommendation();
boolean splitShadeWithActiveMedia =
- mShouldUseSplitNotificationShade && mMediaDataManager.hasActiveMedia();
+ mShouldUseSplitNotificationShade
+ && mMediaDataManager.hasActiveMediaOrRecommendation();
boolean shouldAnimateClockChange = mScreenOffAnimationController.shouldAnimateClockChange();
if ((hasVisibleNotifications && !mShouldUseSplitNotificationShade)
|| (splitShadeWithActiveMedia && !mDozing)) {
@@ -1424,7 +1426,8 @@ public class NotificationPanelViewController extends PanelViewController {
private void updateKeyguardStatusViewAlignment(boolean animate) {
boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
- .getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
+ .getVisibleNotificationCount() != 0
+ || mMediaDataManager.hasActiveMediaOrRecommendation();
boolean shouldBeCentered = !mShouldUseSplitNotificationShade || !hasVisibleNotifications
|| mDozing;
if (mStatusViewCentered != shouldBeCentered) {
@@ -2622,7 +2625,7 @@ public class NotificationPanelViewController extends PanelViewController {
float endPosition = 0;
if (pxAmount > 0.0f) {
if (mNotificationStackScrollLayoutController.getVisibleNotificationCount() == 0
- && !mMediaDataManager.hasActiveMedia()) {
+ && !mMediaDataManager.hasActiveMediaOrRecommendation()) {
// No notifications are visible, let's animate to the height of qs instead
if (mQs != null) {
// Let's interpolate to the header height instead of the top padding,
@@ -3570,7 +3573,7 @@ public class NotificationPanelViewController extends PanelViewController {
public void onFragmentViewCreated(String tag, Fragment fragment) {
mQs = (QS) fragment;
mQs.setPanelView(mHeightListener);
- mQs.setExpandClickListener(mOnClickListener);
+ mQs.setCollapseExpandAction(mCollapseExpandAction);
mQs.setHeaderClickable(isQsExpansionEnabled());
mQs.setOverscrolling(mStackScrollerOverscrolling);
mQs.setInSplitShade(mShouldUseSplitNotificationShade);
@@ -4213,9 +4216,9 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
- private class OnClickListener implements View.OnClickListener {
+ private class CollapseExpandAction implements Runnable {
@Override
- public void onClick(View v) {
+ public void run() {
onQsExpansionStarted();
if (mQsExpanded) {
flingSettings(0 /* vel */, FLING_COLLAPSE, null /* onFinishRunnable */,
@@ -4900,7 +4903,6 @@ public class NotificationPanelViewController extends PanelViewController {
private int mCurrentPanelState = STATE_CLOSED;
private void onPanelStateChanged(@PanelState int state) {
- mAmbientState.setIsShadeOpening(state == STATE_OPENING);
updateQSExpansionEnabledAmbient();
if (state == STATE_OPEN && mCurrentPanelState != state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index ffbf28238883..67b4dbbe3307 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -30,6 +30,7 @@ import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Region;
import android.os.Binder;
+import android.os.Build;
import android.os.RemoteException;
import android.os.Trace;
import android.util.Log;
@@ -327,6 +328,16 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
Trace.setCounter("display_max_refresh_rate",
(long) mLpChanged.preferredMaxDisplayRefreshRate);
}
+
+ if (state.mBouncerShowing && !isDebuggable()) {
+ mLpChanged.flags |= LayoutParams.FLAG_SECURE;
+ } else {
+ mLpChanged.flags &= ~LayoutParams.FLAG_SECURE;
+ }
+ }
+
+ protected boolean isDebuggable() {
+ return Build.IS_DEBUGGABLE;
}
private void adjustScreenOrientation(State state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
index 745228e72596..491e9fde5c9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
@@ -168,14 +168,7 @@ class NotificationsQSContainerController @Inject constructor(
private fun updateBottomSpacing() {
val (containerPadding, notificationsMargin) = calculateBottomSpacing()
var qsScrollPaddingBottom = 0
- val newFooter = featureFlags.isEnabled(Flags.NEW_FOOTER)
- if (!newFooter && !(splitShadeEnabled || isQSCustomizing || isQSDetailShowing ||
- isGestureNavigation || taskbarVisible)) {
- // no taskbar, portrait, navigation buttons enabled:
- // padding is needed so QS can scroll up over bottom insets - to reach the point when
- // the whole QS is above bottom insets
- qsScrollPaddingBottom = bottomStableInsets
- } else if (newFooter && !(isQSCustomizing || isQSDetailShowing)) {
+ if (!(isQSCustomizing || isQSDetailShowing)) {
// With the new footer, we also want this padding in the bottom in these cases
qsScrollPaddingBottom = if (splitShadeEnabled) {
notificationsMargin - scrimShadeBottomMargin
@@ -185,11 +178,7 @@ class NotificationsQSContainerController @Inject constructor(
}
mView.setPadding(0, 0, 0, containerPadding)
mView.setNotificationsMarginBottom(notificationsMargin)
- if (newFooter) {
- mView.setQSContainerPaddingBottom(qsScrollPaddingBottom)
- } else {
- mView.setQSScrollPaddingBottom(qsScrollPaddingBottom)
- }
+ mView.setQSContainerPaddingBottom(qsScrollPaddingBottom)
}
private fun calculateBottomSpacing(): Pair<Int, Int> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index 7caea06e6359..2446cf7ba412 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -103,16 +103,6 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
mStackScroller.setLayoutParams(params);
}
- public void setQSScrollPaddingBottom(int paddingBottom) {
- if (mQSScrollView != null) {
- mQSScrollView.setPaddingRelative(
- mQSScrollView.getPaddingLeft(),
- mQSScrollView.getPaddingTop(),
- mQSScrollView.getPaddingRight(),
- paddingBottom);
- }
- }
-
public void setQSContainerPaddingBottom(int paddingBottom) {
if (mQSContainer != null) {
mQSContainer.setPadding(
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 0b95458b73df..28f2e61bd8c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -1021,15 +1021,24 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
boolean aodWallpaperTimeout = (mState == ScrimState.AOD || mState == ScrimState.PULSING)
&& mWallpaperVisibilityTimedOut;
// We also want to hide FLAG_SHOW_WHEN_LOCKED activities under the scrim.
- boolean occludedKeyguard = (mState == ScrimState.PULSING || mState == ScrimState.AOD)
+ boolean hideFlagShowWhenLockedActivities =
+ (mState == ScrimState.PULSING || mState == ScrimState.AOD)
&& mKeyguardOccluded;
- if (aodWallpaperTimeout || occludedKeyguard) {
+ if (aodWallpaperTimeout || hideFlagShowWhenLockedActivities) {
mBehindAlpha = 1;
}
// Prevent notification scrim flicker when transitioning away from keyguard.
if (mKeyguardStateController.isKeyguardGoingAway()) {
mNotificationsAlpha = 0;
}
+
+ // Prevent flickering for activities above keyguard and quick settings in keyguard.
+ if (mKeyguardOccluded
+ && (mState == ScrimState.KEYGUARD || mState == ScrimState.SHADE_LOCKED)) {
+ mBehindAlpha = 0;
+ mNotificationsAlpha = 0;
+ }
+
setScrimAlpha(mScrimInFront, mInFrontAlpha);
setScrimAlpha(mScrimBehind, mBehindAlpha);
setScrimAlpha(mNotificationsScrim, mNotificationsAlpha);
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 a1cbba47e822..ce1289e0885c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -355,6 +355,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public void onPanelExpansionChanged(float fraction, boolean expanded, boolean tracking) {
+ // Avoid having the shade and the bouncer open at the same time over a dream.
+ final boolean hideBouncerOverDream =
+ mDreamOverlayStateController.isOverlayActive()
+ && (mNotificationPanelViewController.isExpanded()
+ || mNotificationPanelViewController.isExpanding());
+
// We don't want to translate the bounce when:
// • Keyguard is occluded, because we're in a FLAG_SHOW_WHEN_LOCKED activity and need to
// conserve the original animation.
@@ -371,7 +377,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
return;
} else if (bouncerNeedsScrimming()) {
mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
- } else if (mShowing) {
+ } else if (mShowing && !hideBouncerOverDream) {
if (!isWakeAndUnlocking()
&& !mCentralSurfaces.isInLaunchTransition()
&& !isUnlockCollapsing()) {
@@ -1055,8 +1061,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
mKeyguardUpdateManager.onKeyguardVisibilityChanged(showing && !occluded);
}
- if (bouncerIsOrWillBeShowing != mLastBouncerIsOrWillBeShowing || mFirstUpdate) {
- mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerIsOrWillBeShowing);
+ if (bouncerIsOrWillBeShowing != mLastBouncerIsOrWillBeShowing || mFirstUpdate
+ || bouncerShowing != mLastBouncerShowing) {
+ mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerIsOrWillBeShowing,
+ bouncerShowing);
}
mFirstUpdate = false;
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 ea935be334c1..c11d450e47b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -59,14 +59,8 @@ class UnlockedScreenOffAnimationController @Inject constructor(
private val powerManager: PowerManager,
private val handler: Handler = Handler()
) : WakefulnessLifecycle.Observer, ScreenOffAnimation {
- private lateinit var mCentralSurfaces: CentralSurfaces
- /**
- * Whether or not [initialize] has been called to provide us with the StatusBar,
- * NotificationPanelViewController, and LightRevealSrim so that we can run the unlocked screen
- * off animation.
- */
- private var initialized = false
+ private lateinit var mCentralSurfaces: CentralSurfaces
private lateinit var lightRevealScrim: LightRevealScrim
private var animatorDurationScale = 1f
@@ -122,7 +116,6 @@ class UnlockedScreenOffAnimationController @Inject constructor(
centralSurfaces: CentralSurfaces,
lightRevealScrim: LightRevealScrim
) {
- this.initialized = true
this.lightRevealScrim = lightRevealScrim
this.mCentralSurfaces = centralSurfaces
@@ -269,18 +262,6 @@ class UnlockedScreenOffAnimationController @Inject constructor(
* on the current state of the device.
*/
fun shouldPlayUnlockedScreenOffAnimation(): Boolean {
- // If we haven't been initialized yet, we don't have a StatusBar/LightRevealScrim yet, so we
- // can't perform the animation.
- if (!initialized) {
- return false
- }
-
- // If the device isn't in a state where we can control unlocked screen off (no AOD enabled,
- // power save, etc.) then we shouldn't try to do so.
- if (!dozeParameters.get().canControlUnlockedScreenOff()) {
- return false
- }
-
// If we explicitly already decided not to play the screen off animation, then never change
// our mind.
if (decidedToAnimateGoingToSleep == false) {
@@ -323,7 +304,7 @@ class UnlockedScreenOffAnimationController @Inject constructor(
}
override fun shouldDelayDisplayDozeTransition(): Boolean =
- shouldPlayUnlockedScreenOffAnimation()
+ dozeParameters.get().shouldControlUnlockedScreenOff()
/**
* Whether we're doing the light reveal animation or we're done with that and animating in the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
index f530ec83aec5..fe69f7507503 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
@@ -25,6 +25,7 @@ import com.android.systemui.R
import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_IN
import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_OUT
import com.android.systemui.statusbar.events.SystemStatusAnimationCallback
+import com.android.systemui.util.animation.AnimationUtil.Companion.frames
/**
* Tied directly to [SystemStatusAnimationScheduler]. Any StatusBar-like thing (keyguard, collapsed
@@ -45,12 +46,12 @@ class StatusBarSystemEventAnimator(
R.dimen.ongoing_appops_chip_animation_out_status_bar_translation_x)
override fun onSystemEventAnimationBegin(): Animator {
- val moveOut = ValueAnimator.ofFloat(0f, 1f).setDuration(383)
+ val moveOut = ValueAnimator.ofFloat(0f, 1f).setDuration(23.frames)
moveOut.interpolator = STATUS_BAR_X_MOVE_OUT
moveOut.addUpdateListener { animation: ValueAnimator ->
animatedView.translationX = -(translationXIn * animation.animatedValue as Float)
}
- val alphaOut = ValueAnimator.ofFloat(1f, 0f).setDuration(133)
+ val alphaOut = ValueAnimator.ofFloat(1f, 0f).setDuration(8.frames)
alphaOut.interpolator = null
alphaOut.addUpdateListener { animation: ValueAnimator ->
animatedView.alpha = animation.animatedValue as Float
@@ -63,14 +64,14 @@ class StatusBarSystemEventAnimator(
override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator {
animatedView.translationX = translationXOut.toFloat()
- val moveIn = ValueAnimator.ofFloat(1f, 0f).setDuration(467)
- moveIn.startDelay = 33
+ val moveIn = ValueAnimator.ofFloat(1f, 0f).setDuration(28.frames)
+ moveIn.startDelay = 2.frames
moveIn.interpolator = STATUS_BAR_X_MOVE_IN
moveIn.addUpdateListener { animation: ValueAnimator ->
animatedView.translationX = translationXOut * animation.animatedValue as Float
}
- val alphaIn = ValueAnimator.ofFloat(0f, 1f).setDuration(167)
- alphaIn.startDelay = 67
+ val alphaIn = ValueAnimator.ofFloat(0f, 1f).setDuration(10.frames)
+ alphaIn.startDelay = 4.frames
alphaIn.interpolator = null
alphaIn.addUpdateListener { animation: ValueAnimator ->
animatedView.alpha = animation.animatedValue as Float
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 2c05a4ea8238..217a6134fbde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -73,6 +73,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.LongRunning;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.ActivityStarter;
@@ -153,6 +154,7 @@ public class UserSwitcherController implements Dumpable {
private final IActivityManager mActivityManager;
private final Executor mBgExecutor;
private final Executor mUiExecutor;
+ private final Executor mLongRunningExecutor;
private final boolean mGuestUserAutoCreated;
private final AtomicBoolean mGuestIsResetting;
private final AtomicBoolean mGuestCreationScheduled;
@@ -177,6 +179,7 @@ public class UserSwitcherController implements Dumpable {
TelephonyListenerManager telephonyListenerManager,
SecureSettings secureSettings,
@Background Executor bgExecutor,
+ @LongRunning Executor longRunningExecutor,
@Main Executor uiExecutor,
InteractionJankMonitor interactionJankMonitor,
LatencyTracker latencyTracker,
@@ -195,6 +198,7 @@ public class UserSwitcherController implements Dumpable {
mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(
this, mUserTracker, mUiEventLogger, secureSettings);
mBgExecutor = bgExecutor;
+ mLongRunningExecutor = longRunningExecutor;
mUiExecutor = uiExecutor;
if (!UserManager.isGuestUserEphemeral()) {
mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
@@ -794,7 +798,7 @@ public class UserSwitcherController implements Dumpable {
return;
}
- mBgExecutor.execute(() -> {
+ mLongRunningExecutor.execute(() -> {
int newGuestId = createGuest();
mGuestCreationScheduled.set(false);
mGuestIsResetting.set(false);
@@ -1211,7 +1215,8 @@ public class UserSwitcherController implements Dumpable {
}
// Use broadcast instead of ShadeController, as this dialog may have started in
// another process and normal dagger bindings are not available
- mBroadcastSender.closeSystemDialogs();
+ mBroadcastSender.sendBroadcastAsUser(
+ new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), UserHandle.CURRENT);
getContext().startActivityAsUser(
CreateUserActivity.createIntentForStart(getContext()),
mUserTracker.getUserHandle());
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index cbdf87ea0fcc..8f2a432d0ba1 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -155,21 +155,22 @@ constructor(
newRoot.relayout(params) { transaction ->
val vsyncId = Choreographer.getSfInstance().vsyncId
- backgroundExecutor.execute {
- // Apply the transaction that contains the first frame of the overlay
- // synchronously and apply another empty transaction with
- // 'vsyncId + 1' to make sure that it is actually displayed on
- // the screen. The second transaction is necessary to remove the screen blocker
- // (turn on the brightness) only when the content is actually visible as it
- // might be presented only in the next frame.
- // See b/197538198
- transaction.setFrameTimelineVsync(vsyncId).apply(/* sync */ true)
-
- transaction.setFrameTimelineVsync(vsyncId + 1).apply(/* sync */ true)
-
- Trace.endAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
- callback.run()
- }
+ // Apply the transaction that contains the first frame of the overlay and apply
+ // another empty transaction with 'vsyncId + 1' to make sure that it is actually
+ // displayed on the screen. The second transaction is necessary to remove the screen
+ // blocker (turn on the brightness) only when the content is actually visible as it
+ // might be presented only in the next frame.
+ // See b/197538198
+ transaction
+ .setFrameTimelineVsync(vsyncId)
+ .apply()
+
+ transaction.setFrameTimelineVsync(vsyncId + 1)
+ .addTransactionCommittedListener(backgroundExecutor) {
+ Trace.endAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
+ callback.run()
+ }
+ .apply()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/DualHeightHorizontalLinearLayout.kt b/packages/SystemUI/src/com/android/systemui/util/DualHeightHorizontalLinearLayout.kt
deleted file mode 100644
index cfceefa2006c..000000000000
--- a/packages/SystemUI/src/com/android/systemui/util/DualHeightHorizontalLinearLayout.kt
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.content.Context
-import android.content.res.Configuration
-import android.util.AttributeSet
-import android.util.DisplayMetrics
-import android.util.TypedValue
-import android.widget.LinearLayout
-import android.widget.TextView
-import com.android.systemui.R
-
-/**
- * Horizontal [LinearLayout] to contain some text.
- *
- * The height of this container can alternate between two different heights, depending on whether
- * the text takes one line or more.
- *
- * When the text takes multiple lines, it will use the values in the regular attributes (`padding`,
- * `layout_height`). The single line behavior must be set in XML.
- *
- * XML attributes for single line behavior:
- * * `systemui:textViewId`: set the id for the [TextView] that determines the height of the
- * container
- * * `systemui:singleLineHeight`: sets the height of the view when the text takes up only one line.
- * By default, it will use [getMinimumHeight].
- * * `systemui:singleLineVerticalPadding`: sets the padding (top and bottom) when then text takes up
- * only one line. By default, it is 0.
- *
- * All dimensions are updated when configuration changes.
- */
-class DualHeightHorizontalLinearLayout @JvmOverloads constructor(
- context: Context,
- attrs: AttributeSet? = null,
- defStyleAttrs: Int = 0,
- defStyleRes: Int = 0
-) : LinearLayout(context, attrs, defStyleAttrs, defStyleRes) {
-
- private val singleLineHeightValue: TypedValue?
- private var singleLineHeightPx = 0
-
- private val singleLineVerticalPaddingValue: TypedValue?
- private var singleLineVerticalPaddingPx = 0
-
- private val textViewId: Int
- private var textView: TextView? = null
-
- private val displayMetrics: DisplayMetrics
- get() = context.resources.displayMetrics
-
- private var initialPadding = mPaddingTop // All vertical padding is the same
-
- private var originalMaxLines = 1
- var alwaysSingleLine: Boolean = false
- set(value) {
- field = value
- if (field) {
- textView?.setSingleLine()
- } else {
- textView?.maxLines = originalMaxLines
- }
- }
-
- init {
- if (orientation != HORIZONTAL) {
- throw IllegalStateException("This view should always have horizontal orientation")
- }
-
- val ta = context.obtainStyledAttributes(
- attrs,
- R.styleable.DualHeightHorizontalLinearLayout, defStyleAttrs, defStyleRes
- )
-
- val tempHeight = TypedValue()
- singleLineHeightValue = if (
- ta.hasValue(R.styleable.DualHeightHorizontalLinearLayout_singleLineHeight)
- ) {
- ta.getValue(R.styleable.DualHeightHorizontalLinearLayout_singleLineHeight, tempHeight)
- tempHeight
- } else {
- null
- }
-
- val tempPadding = TypedValue()
- singleLineVerticalPaddingValue = if (
- ta.hasValue(R.styleable.DualHeightHorizontalLinearLayout_singleLineVerticalPadding)
- ) {
- ta.getValue(
- R.styleable.DualHeightHorizontalLinearLayout_singleLineVerticalPadding,
- tempPadding
- )
- tempPadding
- } else {
- null
- }
-
- textViewId = ta.getResourceId(R.styleable.DualHeightHorizontalLinearLayout_textViewId, 0)
-
- ta.recycle()
- }
-
- init {
- updateResources()
- }
-
- override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
- super.setPadding(left, top, right, bottom)
- initialPadding = top
- }
-
- override fun setPaddingRelative(start: Int, top: Int, end: Int, bottom: Int) {
- super.setPaddingRelative(start, top, end, bottom)
- initialPadding = top
- }
-
- override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec)
- textView?.let { tv ->
- if (tv.lineCount < 2 || alwaysSingleLine) {
- setMeasuredDimension(measuredWidth, singleLineHeightPx)
- mPaddingBottom = 0
- mPaddingTop = 0
- } else {
- mPaddingBottom = initialPadding
- mPaddingTop = initialPadding
- }
- }
- }
-
- override fun onFinishInflate() {
- super.onFinishInflate()
- textView = findViewById<TextView>(textViewId)?.also {
- originalMaxLines = it.maxLines
- }
- }
-
- override fun onConfigurationChanged(newConfig: Configuration?) {
- super.onConfigurationChanged(newConfig)
- updateResources()
- }
-
- override fun setOrientation(orientation: Int) {
- if (orientation == VERTICAL) {
- throw IllegalStateException("This view should always have horizontal orientation")
- }
- super.setOrientation(orientation)
- }
-
- private fun updateResources() {
- updateDimensionValue(singleLineHeightValue, minimumHeight, ::singleLineHeightPx::set)
- updateDimensionValue(singleLineVerticalPaddingValue, 0, ::singleLineVerticalPaddingPx::set)
- }
-
- private inline fun updateDimensionValue(
- tv: TypedValue?,
- defaultValue: Int,
- propertySetter: (Int) -> Unit
- ) {
- val value = tv?.let {
- if (it.resourceId != 0) {
- context.resources.getDimensionPixelSize(it.resourceId)
- } else {
- it.getDimension(displayMetrics).toInt()
- }
- } ?: defaultValue
- propertySetter(value)
- }
-} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt b/packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt
index c0538c110426..49582280b8e4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt
@@ -37,5 +37,11 @@ class AnimationUtil {
}
return (numFrames * 1000f / 60f).roundToLong()
}
+
+ /**
+ * Convenience extension function for [getMsForFrames], so that we can write `23.frames`
+ */
+ val Int.frames: Long
+ get() = getMsForFrames(this)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
index 3c869e7ceb40..de25ca981a65 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
@@ -211,27 +211,24 @@ public class QuickAccessWalletController {
public void startQuickAccessUiIntent(ActivityStarter activityStarter,
ActivityLaunchAnimator.Controller animationController,
boolean hasCard) {
- if (mQuickAccessWalletClient.useTargetActivityForQuickAccess() || !hasCard) {
- mQuickAccessWalletClient.getWalletPendingIntent(mCallbackExecutor,
- walletPendingIntent -> {
- if (walletPendingIntent == null) {
- Intent intent = mQuickAccessWalletClient.createWalletIntent();
- if (intent == null) {
- intent = getSysUiWalletIntent();
- }
- startQuickAccessViaIntent(intent, hasCard, activityStarter,
- animationController);
- return;
- }
- startQuickAccessViaPendingIntent(walletPendingIntent,
- activityStarter, animationController);
- });
- } else {
- startQuickAccessViaIntent(getSysUiWalletIntent(),
- hasCard,
- activityStarter,
- animationController);
- }
+ mQuickAccessWalletClient.getWalletPendingIntent(mCallbackExecutor,
+ walletPendingIntent -> {
+ if (walletPendingIntent != null) {
+ startQuickAccessViaPendingIntent(walletPendingIntent, activityStarter,
+ animationController);
+ return;
+ }
+ Intent intent = null;
+ if (!hasCard) {
+ intent = mQuickAccessWalletClient.createWalletIntent();
+ }
+ if (intent == null) {
+ intent = getSysUiWalletIntent();
+ }
+ startQuickAccessViaIntent(intent, hasCard, activityStarter,
+ animationController);
+
+ });
}
private Intent getSysUiWalletIntent() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
index 4bdab7658a06..cc606de1b0b9 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
@@ -58,7 +58,7 @@ private fun fingerprintModel(user: Int) = KeyguardFingerprintListenModel(
userId = user,
listening = false,
biometricEnabledForUser = false,
- bouncer = false,
+ bouncerIsOrWillShow = false,
canSkipBouncer = false,
credentialAttempted = false,
deviceInteractive = false,
@@ -85,9 +85,10 @@ private fun faceModel(user: Int) = KeyguardFaceListenModel(
authInterruptActive = false,
becauseCannotSkipBouncer = false,
biometricSettingEnabledForUser = false,
- bouncer = false,
+ bouncerFullyShown = false,
faceAuthenticated = false,
faceDisabled = false,
+ goingToSleep = false,
keyguardAwake = false,
keyguardGoingAway = false,
listeningForFaceAssistant = false,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 42e15c4fb7d9..775addd9390b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -35,10 +35,12 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.IStrongAuthTracker;
import android.app.trust.TrustManager;
@@ -50,15 +52,20 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.BiometricSourceType;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.fingerprint.FingerprintSensorProperties;
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.nfc.NfcAdapter;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.UserHandle;
@@ -121,6 +128,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
TEST_CARRIER, TEST_CARRIER_2, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", true, TEST_GROUP_UUID,
TEST_CARRIER_ID, 0);
+ private static final int FACE_SENSOR_ID = 0;
+ private static final int FINGERPRINT_SENSOR_ID = 1;
+
@Mock
private DumpManager mDumpManager;
@Mock
@@ -212,6 +222,16 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
+ when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(List.of(
+ new FingerprintSensorPropertiesInternal(1 /* sensorId */,
+ FingerprintSensorProperties.STRENGTH_STRONG,
+ 1 /* maxEnrollmentsPerUser */,
+ List.of(new ComponentInfoInternal("fingerprintSensor" /* componentId */,
+ "vendor/model/revision" /* hardwareVersion */,
+ "1.01" /* firmwareVersion */,
+ "00000001" /* serialNumber */, "" /* softwareVersion */)),
+ FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+ false /* resetLockoutRequiresHAT */)));
when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true);
when(mUserManager.isPrimaryUser()).thenReturn(true);
when(mStrongAuthTracker.getStub()).thenReturn(mock(IStrongAuthTracker.Stub.class));
@@ -232,9 +252,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mSpiedContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
mMockitoSession = ExtendedMockito.mockitoSession()
- .spyStatic(SubscriptionManager.class).startMocking();
+ .spyStatic(SubscriptionManager.class)
+ .spyStatic(ActivityManager.class)
+ .startMocking();
ExtendedMockito.doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
.when(SubscriptionManager::getDefaultSubscriptionId);
+ ExtendedMockito.doReturn(KeyguardUpdateMonitor.getCurrentUser())
+ .when(ActivityManager::getCurrentUser);
mTestableLooper = TestableLooper.get(this);
allowTestableLooperAsMainThread();
@@ -527,6 +551,15 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
+ public void testNoStartAuthenticate_whenAboutToShowBouncer() {
+ mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(
+ /* bouncerIsOrWillBeShowing */ true, /* bouncerFullyShown */ false);
+
+ verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+ anyBoolean());
+ }
+
+ @Test
public void testTriesToAuthenticate_whenKeyguard() {
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mTestableLooper.processAllMessages();
@@ -649,7 +682,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
// doesn't matter here
mKeyguardUpdateMonitor.onFaceAuthenticated(KeyguardUpdateMonitor.getCurrentUser(),
true /* isStrongBiometric */);
- mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
+ setKeyguardBouncerVisibility(true);
mTestableLooper.processAllMessages();
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
@@ -757,6 +790,59 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
+ public void testMultiUserLockoutChanged_whenUserSwitches() {
+ testMultiUserLockout_whenUserSwitches(BiometricConstants.BIOMETRIC_LOCKOUT_PERMANENT,
+ BiometricConstants.BIOMETRIC_LOCKOUT_PERMANENT);
+ }
+
+ @Test
+ public void testMultiUserLockoutNotChanged_whenUserSwitches() {
+ testMultiUserLockout_whenUserSwitches(BiometricConstants.BIOMETRIC_LOCKOUT_NONE,
+ BiometricConstants.BIOMETRIC_LOCKOUT_NONE);
+ }
+
+ private void testMultiUserLockout_whenUserSwitches(
+ @BiometricConstants.LockoutMode int fingerprintLockoutMode,
+ @BiometricConstants.LockoutMode int faceLockoutMode) {
+ final int newUser = 12;
+ final boolean faceLocked =
+ faceLockoutMode != BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
+ final boolean fpLocked =
+ fingerprintLockoutMode != BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
+ when(mFingerprintManager.getLockoutModeForUser(eq(FINGERPRINT_SENSOR_ID), eq(newUser)))
+ .thenReturn(fingerprintLockoutMode);
+ when(mFaceManager.getLockoutModeForUser(eq(FACE_SENSOR_ID), eq(newUser)))
+ .thenReturn(faceLockoutMode);
+
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+ mTestableLooper.processAllMessages();
+ mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+
+ verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+ verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
+ anyInt());
+
+ final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
+ final CancellationSignal fpCancel = spy(mKeyguardUpdateMonitor.mFingerprintCancelSignal);
+ mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel;
+ mKeyguardUpdateMonitor.mFingerprintCancelSignal = fpCancel;
+ KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
+ mKeyguardUpdateMonitor.registerCallback(callback);
+
+ mKeyguardUpdateMonitor.handleUserSwitchComplete(newUser);
+ mTestableLooper.processAllMessages();
+
+ verify(faceCancel, faceLocked ? times(1) : never()).cancel();
+ verify(fpCancel, fpLocked ? times(1) : never()).cancel();
+ verify(callback, faceLocked ? times(1) : never()).onBiometricRunningStateChanged(
+ eq(false), eq(BiometricSourceType.FACE));
+ verify(callback, fpLocked ? times(1) : never()).onBiometricRunningStateChanged(
+ eq(false), eq(BiometricSourceType.FINGERPRINT));
+ assertThat(mKeyguardUpdateMonitor.isFingerprintLockedOut()).isEqualTo(fpLocked);
+ assertThat(mKeyguardUpdateMonitor.isFaceLockedOut()).isEqualTo(faceLocked);
+ }
+
+ @Test
public void testGetUserCanSkipBouncer_whenTrust() {
int user = KeyguardUpdateMonitor.getCurrentUser();
mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, user, 0 /* flags */,
@@ -1064,7 +1150,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
private void setKeyguardBouncerVisibility(boolean isVisible) {
- mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(isVisible);
+ mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(isVisible, isVisible);
mTestableLooper.processAllMessages();
}
@@ -1115,5 +1201,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mSimStateChanged.set(true);
super.handleSimStateChange(subId, slotId, state);
}
+
+ @Override
+ protected int getBiometricLockoutDelay() {
+ return 0;
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
index 96e6bd15a3e2..5734c3de70e0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
@@ -37,7 +37,6 @@ import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.`when`
-import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -104,26 +103,6 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {
verify(runnable).run()
}
- @Test
- fun testWakeAndUnlockDelaysRunnable() {
- // GIVEN wakeAndUnlocking has been set to true
- screenOnCoordinator.wakeAndUnlocking = true
-
- // WHEN the screen turns on and two tasks have completed
- screenOnCoordinator.onScreenTurningOn(runnable)
- onUnfoldOverlayReady()
- onFoldAodReady()
-
- // THEN the runnable should not have run yet
- verify(runnable, never()).run()
-
- // WHEN the value of wakeAndUnlocking changes
- screenOnCoordinator.wakeAndUnlocking = false
-
- // THEN the runnable should have run, as it is the last task to complete
- verify(runnable).run()
- }
-
private fun onUnfoldOverlayReady() {
verify(unfoldAnimation).onScreenTurningOn(capture(readyCaptor))
readyCaptor.getValue().run()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 483dbf51d4a9..666c9e481adc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -48,6 +48,7 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.eq
+import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
@@ -81,8 +82,29 @@ class AuthContainerViewTest : SysuiTestCase() {
}
@Test
+ fun testNotifiesAnimatedIn() {
+ initializeContainer()
+ verify(callback).onDialogAnimatedIn()
+ }
+
+ @Test
+ fun testIgnoresAnimatedInWhenDismissed() {
+ val container = initializeContainer(addToView = false)
+ container.dismissFromSystemServer()
+ waitForIdleSync()
+
+ verify(callback, never()).onDialogAnimatedIn()
+
+ container.addToView()
+ waitForIdleSync()
+
+ // attaching the view resets the state and allows this to happen again
+ verify(callback).onDialogAnimatedIn()
+ }
+
+ @Test
fun testActionAuthenticated_sendsDismissedAuthenticated() {
- val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ val container = initializeContainer()
container.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_AUTHENTICATED
)
@@ -97,7 +119,7 @@ class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testActionUserCanceled_sendsDismissedUserCanceled() {
- val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ val container = initializeContainer()
container.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_USER_CANCELED
)
@@ -115,7 +137,7 @@ class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testActionButtonNegative_sendsDismissedButtonNegative() {
- val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ val container = initializeContainer()
container.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE
)
@@ -141,7 +163,7 @@ class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testActionError_sendsDismissedError() {
- val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ val container = initializeContainer()
authContainer!!.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_ERROR
)
@@ -183,7 +205,7 @@ class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testShowBiometricUI() {
- val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ val container = initializeContainer()
waitForIdleSync()
@@ -252,7 +274,10 @@ class AuthContainerViewTest : SysuiTestCase() {
assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.ime()) == 0).isTrue()
}
- private fun initializeContainer(authenticators: Int): TestAuthContainerView {
+ private fun initializeContainer(
+ authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
+ addToView: Boolean = true
+ ): TestAuthContainerView {
val config = AuthContainerView.Config()
config.mContext = mContext
config.mCallback = callback
@@ -291,7 +316,11 @@ class AuthContainerViewTest : SysuiTestCase() {
lockPatternUtils,
Handler(TestableLooper.get(this).looper)
)
- ViewUtils.attachView(authContainer)
+
+ if (addToView) {
+ authContainer!!.addToView()
+ }
+
return authContainer!!
}
@@ -316,6 +345,12 @@ class AuthContainerViewTest : SysuiTestCase() {
TestableLooper.get(this).processAllMessages()
super.waitForIdleSync()
}
+
+ private fun AuthContainerView.addToView() {
+ ViewUtils.attachView(this)
+ waitForIdleSync()
+ assertThat(isAttachedToWindow).isTrue()
+ }
}
private fun AuthContainerView.hasBiometricPrompt() =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 42c3c7f899fa..190228d80cde 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -20,6 +20,8 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRIN
import static android.hardware.biometrics.BiometricManager.Authenticators;
import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
+import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
@@ -104,6 +106,8 @@ import javax.inject.Provider;
@SmallTest
public class AuthControllerTest extends SysuiTestCase {
+ private static final long REQUEST_ID = 22;
+
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@@ -173,6 +177,9 @@ public class AuthControllerTest extends SysuiTestCase {
when(mDialog1.isAllowDeviceCredentials()).thenReturn(false);
when(mDialog2.isAllowDeviceCredentials()).thenReturn(false);
+ when(mDialog1.getRequestId()).thenReturn(REQUEST_ID);
+ when(mDialog2.getRequestId()).thenReturn(REQUEST_ID);
+
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
@@ -482,7 +489,12 @@ public class AuthControllerTest extends SysuiTestCase {
@Test
public void testHideAuthenticationDialog_invokesDismissFromSystemServer() {
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
- mAuthController.hideAuthenticationDialog();
+
+ mAuthController.hideAuthenticationDialog(REQUEST_ID + 1);
+ verify(mDialog1, never()).dismissFromSystemServer();
+ assertThat(mAuthController.mCurrentDialog).isSameInstanceAs(mDialog1);
+
+ mAuthController.hideAuthenticationDialog(REQUEST_ID);
verify(mDialog1).dismissFromSystemServer();
// In this case, BiometricService sends the error to the client immediately, without
@@ -512,7 +524,7 @@ public class AuthControllerTest extends SysuiTestCase {
eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED),
AdditionalMatchers.aryEq(credentialAttestation));
- mAuthController.hideAuthenticationDialog();
+ mAuthController.hideAuthenticationDialog(REQUEST_ID);
}
@Test
@@ -648,7 +660,7 @@ public class AuthControllerTest extends SysuiTestCase {
verify(mDisplayManager).registerDisplayListener(any(), eq(mHandler));
- mAuthController.hideAuthenticationDialog();
+ mAuthController.hideAuthenticationDialog(REQUEST_ID);
verify(mDisplayManager).unregisterDisplayListener(any());
}
@@ -704,7 +716,7 @@ public class AuthControllerTest extends SysuiTestCase {
0 /* userId */,
0 /* operationId */,
"testPackage",
- 1 /* requestId */,
+ REQUEST_ID,
BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 406ed5c17b0c..05cf6a50eda0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -67,7 +67,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.VibratorHelper;
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.SystemUIDialogManager;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
@@ -150,8 +149,6 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
- private KeyguardBypassController mKeyguardBypassController;
- @Mock
private DisplayManager mDisplayManager;
@Mock
private Handler mHandler;
@@ -252,7 +249,6 @@ public class UdfpsControllerTest extends SysuiTestCase {
mUdfpsHapticsSimulator,
Optional.of(mHbmProvider),
mKeyguardStateController,
- mKeyguardBypassController,
mDisplayManager,
mHandler,
mConfigurationController,
@@ -310,75 +306,6 @@ public class UdfpsControllerTest extends SysuiTestCase {
}
@Test
- public void onActionMove_dozing_setDeviceEntryIntent() throws RemoteException {
- // GIVEN the current animation is UdfpsKeyguardViewController and device IS dozing
- when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
- when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
- when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
- when(mStatusBarStateController.isDozing()).thenReturn(true);
-
- // GIVEN that the overlay is showing
- mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID,
- BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
- mFgExecutor.runAllReady();
-
- // WHEN ACTION_DOWN is received
- verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
- MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
- mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
- moveEvent.recycle();
-
- // THEN device entry intent is never to true b/c device was dozing on touch
- verify(mKeyguardBypassController, never()).setUserHasDeviceEntryIntent(true);
- }
-
- @Test
- public void onActionMove_onKeyguard_setDeviceEntryIntent() throws RemoteException {
- // GIVEN the current animation is UdfpsKeyguardViewController and device isn't dozing
- when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
- when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
- when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
- when(mStatusBarStateController.isDozing()).thenReturn(false);
-
- // GIVEN that the overlay is showing
- mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID,
- BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
- mFgExecutor.runAllReady();
-
- // WHEN ACTION_DOWN is received
- verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
- MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
- mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
- moveEvent.recycle();
-
- // THEN device entry intent is set to true
- verify(mKeyguardBypassController).setUserHasDeviceEntryIntent(true);
- }
-
- @Test
- public void onActionMove_onEnrollment_neverSetDeviceEntryIntent() throws RemoteException {
- // GIVEN the current animation is UdfpsEnrollViewController
- when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
- when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
- when(mUdfpsView.getAnimationViewController()).thenReturn(
- (UdfpsAnimationViewController) mock(UdfpsEnrollViewController.class));
-
- // GIVEN that the overlay is showing
- mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID,
- BiometricOverlayConstants.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback);
- mFgExecutor.runAllReady();
-
- // WHEN ACTION_DOWN is received
- verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
- MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
- mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
- moveEvent.recycle();
-
- // THEN device entry intent is never set
- verify(mKeyguardBypassController, never()).setUserHasDeviceEntryIntent(anyBoolean());
- }
-
- @Test
public void onActionMoveTouch_whenCanDismissLockScreen_entersDevice()
throws RemoteException {
onActionMoveTouch_whenCanDismissLockScreen_entersDevice(false /* stale */);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index 3d8d1282e184..6d4cc4c96e0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -23,7 +23,6 @@ import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.ViewUtils
import android.view.LayoutInflater
-import android.view.Surface
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -37,7 +36,6 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.anyInt
import org.mockito.Mockito.never
import org.mockito.Mockito.nullable
import org.mockito.Mockito.verify
@@ -148,7 +146,7 @@ class UdfpsViewTest : SysuiTestCase() {
view.startIllumination(onDone)
val illuminator = withArgCaptor<Runnable> {
- verify(hbmProvider).enableHbm(anyInt(), nullable(Surface::class.java), capture())
+ verify(hbmProvider).enableHbm(capture())
}
assertThat(view.isIlluminationRequested).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index f514b5643553..a1d19332b537 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -56,6 +56,7 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val user0 = UserHandle.of(0)
val user1 = UserHandle.of(1)
const val DEFAULT_FLAG = Context.RECEIVER_EXPORTED
+ val DEFAULT_PERMISSION: String? = null
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
const val TEST_ACTION = "TEST_ACTION"
@@ -190,6 +191,38 @@ class BroadcastDispatcherTest : SysuiTestCase() {
}
@Test
+ fun testAddReceiverCorrectPermission_executor() {
+ val flag = 3
+ val permission = "CUSTOM_PERMISSION"
+
+ broadcastDispatcher.registerReceiver(
+ broadcastReceiver,
+ intentFilter,
+ flags = flag,
+ permission = permission
+ )
+ testableLooper.processAllMessages()
+
+ verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(flag))
+
+ assertSame(broadcastReceiver, argumentCaptor.value.receiver)
+ assertSame(intentFilter, argumentCaptor.value.filter)
+ assertSame(permission, argumentCaptor.value.permission)
+ }
+
+ @Test
+ fun testAddReceiverDefaultPermission_executor() {
+ broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter)
+ testableLooper.processAllMessages()
+
+ verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
+
+ assertSame(broadcastReceiver, argumentCaptor.value.receiver)
+ assertSame(intentFilter, argumentCaptor.value.filter)
+ assertSame(DEFAULT_PERMISSION, argumentCaptor.value.permission)
+ }
+
+ @Test
fun testAddReceiverCorrectFlag_executor() {
val flag = 3
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
index fd1c41ef25b8..141b3b446c01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
@@ -17,6 +17,7 @@
package com.android.systemui.broadcast
import android.content.BroadcastReceiver
+import android.content.Context
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
@@ -45,7 +46,8 @@ class FakeBroadcastDispatcher(
filter: IntentFilter,
handler: Handler,
user: UserHandle,
- flags: Int
+ @Context.RegisterReceiverFlags flags: Int,
+ permission: String?
) {
registeredReceivers.add(receiver)
}
@@ -55,7 +57,8 @@ class FakeBroadcastDispatcher(
filter: IntentFilter,
executor: Executor?,
user: UserHandle?,
- flags: Int
+ @Context.RegisterReceiverFlags flags: Int,
+ permission: String?
) {
registeredReceivers.add(receiver)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
index 4e3345c7576d..116b81d4d5ca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
@@ -85,7 +85,11 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
userBroadcastDispatcher = object : UserBroadcastDispatcher(
mockContext, USER_ID, testableLooper.looper, mock(Executor::class.java), logger) {
- override fun createActionReceiver(action: String, flags: Int): ActionReceiver {
+ override fun createActionReceiver(
+ action: String,
+ permission: String?,
+ flags: Int
+ ): ActionReceiver {
return mock(ActionReceiver::class.java)
}
}
@@ -123,6 +127,24 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
}
@Test
+ fun testDifferentActionReceiversForDifferentPermissions() {
+ intentFilter = IntentFilter(ACTION_1)
+ val receiverData1 =
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE, "PERMISSION1")
+ val receiverData2 =
+ ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE, "PERMISSION2")
+
+ userBroadcastDispatcher.registerReceiver(receiverData1, 0)
+ userBroadcastDispatcher.registerReceiver(receiverData2, 0)
+ testableLooper.processAllMessages()
+
+ assertNotSame(
+ userBroadcastDispatcher.getActionReceiver(ACTION_1, 0, "PERMISSION1"),
+ userBroadcastDispatcher.getActionReceiver(ACTION_1, 0, "PERMISSION2")
+ )
+ }
+
+ @Test
fun testSingleReceiverRegistered_logging() {
intentFilter = IntentFilter(ACTION_1)
@@ -213,8 +235,45 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
any(), any(), any(), nullable(String::class.java), any(), eq(FLAG))
}
- private fun UserBroadcastDispatcher
- .getActionReceiver(action: String, flags: Int): ActionReceiver? {
- return actionsToActionsReceivers.get(action to flags)
+ @Test
+ fun testCreateActionReceiver_registerWithPermission() {
+ val permission = "CUSTOM_PERMISSION"
+ val uBR = UserBroadcastDispatcher(
+ mockContext,
+ USER_ID,
+ testableLooper.looper,
+ fakeExecutor,
+ logger
+ )
+ uBR.registerReceiver(
+ ReceiverData(
+ broadcastReceiver,
+ IntentFilter(ACTION_1),
+ fakeExecutor,
+ USER_HANDLE,
+ permission
+ ),
+ FLAG
+ )
+
+ testableLooper.processAllMessages()
+ fakeExecutor.runAllReady()
+
+ verify(mockContext).registerReceiverAsUser(
+ any(), any(), any(), eq(permission), any(), eq(FLAG))
+ }
+
+ private fun UserBroadcastDispatcher.getActionReceiver(
+ action: String,
+ flags: Int,
+ permission: String? = null
+ ): ActionReceiver? {
+ return actionsToActionsReceivers.get(
+ UserBroadcastDispatcher.ReceiverProperties(
+ action,
+ flags,
+ permission
+ )
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
index cff6b9ab935b..3c7ea4fe6f35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
@@ -168,7 +168,8 @@ class ControlsControllerImplTest : SysuiTestCase() {
controller.auxiliaryPersistenceWrapper = auxiliaryPersistenceWrapper
verify(broadcastDispatcher).registerReceiver(
- capture(broadcastReceiverCaptor), any(), any(), eq(UserHandle.ALL), anyInt())
+ capture(broadcastReceiverCaptor), any(), any(), eq(UserHandle.ALL), anyInt(), any()
+ )
verify(listingController).addCallback(capture(listingCallbackCaptor))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index f4b378e6c19c..4736587e6955 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -211,20 +211,6 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
}
@Test
- public void testPausingAod_doesNotResetBrightness() throws Exception {
- mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
- mScreen.transitionTo(INITIALIZED, DOZE_AOD);
- waitForSensorManager();
-
- mSensor.sendSensorEvent(1);
-
- mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
- mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
-
- assertEquals(1, mServiceFake.screenBrightness);
- }
-
- @Test
public void testPulsing_withoutLightSensor_setsAoDDimmingScrimTransparent() throws Exception {
mScreen = new DozeScreenBrightness(
mContext,
@@ -431,18 +417,14 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
}
@Test
- public void pausingAod_unblanksAfterSensor() {
+ public void pausingAod_unblanksAfterSensorEvent() {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
waitForSensorManager();
- mSensor.sendSensorEvent(2);
-
mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
- mSensor.sendSensorEvent(0);
-
reset(mDozeHost);
mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
waitForSensorManager();
@@ -451,21 +433,6 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
}
@Test
- public void pausingAod_unblanksIfSensorWasAlwaysReady() throws Exception {
- mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
- mScreen.transitionTo(INITIALIZED, DOZE_AOD);
- waitForSensorManager();
-
- mSensor.sendSensorEvent(2);
- mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
- mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
-
- reset(mDozeHost);
- mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
- verify(mDozeHost).setAodDimmingScrim(eq(0f));
- }
-
- @Test
public void transitionToDoze_shouldClampBrightness_afterTimeout_clampsToDim() {
when(mWakefulnessLifecycle.getLastSleepReason()).thenReturn(
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
@@ -538,6 +505,44 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
assertEquals(mServiceFake.screenBrightness, DEFAULT_BRIGHTNESS);
}
+ @Test
+ public void transitionToAodPaused_resetsToDefaultBrightness_lightSensorDisabled() {
+ // GIVEN AOD
+ mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+ mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+ // WHEN AOD is paused
+ mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
+ mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+ waitForSensorManager();
+
+ // THEN brightness is reset and light sensor is unregistered
+ assertEquals(mServiceFake.screenBrightness, DEFAULT_BRIGHTNESS);
+
+ // THEN new light events don't update brightness since the light sensor was unregistered
+ mSensor.sendSensorEvent(1);
+ assertEquals(mServiceFake.screenBrightness, DEFAULT_BRIGHTNESS);
+ }
+
+ @Test
+ public void transitionFromAodPausedToAod_lightSensorEnabled() {
+ // GIVEN AOD paused
+ mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+ mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+ mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
+ mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+
+ // WHEN device transitions back to AOD
+ mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
+ waitForSensorManager();
+
+ // WHEN there are brightness changes
+ mSensor.sendSensorEvent(1);
+
+ // THEN aod brightness is updated
+ assertEquals(mServiceFake.screenBrightness, 1);
+ }
+
private void waitForSensorManager() {
mFakeExecutor.runAllReady();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index 76f6529e3894..6453c204342c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -107,6 +107,7 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
mStatusBarKeyguardViewManager,
mBlurUtils,
mHandler,
+ mResources,
MAX_BURN_IN_OFFSET,
BURN_IN_PROTECTION_UPDATE_INTERVAL,
MILLIS_UNTIL_FULL_JITTER);
@@ -160,11 +161,10 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
bouncerExpansionCaptor.getValue().onExpansionChanged(0.5f);
verify(mBlurUtils, never()).applyBlur(eq(mViewRoot), anyInt(), eq(false));
- verify(mDreamOverlayContainerView, never()).setAlpha(anyFloat());
}
@Test
- public void testBouncerAnimation_updateBlurAndAlpha() {
+ public void testBouncerAnimation_updateBlur() {
final ArgumentCaptor<BouncerExpansionCallback> bouncerExpansionCaptor =
ArgumentCaptor.forClass(BouncerExpansionCallback.class);
mController.onViewAttached();
@@ -182,6 +182,5 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
bouncerExpansionCaptor.getValue().onExpansionChanged(bouncerHideAmount);
verify(mBlurUtils).blurRadiusOfRatio(1 - scaledFraction);
verify(mBlurUtils).applyBlur(mViewRoot, (int) blurRadius, false);
- verify(mDreamOverlayContainerView).setAlpha(scaledFraction);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
index 35bcfcd39fca..2448f1a7633d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
@@ -40,7 +40,10 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.Arrays;
+import java.util.List;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -448,4 +451,70 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase {
verify(firstViewInfo.view, never()).getParent();
verify(mLayout, never()).removeView(firstViewInfo.view);
}
+
+ @Test
+ public void testGetViews() {
+ final ComplicationLayoutEngine engine =
+ new ComplicationLayoutEngine(mLayout, 0, mTouchSession, 0, 0);
+
+ final ViewInfo topEndView = new ViewInfo(
+ new ComplicationLayoutParams(
+ 100,
+ 100,
+ ComplicationLayoutParams.POSITION_TOP
+ | ComplicationLayoutParams.POSITION_END,
+ ComplicationLayoutParams.DIRECTION_DOWN,
+ 0),
+ Complication.CATEGORY_STANDARD,
+ mLayout);
+
+ addComplication(engine, topEndView);
+
+ final ViewInfo topStartView = new ViewInfo(
+ new ComplicationLayoutParams(
+ 100,
+ 100,
+ ComplicationLayoutParams.POSITION_TOP
+ | ComplicationLayoutParams.POSITION_START,
+ ComplicationLayoutParams.DIRECTION_DOWN,
+ 0),
+ Complication.CATEGORY_SYSTEM,
+ mLayout);
+
+ addComplication(engine, topStartView);
+
+ final ViewInfo bottomEndView = new ViewInfo(
+ new ComplicationLayoutParams(
+ 100,
+ 100,
+ ComplicationLayoutParams.POSITION_BOTTOM
+ | ComplicationLayoutParams.POSITION_END,
+ ComplicationLayoutParams.DIRECTION_START,
+ 1),
+ Complication.CATEGORY_SYSTEM,
+ mLayout);
+
+ addComplication(engine, bottomEndView);
+
+ verifyViewsAtPosition(engine, ComplicationLayoutParams.POSITION_TOP, topStartView,
+ topEndView);
+ verifyViewsAtPosition(engine,
+ ComplicationLayoutParams.POSITION_TOP | ComplicationLayoutParams.POSITION_START,
+ topStartView);
+ verifyViewsAtPosition(engine,
+ ComplicationLayoutParams.POSITION_BOTTOM,
+ bottomEndView);
+ }
+
+ private void verifyViewsAtPosition(ComplicationLayoutEngine engine, int position,
+ ViewInfo... views) {
+ final List<Integer> idList = engine.getViewsAtPosition(position).stream()
+ .map(View::getId)
+ .collect(Collectors.toList());
+
+ assertThat(idList).containsExactlyElementsIn(
+ Arrays.stream(views)
+ .map(viewInfo -> viewInfo.view.getId())
+ .collect(Collectors.toList()));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index 74cf49758ac6..a016a1d8ca70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -169,7 +169,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
* Makes sure swiping up when bouncer initially showing doesn't change the expansion amount.
*/
@Test
- public void testSwipeUp_whenBouncerInitiallyShowing_keepsExpansionAtZero() {
+ public void testSwipeUp_whenBouncerInitiallyShowing_doesNotSetExpansion() {
when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
mTouchHandler.onSessionStart(mTouchSession);
@@ -191,21 +191,15 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
assertThat(gestureListener.onScroll(event1, event2, 0, distanceY))
.isTrue();
- // Ensure only called once
- verify(mStatusBarKeyguardViewManager)
+ verify(mStatusBarKeyguardViewManager, never())
.onPanelExpansionChanged(anyFloat(), anyBoolean(), anyBoolean());
-
- // TODO(b/227348372): update the logic and also this test.
- // Ensure the expansion is kept at 0.
- verify(mStatusBarKeyguardViewManager).onPanelExpansionChanged(eq(0f), eq(false),
- eq(true));
}
/**
* Makes sure swiping down when bouncer initially hidden doesn't change the expansion amount.
*/
@Test
- public void testSwipeDown_whenBouncerInitiallyHidden_keepsExpansionAtOne() {
+ public void testSwipeDown_whenBouncerInitiallyHidden_doesNotSetExpansion() {
mTouchHandler.onSessionStart(mTouchSession);
ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
@@ -225,14 +219,8 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
assertThat(gestureListener.onScroll(event1, event2, 0, distanceY))
.isTrue();
- // Ensure only called once
- verify(mStatusBarKeyguardViewManager)
+ verify(mStatusBarKeyguardViewManager, never())
.onPanelExpansionChanged(anyFloat(), anyBoolean(), anyBoolean());
-
- // TODO(b/227348372): update the logic and also this test.
- // Ensure the expansion is kept at 1.
- verify(mStatusBarKeyguardViewManager).onPanelExpansionChanged(eq(1f), eq(false),
- eq(true));
}
/**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt
new file mode 100644
index 000000000000..1d2afe4047c3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt
@@ -0,0 +1,146 @@
+/*
+ * 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.systemui.dump
+
+import androidx.test.filters.SmallTest
+
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+
+import java.io.PrintWriter
+import java.io.StringWriter
+
+@SmallTest
+class DumpsysTableLoggerTest : SysuiTestCase() {
+ private val logger = DumpsysTableLogger(
+ TEST_SECTION_NAME,
+ TEST_COLUMNS,
+ TEST_DATA_VALID)
+
+ private val stringWriter = StringWriter()
+ private val printWriter = PrintWriter(stringWriter)
+
+ @Before
+ fun setup() {
+ }
+
+ @Test
+ fun testTableLogger_header() {
+ logger.printTableData(printWriter)
+ val lines = logLines(stringWriter)
+
+ val line1 = lines[0]
+
+ assertEquals("table logger header is incorrect",
+ HEADER_PREFIX + TEST_SECTION_NAME, line1)
+ }
+
+ @Test
+ fun testTableLogger_version() {
+ logger.printTableData(printWriter)
+ val lines = logLines(stringWriter)
+
+ val line2 = lines[1]
+
+ assertEquals("version probably shouldn't have changed",
+ "version $VERSION", line2)
+ }
+
+ @Test
+ fun testTableLogger_footer() {
+ logger.printTableData(printWriter)
+ val lines = logLines(stringWriter)
+
+ val footer = lines.last()
+ android.util.Log.d("evanevan", footer)
+ android.util.Log.d("evanevan", lines.toString())
+
+ assertEquals("table logger footer is incorrect",
+ FOOTER_PREFIX + TEST_SECTION_NAME, footer)
+ }
+
+ @Test
+ fun testTableLogger_data_length() {
+ logger.printTableData(printWriter)
+ val lines = logLines(stringWriter)
+
+ // Header is 2 lines long, plus a line for the column defs so data is lines[3..last()-1]
+ val data = lines.subList(3, lines.size - 1)
+ assertEquals(TEST_DATA_LENGTH, data.size)
+ }
+
+ @Test
+ fun testTableLogger_data_columns() {
+ logger.printTableData(printWriter)
+ val lines = logLines(stringWriter)
+
+ // Header is always 2 lines long so data is lines[2..last()-1]
+ val data = lines.subList(3, lines.size - 1)
+
+ data.forEach { dataLine ->
+ assertEquals(TEST_COLUMNS.size, dataLine.split(SEPARATOR).size)
+ }
+ }
+
+ @Test
+ fun testInvalidLinesAreFiltered() {
+ // GIVEN an invalid data row, by virtue of having an extra field
+ val invalidLine = List(TEST_COLUMNS.size) { col ->
+ "data${col}X"
+ } + "INVALID COLUMN"
+ val invalidData = TEST_DATA_VALID.toMutableList().also {
+ it.add(invalidLine)
+ }
+
+ // WHEN the table logger is created and asked to print the table
+ val tableLogger = DumpsysTableLogger(
+ TEST_SECTION_NAME,
+ TEST_COLUMNS,
+ invalidData)
+
+ tableLogger.printTableData(printWriter)
+
+ // THEN the invalid line is filtered out
+ val invalidString = invalidLine.joinToString(separator = SEPARATOR)
+ val logString = stringWriter.toString()
+
+ assertThat(logString).doesNotContain(invalidString)
+ }
+
+ private fun logLines(sw: StringWriter): List<String> {
+ return sw.toString().split("\n").filter { it.isNotBlank() }
+ }
+}
+
+// Copying these here from [DumpsysTableLogger] so that we catch any accidental versioning change
+private const val HEADER_PREFIX = "SystemUI TableSection START: "
+private const val FOOTER_PREFIX = "SystemUI TableSection END: "
+private const val SEPARATOR = "|" // TBD
+private const val VERSION = "1"
+
+const val TEST_SECTION_NAME = "TestTableSection"
+const val TEST_DATA_LENGTH = 5
+val TEST_COLUMNS = arrayListOf("col1", "col2", "col3")
+val TEST_DATA_VALID = List(TEST_DATA_LENGTH) { row ->
+ List(TEST_COLUMNS.size) { col ->
+ "data$col$row"
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
index 5dea5a1a0a64..3b4888fc5b58 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
@@ -26,6 +26,7 @@ import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.time.FakeSystemClock
import org.junit.Before
import org.junit.Test
@@ -68,7 +69,8 @@ class LogBufferFreezerTest : SysuiTestCase() {
any(IntentFilter::class.java),
eq(executor),
any(UserHandle::class.java),
- anyInt())
+ anyInt(),
+ nullable())
receiver = receiverCaptor.value
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
index 46e675684782..67fe0445e225 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
@@ -52,6 +52,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
@Mock lateinit var panel: MediaControlPanel
@Mock lateinit var visualStabilityProvider: VisualStabilityProvider
@Mock lateinit var mediaHostStatesManager: MediaHostStatesManager
+ @Mock lateinit var mediaHostState: MediaHostState
@Mock lateinit var activityStarter: ActivityStarter
@Mock @Main private lateinit var executor: DelayableExecutor
@Mock lateinit var mediaDataManager: MediaDataManager
@@ -142,7 +143,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
expected.forEach {
clock.setCurrentTimeMillis(it.third)
MediaPlayerData.addMediaPlayer(it.first, it.second.copy(notificationKey = it.first),
- panel, clock)
+ panel, clock, isSsReactivated = false)
}
for ((index, key) in MediaPlayerData.playerKeys().withIndex()) {
@@ -188,4 +189,40 @@ class MediaCarouselControllerTest : SysuiTestCase() {
verify(logger).logCarouselSettings()
}
+
+ @Test
+ fun testLocationChangeQs_logged() {
+ mediaCarouselController.onDesiredLocationChanged(
+ MediaHierarchyManager.LOCATION_QS,
+ mediaHostState,
+ animate = false)
+ verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_QS)
+ }
+
+ @Test
+ fun testLocationChangeQqs_logged() {
+ mediaCarouselController.onDesiredLocationChanged(
+ MediaHierarchyManager.LOCATION_QQS,
+ mediaHostState,
+ animate = false)
+ verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_QQS)
+ }
+
+ @Test
+ fun testLocationChangeLockscreen_logged() {
+ mediaCarouselController.onDesiredLocationChanged(
+ MediaHierarchyManager.LOCATION_LOCKSCREEN,
+ mediaHostState,
+ animate = false)
+ verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_LOCKSCREEN)
+ }
+
+ @Test
+ fun testLocationChangeDream_logged() {
+ mediaCarouselController.onDesiredLocationChanged(
+ MediaHierarchyManager.LOCATION_DREAM_OVERLAY,
+ mediaHostState,
+ animate = false)
+ verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_DREAM_OVERLAY)
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index f2e3edbc0761..91167161ac75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media
+import android.app.PendingIntent
import org.mockito.Mockito.`when` as whenever
import android.content.Intent
import android.graphics.Color
@@ -749,6 +750,20 @@ public class MediaControlPanelTest : SysuiTestCase() {
}
@Test
+ fun tapContentView_isLogged() {
+ val pendingIntent = mock(PendingIntent::class.java)
+ val captor = ArgumentCaptor.forClass(View.OnClickListener::class.java)
+ val data = mediaData.copy(clickIntent = pendingIntent)
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(data, KEY)
+ verify(viewHolder.player).setOnClickListener(captor.capture())
+
+ captor.value.onClick(viewHolder.player)
+
+ verify(logger).logTapContentView(anyInt(), eq(PACKAGE), eq(instanceId))
+ }
+
+ @Test
fun logSeek() {
player.attachPlayer(viewHolder)
player.bindPlayer(mediaData, KEY)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
index b0f6a80bc8a5..eacec20cac12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -87,10 +87,10 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
public void eventNotEmittedWithoutDevice() {
// WHEN data source emits an event without device data
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
// THEN an event isn't emitted
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(),
- anyInt());
+ anyInt(), anyBoolean());
}
@Test
@@ -99,7 +99,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
// THEN an event isn't emitted
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(),
- anyInt());
+ anyInt(), anyBoolean());
}
@Test
@@ -108,11 +108,11 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
// WHEN media event is received
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
// THEN the listener receives a combined event
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean(),
- anyInt());
+ anyInt(), anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@@ -120,13 +120,13 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
public void emitEventAfterMediaFirst() {
// GIVEN that media event has already been received
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
// WHEN device event is received
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
// THEN the listener receives a combined event
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean(),
- anyInt());
+ anyInt(), anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@@ -134,16 +134,16 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
public void migrateKeyMediaFirst() {
// GIVEN that media and device info has already been received
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
reset(mListener);
// WHEN a key migration event is received
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
// THEN the listener receives a combined event
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean(),
- anyInt());
+ anyInt(), anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@@ -151,7 +151,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
public void migrateKeyDeviceFirst() {
// GIVEN that media and device info has already been received
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
reset(mListener);
// WHEN a key migration event is received
@@ -159,7 +159,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
// THEN the listener receives a combined event
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean(),
- anyInt());
+ anyInt(), anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@@ -167,17 +167,17 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
public void migrateKeyMediaAfter() {
// GIVEN that media and device info has already been received
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
reset(mListener);
// WHEN a second key migration event is received for media
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
// THEN the key has already been migrated
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean(),
- anyInt());
+ anyInt(), anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@@ -185,17 +185,17 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
public void migrateKeyDeviceAfter() {
// GIVEN that media and device info has already been received
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
reset(mListener);
// WHEN a second key migration event is received for the device
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
// THEN the key has already be migrated
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean(),
- anyInt());
+ anyInt(), anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@@ -210,7 +210,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
@Test
public void mediaDataRemovedAfterMediaEvent() {
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
mManager.onMediaDataRemoved(KEY);
verify(mListener).onMediaDataRemoved(eq(KEY));
}
@@ -226,14 +226,14 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
public void mediaDataKeyUpdated() {
// GIVEN that device and media events have already been received
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
// WHEN the key is changed
mManager.onMediaDataLoaded("NEW_KEY", KEY, mMediaData, true /* immediately */,
- 0 /* receivedSmartspaceCardLatency */);
+ 0 /* receivedSmartspaceCardLatency */, false /* isSsReactivated */);
// THEN the listener gets a load event with the correct keys
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
verify(mListener).onMediaDataLoaded(
- eq("NEW_KEY"), any(), captor.capture(), anyBoolean(), anyInt());
+ eq("NEW_KEY"), any(), captor.capture(), anyBoolean(), anyInt(), anyBoolean());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
index b8e249fcfeb1..3b996d4a37d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
@@ -115,7 +115,7 @@ class MediaDataFilterTest : SysuiTestCase() {
// THEN we should tell the listener
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -124,7 +124,8 @@ class MediaDataFilterTest : SysuiTestCase() {
mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest)
// THEN we should NOT tell the listener
- verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt())
+ verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(),
+ anyInt(), anyBoolean())
}
@Test
@@ -171,51 +172,56 @@ class MediaDataFilterTest : SysuiTestCase() {
// THEN we should add back the guest user media
verify(listener).onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true),
- eq(0))
+ eq(0), eq(false))
// but not the main user's
verify(listener, never()).onMediaDataLoaded(eq(KEY), any(), eq(dataMain), anyBoolean(),
- anyInt())
+ anyInt(), anyBoolean())
}
@Test
- fun testHasAnyMedia() {
- assertThat(mediaDataFilter.hasAnyMedia()).isFalse()
+ fun testHasAnyMediaOrRecommendation() {
+ assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isFalse()
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = dataMain)
+ assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isTrue()
assertThat(mediaDataFilter.hasAnyMedia()).isTrue()
}
@Test
- fun testHasActiveMedia() {
- assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
+ fun testHasActiveMediaOrRecommendation() {
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
val data = dataMain.copy(active = true)
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data)
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
}
@Test
- fun testHasAnyMedia_onlyCurrentUser() {
- assertThat(mediaDataFilter.hasAnyMedia()).isFalse()
+ fun testHasAnyMediaOrRecommendation_onlyCurrentUser() {
+ assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isFalse()
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = dataGuest)
+ assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isFalse()
assertThat(mediaDataFilter.hasAnyMedia()).isFalse()
}
@Test
- fun testHasActiveMedia_onlyCurrentUser() {
- assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
+ fun testHasActiveMediaOrRecommendation_onlyCurrentUser() {
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
val data = dataGuest.copy(active = true)
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data)
- assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
+ assertThat(mediaDataFilter.hasAnyMedia()).isFalse()
}
@Test
fun testOnNotificationRemoved_doesntHaveMedia() {
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = dataMain)
mediaDataFilter.onMediaDataRemoved(KEY)
+ assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isFalse()
assertThat(mediaDataFilter.hasAnyMedia()).isFalse()
}
@@ -232,9 +238,9 @@ class MediaDataFilterTest : SysuiTestCase() {
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
verify(listener)
- .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true),
- eq(false))
- assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
+ .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
+ assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
@Test
@@ -243,9 +249,10 @@ class MediaDataFilterTest : SysuiTestCase() {
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
- verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt())
- verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean(),
- anyBoolean())
+ verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(),
+ anyInt(), anyBoolean())
+ verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
@@ -257,9 +264,9 @@ class MediaDataFilterTest : SysuiTestCase() {
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
verify(listener)
- .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true),
- eq(true))
- assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
+ .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
+ assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
@Test
@@ -271,8 +278,8 @@ class MediaDataFilterTest : SysuiTestCase() {
clock.advanceTime(SMARTSPACE_MAX_AGE + 100)
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
- verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean(),
- anyBoolean())
+ verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
@@ -284,16 +291,16 @@ class MediaDataFilterTest : SysuiTestCase() {
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
- eq(0))
+ eq(0), eq(false))
// AND we get a smartspace signal
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
// THEN we should tell listeners to treat the media as not active instead
verify(listener, never()).onMediaDataLoaded(eq(KEY), eq(KEY), any(), anyBoolean(),
- anyInt())
- verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean(),
- anyBoolean())
+ anyInt(), anyBoolean())
+ verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
@@ -305,7 +312,7 @@ class MediaDataFilterTest : SysuiTestCase() {
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
- eq(0))
+ eq(0), eq(false))
// AND we get a smartspace signal
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
@@ -313,11 +320,10 @@ class MediaDataFilterTest : SysuiTestCase() {
// THEN we should tell listeners to treat the media as active instead
val dataCurrentAndActive = dataCurrent.copy(active = true)
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
- eq(100))
- assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
+ eq(100), eq(true))
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
// Smartspace update shouldn't be propagated for the empty rec list.
- verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean(),
- anyBoolean())
+ verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
}
@Test
@@ -326,7 +332,7 @@ class MediaDataFilterTest : SysuiTestCase() {
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
- eq(0))
+ eq(0), eq(false))
// AND we get a smartspace signal
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
@@ -334,12 +340,11 @@ class MediaDataFilterTest : SysuiTestCase() {
// THEN we should tell listeners to treat the media as active instead
val dataCurrentAndActive = dataCurrent.copy(active = true)
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
- eq(100))
- assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
+ eq(100), eq(true))
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
// Smartspace update should also be propagated but not prioritized.
verify(listener)
- .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false),
- eq(true))
+ .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
}
@Test
@@ -348,6 +353,7 @@ class MediaDataFilterTest : SysuiTestCase() {
mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
@@ -356,17 +362,18 @@ class MediaDataFilterTest : SysuiTestCase() {
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
- eq(0))
+ eq(0), eq(false))
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
val dataCurrentAndActive = dataCurrent.copy(active = true)
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
- eq(100))
+ eq(100), eq(true))
mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
+ assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index ccd8ef1b7c6b..b9ff8775f2b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -210,7 +210,7 @@ class MediaDataManagerTest : SysuiTestCase() {
backgroundExecutor.runAllReady()
foregroundExecutor.runAllReady()
verify(listener).onMediaDataLoaded(eq(PACKAGE_NAME), eq(null), capture(mediaDataCaptor),
- eq(true), eq(0))
+ eq(true), eq(0), eq(false))
mediaDataManager.setTimedOut(PACKAGE_NAME, timedOut = true)
verify(logger).logMediaTimeout(anyInt(), eq(PACKAGE_NAME),
@@ -244,7 +244,7 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value!!.active).isTrue()
}
@@ -266,7 +266,7 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value!!.playbackLocation).isEqualTo(
MediaData.PLAYBACK_CAST_REMOTE)
verify(logger).logActiveMediaAdded(anyInt(), eq(SYSTEM_PACKAGE_NAME),
@@ -295,7 +295,7 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN the media data indicates that it is for resumption
verify(listener)
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value.resumption).isTrue()
assertThat(mediaDataCaptor.value.isPlaying).isFalse()
verify(logger).logActiveConvertedToResume(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId))
@@ -311,7 +311,7 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(foregroundExecutor.runAllReady()).isEqualTo(2)
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
val data = mediaDataCaptor.value
assertThat(data.resumption).isFalse()
val resumableData = data.copy(resumeAction = Runnable {})
@@ -323,7 +323,7 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN the data is for resumption and the key is migrated to the package name
verify(listener)
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value.resumption).isTrue()
verify(listener, never()).onMediaDataRemoved(eq(KEY))
// WHEN the second is removed
@@ -332,7 +332,7 @@ class MediaDataManagerTest : SysuiTestCase() {
verify(listener)
.onMediaDataLoaded(
eq(PACKAGE_NAME), eq(PACKAGE_NAME), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value.resumption).isTrue()
verify(listener).onMediaDataRemoved(eq(KEY_2))
}
@@ -373,7 +373,7 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN the media data indicates that it is for resumption
verify(listener)
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(null), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
val data = mediaDataCaptor.value
assertThat(data.resumption).isTrue()
assertThat(data.song).isEqualTo(SESSION_TITLE)
@@ -396,7 +396,7 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
verify(listener).onMediaDataLoaded(eq(PACKAGE_NAME), eq(null), capture(mediaDataCaptor),
- eq(true), eq(0))
+ eq(true), eq(0), eq(false))
val data = mediaDataCaptor.value
mediaDataManager.setMediaResumptionEnabled(false)
@@ -445,7 +445,7 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -456,7 +456,7 @@ class MediaDataManagerTest : SysuiTestCase() {
eq(SmartspaceMediaData(KEY_MEDIA_SMARTSPACE, true /* isActive */, true /*isValid */,
PACKAGE_NAME, mediaSmartspaceBaseAction, listOf(mediaRecommendationItem),
DISMISS_INTENT, 0, 1234L)),
- eq(false), eq(false))
+ eq(false))
}
@Test
@@ -469,7 +469,7 @@ class MediaDataManagerTest : SysuiTestCase() {
.copy(targetId = KEY_MEDIA_SMARTSPACE, isActive = true,
isValid = false, dismissIntent = DISMISS_INTENT,
headphoneConnectionTimeMillis = 1234L)),
- eq(false), eq(false))
+ eq(false))
}
@Test
@@ -489,14 +489,14 @@ class MediaDataManagerTest : SysuiTestCase() {
eq(EMPTY_SMARTSPACE_MEDIA_DATA
.copy(targetId = KEY_MEDIA_SMARTSPACE, isActive = true,
isValid = false, dismissIntent = null, headphoneConnectionTimeMillis = 1234L)),
- eq(false), eq(false))
+ eq(false))
}
@Test
fun testOnSmartspaceMediaDataLoaded_hasNoneMediaTarget_notCallsListener() {
smartspaceMediaDataProvider.onTargetsAvailable(listOf())
verify(listener, never())
- .onSmartspaceMediaDataLoaded(anyObject(), anyObject(), anyBoolean(), anyBoolean())
+ .onSmartspaceMediaDataLoaded(anyObject(), anyObject(), anyBoolean())
}
@Test
@@ -520,7 +520,7 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN smartspace signal is ignored
verify(listener, never())
- .onSmartspaceMediaDataLoaded(anyObject(), anyObject(), anyBoolean(), anyBoolean())
+ .onSmartspaceMediaDataLoaded(anyObject(), anyObject(), anyBoolean())
}
@Test
@@ -528,7 +528,7 @@ class MediaDataManagerTest : SysuiTestCase() {
// GIVEN a media recommendation card is present
smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
verify(listener).onSmartspaceMediaDataLoaded(eq(KEY_MEDIA_SMARTSPACE), anyObject(),
- anyBoolean(), anyBoolean())
+ anyBoolean())
// WHEN the media recommendation setting is turned off
Settings.Secure.putInt(context.contentResolver,
@@ -562,7 +562,7 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN the last active time is not changed
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
}
@@ -584,7 +584,7 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN the last active time is not changed
verify(listener)
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value.resumption).isTrue()
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
@@ -615,7 +615,7 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN only the first MAX_COMPACT_ACTIONS are actually set
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value.actionsToShowInCompact.size).isEqualTo(
MediaDataManager.MAX_COMPACT_ACTIONS)
}
@@ -640,7 +640,7 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
assertThat(mediaDataCaptor.value!!.semanticActions).isNull()
assertThat(mediaDataCaptor.value!!.actions).hasSize(1)
@@ -803,6 +803,6 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
- eq(0))
+ eq(0), eq(false))
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
index 7bd210d762f9..6e38d26411ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
@@ -61,8 +61,10 @@ public class MediaPlayerDataTest : SysuiTestCase() {
val playerIsRemote = mock(MediaControlPanel::class.java)
val dataIsRemote = createMediaData("app2", PLAYING, REMOTE, !RESUMPTION)
- MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote, systemClock)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying, systemClock)
+ MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote, systemClock,
+ isSsReactivated = false)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying, systemClock,
+ isSsReactivated = false)
val players = MediaPlayerData.players()
assertThat(players).hasSize(2)
@@ -77,18 +79,22 @@ public class MediaPlayerDataTest : SysuiTestCase() {
val playerIsPlaying2 = mock(MediaControlPanel::class.java)
var dataIsPlaying2 = createMediaData("app2", !PLAYING, LOCAL, !RESUMPTION)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1, systemClock)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1, systemClock,
+ isSsReactivated = false)
systemClock.advanceTime(1)
- MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2, systemClock)
+ MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2, systemClock,
+ isSsReactivated = false)
systemClock.advanceTime(1)
dataIsPlaying1 = createMediaData("app1", !PLAYING, LOCAL, !RESUMPTION)
dataIsPlaying2 = createMediaData("app2", PLAYING, LOCAL, !RESUMPTION)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1, systemClock)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1, systemClock,
+ isSsReactivated = false)
systemClock.advanceTime(1)
- MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2, systemClock)
+ MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2, systemClock,
+ isSsReactivated = false)
systemClock.advanceTime(1)
val players = MediaPlayerData.players()
@@ -116,14 +122,20 @@ public class MediaPlayerDataTest : SysuiTestCase() {
val dataUndetermined = createMediaData("app6", UNDETERMINED, LOCAL, RESUMPTION)
MediaPlayerData.addMediaPlayer(
- "3", dataIsStoppedAndLocal, playerIsStoppedAndLocal, systemClock)
+ "3", dataIsStoppedAndLocal, playerIsStoppedAndLocal, systemClock,
+ isSsReactivated = false)
MediaPlayerData.addMediaPlayer(
- "5", dataIsStoppedAndRemote, playerIsStoppedAndRemote, systemClock)
- MediaPlayerData.addMediaPlayer("4", dataCanResume, playerCanResume, systemClock)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying, systemClock)
+ "5", dataIsStoppedAndRemote, playerIsStoppedAndRemote, systemClock,
+ isSsReactivated = false)
+ MediaPlayerData.addMediaPlayer("4", dataCanResume, playerCanResume, systemClock,
+ isSsReactivated = false)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying, systemClock,
+ isSsReactivated = false)
MediaPlayerData.addMediaPlayer(
- "2", dataIsPlayingAndRemote, playerIsPlayingAndRemote, systemClock)
- MediaPlayerData.addMediaPlayer("6", dataUndetermined, playerUndetermined, systemClock)
+ "2", dataIsPlayingAndRemote, playerIsPlayingAndRemote, systemClock,
+ isSsReactivated = false)
+ MediaPlayerData.addMediaPlayer("6", dataUndetermined, playerUndetermined, systemClock,
+ isSsReactivated = false)
val players = MediaPlayerData.players()
assertThat(players).hasSize(6)
@@ -141,11 +153,13 @@ public class MediaPlayerDataTest : SysuiTestCase() {
assertThat(MediaPlayerData.players()).hasSize(0)
- MediaPlayerData.addMediaPlayer(keyA, data, playerIsPlaying, systemClock)
+ MediaPlayerData.addMediaPlayer(keyA, data, playerIsPlaying, systemClock,
+ isSsReactivated = false)
systemClock.advanceTime(1)
assertThat(MediaPlayerData.players()).hasSize(1)
- MediaPlayerData.addMediaPlayer(keyB, data, playerIsPlaying, systemClock)
+ MediaPlayerData.addMediaPlayer(keyB, data, playerIsPlaying, systemClock,
+ isSsReactivated = false)
systemClock.advanceTime(1)
assertThat(MediaPlayerData.players()).hasSize(2)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaResumeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaResumeListenerTest.kt
index 2d34913d3467..3e98a12b4564 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaResumeListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaResumeListenerTest.kt
@@ -149,7 +149,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
resumeBrowserFactory, dumpManager, clock)
listener.setManager(mediaDataManager)
verify(broadcastDispatcher, never()).registerReceiver(eq(listener.userChangeReceiver),
- any(), any(), any(), anyInt())
+ any(), any(), any(), anyInt(), any())
// When data is loaded, we do NOT execute or update anything
listener.onMediaDataLoaded(KEY, OLD_KEY, data)
@@ -272,7 +272,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
// Make sure broadcast receiver is registered
resumeListener.setManager(mediaDataManager)
verify(broadcastDispatcher).registerReceiver(eq(resumeListener.userChangeReceiver),
- any(), any(), any(), anyInt())
+ any(), any(), any(), anyInt(), any())
// When we get an unlock event
val intent = Intent(Intent.ACTION_USER_UNLOCKED)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
index ee4f8db48ae3..558645377936 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
@@ -162,7 +162,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -185,7 +185,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -215,7 +215,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -231,14 +231,14 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
// WHEN a loaded event is received that matches the local session
filter.onMediaDataLoaded(KEY, null, mediaData2)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is filtered
verify(mediaListener, never()).onMediaDataLoaded(
- eq(KEY), eq(null), eq(mediaData2), anyBoolean(), anyInt())
+ eq(KEY), eq(null), eq(mediaData2), anyBoolean(), anyInt(), anyBoolean())
}
@Test
@@ -255,7 +255,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
// THEN the event is not filtered because there isn't a notification for the remote
// session.
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -273,14 +273,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
// WHEN a loaded event is received that matches the local session
filter.onMediaDataLoaded(key2, null, mediaData2)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is filtered
verify(mediaListener, never())
- .onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyInt())
+ .onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(),
+ anyInt(), anyBoolean())
// AND there should be a removed event for key2
verify(mediaListener).onMediaDataRemoved(eq(key2))
}
@@ -300,14 +301,14 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
// WHEN a loaded event is received that matches the remote session
filter.onMediaDataLoaded(key2, null, mediaData2)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -324,14 +325,14 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
// WHEN a loaded event is received that matches the local session
filter.onMediaDataLoaded(KEY, null, mediaData2)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData2), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -350,7 +351,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the event is not filtered
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -373,7 +374,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the key migration event is fired
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(key1), eq(mediaData2), eq(true),
- eq(0))
+ eq(0), eq(false))
}
@Test
@@ -403,13 +404,14 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the key migration event is filtered
verify(mediaListener, never())
- .onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyInt())
+ .onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(),
+ anyInt(), anyBoolean())
// WHEN a loaded event is received that matches the remote session
filter.onMediaDataLoaded(key2, null, mediaData1)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the key migration event is fired
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData1), eq(true),
- eq(0))
+ eq(0), eq(false))
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java
index 114fc90e8590..247316a32473 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java
@@ -75,11 +75,13 @@ public class MediaDreamSentinelTest extends SysuiTestCase {
final MediaDataManager.Listener listener = listenerCaptor.getValue();
when(mMediaDataManager.hasActiveMedia()).thenReturn(false);
- listener.onMediaDataLoaded(mKey, mOldKey, mData, true, 0);
+ listener.onMediaDataLoaded(mKey, mOldKey, mData, /* immediately= */ true,
+ /* receivedSmartspaceCardLatency= */ 0, /* isSsReactived= */ false);
verify(mDreamOverlayStateController, never()).addComplication(any());
when(mMediaDataManager.hasActiveMedia()).thenReturn(true);
- listener.onMediaDataLoaded(mKey, mOldKey, mData, true, 0);
+ listener.onMediaDataLoaded(mKey, mOldKey, mData, /* immediately= */true,
+ /* receivedSmartspaceCardLatency= */0, /* isSsReactived= */ false);
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
listener.onMediaDataRemoved(mKey);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
index 3e92e90f2a77..43fb1bd8636e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
@@ -145,7 +145,7 @@ public class AutoAddTrackerTest extends SysuiTestCase {
public void testBroadcastReceiverRegistered() {
verify(mBroadcastDispatcher).registerReceiver(
any(), mIntentFilterArgumentCaptor.capture(), any(), eq(UserHandle.of(USER)),
- anyInt());
+ anyInt(), any());
assertTrue(
mIntentFilterArgumentCaptor.getValue().hasAction(Intent.ACTION_SETTING_RESTORED));
@@ -158,13 +158,14 @@ public class AutoAddTrackerTest extends SysuiTestCase {
InOrder inOrder = Mockito.inOrder(mBroadcastDispatcher);
inOrder.verify(mBroadcastDispatcher).unregisterReceiver(any());
inOrder.verify(mBroadcastDispatcher)
- .registerReceiver(any(), any(), any(), eq(UserHandle.of(USER + 1)), anyInt());
+ .registerReceiver(any(), any(), any(), eq(UserHandle.of(USER + 1)), anyInt(),
+ any());
}
@Test
public void testSettingRestoredWithTilesNotRemovedInSource_noAutoAddedInTarget() {
verify(mBroadcastDispatcher).registerReceiver(
- mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt());
+ mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any());
// These tiles were present in the original device
String restoredTiles = "saver,work,internet,cast";
@@ -188,7 +189,7 @@ public class AutoAddTrackerTest extends SysuiTestCase {
public void testSettingRestoredWithTilesRemovedInSource_noAutoAddedInTarget() {
verify(mBroadcastDispatcher)
.registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(),
- anyInt());
+ anyInt(), any());
// These tiles were present in the original device
String restoredTiles = "saver,internet,cast";
@@ -212,7 +213,7 @@ public class AutoAddTrackerTest extends SysuiTestCase {
public void testSettingRestoredWithTilesRemovedInSource_sameAutoAddedinTarget() {
verify(mBroadcastDispatcher)
.registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(),
- anyInt());
+ anyInt(), any());
// These tiles were present in the original device
String restoredTiles = "saver,internet,cast";
@@ -237,7 +238,7 @@ public class AutoAddTrackerTest extends SysuiTestCase {
public void testSettingRestoredWithTilesRemovedInSource_othersAutoAddedinTarget() {
verify(mBroadcastDispatcher)
.registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(),
- anyInt());
+ anyInt(), any());
// These tiles were present in the original device
String restoredTiles = "saver,internet,cast";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
index 7b17c36aaf16..35d0024b3bf1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
@@ -8,20 +8,20 @@ import android.testing.TestableLooper
import android.testing.ViewUtils
import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.internal.logging.testing.FakeMetricsLogger
import com.android.systemui.R
import com.android.systemui.classifier.FalsingManagerFake
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
import com.android.systemui.globalactions.GlobalActionsDialogLite
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.phone.MultiUserSwitchController
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.statusbar.policy.UserInfoController
+import com.android.systemui.util.mockito.capture
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.utils.leaks.LeakCheckedTest
import com.google.common.truth.Truth.assertThat
@@ -29,10 +29,14 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
@@ -65,11 +69,12 @@ class FooterActionsControllerTest : LeakCheckedTest() {
@Mock
private lateinit var uiEventLogger: UiEventLogger
@Mock
- private lateinit var featureFlags: FeatureFlags
- @Mock
private lateinit var securityFooterController: QSSecurityFooter
@Mock
private lateinit var fgsManagerController: QSFgsManagerFooter
+ @Captor
+ private lateinit var visibilityChangedCaptor:
+ ArgumentCaptor<VisibilityChangedDispatcher.OnVisibilityChangedListener>
private lateinit var controller: FooterActionsController
@@ -78,6 +83,8 @@ class FooterActionsControllerTest : LeakCheckedTest() {
private val falsingManager: FalsingManagerFake = FalsingManagerFake()
private lateinit var testableLooper: TestableLooper
private lateinit var fakeSettings: FakeSettings
+ private lateinit var securityFooter: View
+ private lateinit var fgsFooter: View
@Before
fun setUp() {
@@ -87,9 +94,14 @@ class FooterActionsControllerTest : LeakCheckedTest() {
whenever(multiUserSwitchControllerFactory.create(any()))
.thenReturn(multiUserSwitchController)
- whenever(featureFlags.isEnabled(Flags.NEW_FOOTER)).thenReturn(false)
whenever(globalActionsDialogProvider.get()).thenReturn(globalActionsDialog)
+ securityFooter = View(mContext)
+ fgsFooter = View(mContext)
+
+ whenever(securityFooterController.view).thenReturn(securityFooter)
+ whenever(fgsManagerController.view).thenReturn(fgsFooter)
+
view = inflateView()
controller = constructFooterActionsController(view)
@@ -107,6 +119,13 @@ class FooterActionsControllerTest : LeakCheckedTest() {
}
@Test
+ fun testInitializesControllers() {
+ verify(multiUserSwitchController).init()
+ verify(fgsManagerController).init()
+ verify(securityFooterController).init()
+ }
+
+ @Test
fun testLogPowerMenuClick() {
controller.visible = true
falsingManager.setFalseTap(false)
@@ -182,6 +201,10 @@ class FooterActionsControllerTest : LeakCheckedTest() {
@Test
fun testCleanUpGAD() {
reset(globalActionsDialogProvider)
+ // We are creating a new controller, so detach the views from it
+ (securityFooter.parent as ViewGroup).removeView(securityFooter)
+ (fgsFooter.parent as ViewGroup).removeView(fgsFooter)
+
whenever(globalActionsDialogProvider.get()).thenReturn(globalActionsDialog)
val view = inflateView()
controller = constructFooterActionsController(view)
@@ -198,6 +221,80 @@ class FooterActionsControllerTest : LeakCheckedTest() {
verify(globalActionsDialog).destroy()
}
+ @Test
+ fun testSeparatorVisibility_noneVisible_gone() {
+ verify(securityFooterController)
+ .setOnVisibilityChangedListener(capture(visibilityChangedCaptor))
+ val listener = visibilityChangedCaptor.value
+ val separator = controller.securityFootersSeparator
+
+ setVisibilities(securityFooterVisible = false, fgsFooterVisible = false, listener)
+ assertThat(separator.visibility).isEqualTo(View.GONE)
+ }
+
+ @Test
+ fun testSeparatorVisibility_onlySecurityFooterVisible_gone() {
+ verify(securityFooterController)
+ .setOnVisibilityChangedListener(capture(visibilityChangedCaptor))
+ val listener = visibilityChangedCaptor.value
+ val separator = controller.securityFootersSeparator
+
+ setVisibilities(securityFooterVisible = true, fgsFooterVisible = false, listener)
+ assertThat(separator.visibility).isEqualTo(View.GONE)
+ }
+
+ @Test
+ fun testSeparatorVisibility_onlyFgsFooterVisible_gone() {
+ verify(securityFooterController)
+ .setOnVisibilityChangedListener(capture(visibilityChangedCaptor))
+ val listener = visibilityChangedCaptor.value
+ val separator = controller.securityFootersSeparator
+
+ setVisibilities(securityFooterVisible = false, fgsFooterVisible = true, listener)
+ assertThat(separator.visibility).isEqualTo(View.GONE)
+ }
+
+ @Test
+ fun testSeparatorVisibility_bothVisible_visible() {
+ verify(securityFooterController)
+ .setOnVisibilityChangedListener(capture(visibilityChangedCaptor))
+ val listener = visibilityChangedCaptor.value
+ val separator = controller.securityFootersSeparator
+
+ setVisibilities(securityFooterVisible = true, fgsFooterVisible = true, listener)
+ assertThat(separator.visibility).isEqualTo(View.VISIBLE)
+ }
+
+ @Test
+ fun testFgsFooterCollapsed() {
+ verify(securityFooterController)
+ .setOnVisibilityChangedListener(capture(visibilityChangedCaptor))
+ val listener = visibilityChangedCaptor.value
+
+ val booleanCaptor = ArgumentCaptor.forClass(Boolean::class.java)
+
+ clearInvocations(fgsManagerController)
+ setVisibilities(securityFooterVisible = false, fgsFooterVisible = true, listener)
+ verify(fgsManagerController, atLeastOnce()).setCollapsed(capture(booleanCaptor))
+ assertThat(booleanCaptor.allValues.last()).isFalse()
+
+ clearInvocations(fgsManagerController)
+ setVisibilities(securityFooterVisible = true, fgsFooterVisible = true, listener)
+ verify(fgsManagerController, atLeastOnce()).setCollapsed(capture(booleanCaptor))
+ assertThat(booleanCaptor.allValues.last()).isTrue()
+ }
+
+ private fun setVisibilities(
+ securityFooterVisible: Boolean,
+ fgsFooterVisible: Boolean,
+ listener: VisibilityChangedDispatcher.OnVisibilityChangedListener
+ ) {
+ securityFooter.visibility = if (securityFooterVisible) View.VISIBLE else View.GONE
+ listener.onVisibilityChanged(securityFooter.visibility)
+ fgsFooter.visibility = if (fgsFooterVisible) View.VISIBLE else View.GONE
+ listener.onVisibilityChanged(fgsFooter.visibility)
+ }
+
private fun inflateView(): FooterActionsView {
return LayoutInflater.from(context)
.inflate(R.layout.footer_actions, null) as FooterActionsView
@@ -208,6 +305,6 @@ class FooterActionsControllerTest : LeakCheckedTest() {
activityStarter, userManager, userTracker, userInfoController,
deviceProvisionedController, securityFooterController, fgsManagerController,
falsingManager, metricsLogger, globalActionsDialogProvider, uiEventLogger,
- showPMLiteButton = true, fakeSettings, Handler(testableLooper.looper), featureFlags)
+ showPMLiteButton = true, fakeSettings, Handler(testableLooper.looper))
}
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt
index a67483b10c4b..4c7240673fb0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt
@@ -163,7 +163,7 @@ class HeaderPrivacyIconsControllerTest : SysuiTestCase() {
val receiverCaptor = argumentCaptor<BroadcastReceiver>()
whenever(safetyCenterManager.isSafetyCenterEnabled).thenReturn(true)
verify(broadcastDispatcher).registerReceiver(capture(receiverCaptor),
- any(), any(), nullable(), anyInt())
+ any(), any(), nullable(), anyInt(), nullable())
receiverCaptor.value.onReceive(
context,
Intent(SafetyCenterManager.ACTION_SAFETY_CENTER_ENABLED_CHANGED)
@@ -193,8 +193,10 @@ class HeaderPrivacyIconsControllerTest : SysuiTestCase() {
val broadcastReceiverCaptor = argumentCaptor<BroadcastReceiver>()
val intentFilterCaptor = argumentCaptor<IntentFilter>()
// Broadcast receiver is registered on init and when privacy chip is attached
- verify(broadcastDispatcher, times(2)).registerReceiver(capture(broadcastReceiverCaptor),
- capture(intentFilterCaptor), any(), nullable(), anyInt())
+ verify(broadcastDispatcher, times(2)).registerReceiver(
+ capture(broadcastReceiverCaptor),
+ capture(intentFilterCaptor), any(), nullable(), anyInt(), nullable()
+ )
}
private fun setPrivacyController(micCamera: Boolean, location: Boolean) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
index bf82e90e88f6..489c8c86028e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
@@ -59,22 +59,14 @@ class QSContainerImplTest : SysuiTestCase() {
fun testContainerBottomPadding() {
qsContainer.updateResources(
qsPanelController,
- quickStatusBarHeaderController,
- /* newFooter */ false
- )
- verify(qsPanelContainer).setPaddingRelative(anyInt(), anyInt(), anyInt(), eq(0))
-
- qsContainer.updateResources(
- qsPanelController,
- quickStatusBarHeaderController,
- /* newFooter */ true
+ quickStatusBarHeaderController
)
verify(qsPanelContainer)
.setPaddingRelative(
anyInt(),
anyInt(),
anyInt(),
- eq(mContext.resources.getDimensionPixelSize(R.dimen.new_footer_height))
+ eq(mContext.resources.getDimensionPixelSize(R.dimen.footer_actions_height))
)
}
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 63f8641ad16d..829445eb92be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Fragment;
@@ -304,6 +305,16 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
assertThat(mQsFragmentView.getY()).isEqualTo(-qsAbsoluteBottom);
}
+ @Test
+ public void setCollapseExpandAction_passedToControllers() {
+ Runnable action = () -> {};
+ QSFragment fragment = resumeAndGetFragment();
+ fragment.setCollapseExpandAction(action);
+
+ verify(mQSPanelController).setCollapseExpandAction(action);
+ verify(mQuickQSPanelController).setCollapseExpandAction(action);
+ }
+
@Override
protected Fragment instantiate(Context context, String className, Bundle arguments) {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index 58a070db9a95..689de50d5b4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -6,7 +6,6 @@ import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
-import com.android.systemui.flags.FeatureFlags
import com.android.systemui.media.MediaHost
import com.android.systemui.media.MediaHostState
import com.android.systemui.plugins.FalsingManager
@@ -35,8 +34,6 @@ import org.mockito.Mockito.`when` as whenever
class QSPanelControllerTest : SysuiTestCase() {
@Mock private lateinit var qsPanel: QSPanel
- @Mock private lateinit var qsFgsManagerFooter: QSFgsManagerFooter
- @Mock private lateinit var qsSecurityFooter: QSSecurityFooter
@Mock private lateinit var tunerService: TunerService
@Mock private lateinit var qsTileHost: QSTileHost
@Mock private lateinit var qsCustomizerController: QSCustomizerController
@@ -50,7 +47,6 @@ class QSPanelControllerTest : SysuiTestCase() {
@Mock private lateinit var brightnessSlider: BrightnessSliderController
@Mock private lateinit var brightnessSliderFactory: BrightnessSliderController.Factory
@Mock private lateinit var falsingManager: FalsingManager
- @Mock private lateinit var featureFlags: FeatureFlags
@Mock private lateinit var mediaHost: MediaHost
@Mock private lateinit var tile: QSTile
@Mock private lateinit var otherTile: QSTile
@@ -69,8 +65,6 @@ class QSPanelControllerTest : SysuiTestCase() {
controller = QSPanelController(
qsPanel,
- qsFgsManagerFooter,
- qsSecurityFooter,
tunerService,
qsTileHost,
qsCustomizerController,
@@ -84,7 +78,6 @@ class QSPanelControllerTest : SysuiTestCase() {
brightnessControllerFactory,
brightnessSliderFactory,
falsingManager,
- featureFlags,
statusBarKeyguardViewManager
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
index 04bbd60b8d90..e237a5ce03fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
@@ -13,32 +13,24 @@
*/
package com.android.systemui.qs
-import android.content.res.Configuration
-import android.content.res.Configuration.ORIENTATION_LANDSCAPE
-import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import android.view.View
import android.view.ViewGroup
+import android.view.accessibility.AccessibilityNodeInfo
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
-import com.android.systemui.plugins.qs.QSTileView
-import com.android.systemui.qs.QSPanelControllerBase.TileRecord
-import com.android.systemui.qs.logging.QSLogger
-import com.android.systemui.qs.tileimpl.QSTileImpl
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyBoolean
-import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
@@ -47,22 +39,8 @@ class QSPanelTest : SysuiTestCase() {
private lateinit var mTestableLooper: TestableLooper
private lateinit var mQsPanel: QSPanel
- @Mock
- private lateinit var mHost: QSTileHost
-
- @Mock
- private lateinit var dndTile: QSTileImpl<*>
-
- @Mock
- private lateinit var mDndTileRecord: TileRecord
-
- @Mock
- private lateinit var mQSLogger: QSLogger
private lateinit var mParentView: ViewGroup
- @Mock
- private lateinit var mQSTileView: QSTileView
-
private lateinit var mFooter: View
@Before
@@ -71,8 +49,6 @@ class QSPanelTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this)
mTestableLooper = TestableLooper.get(this)
- mDndTileRecord.tile = dndTile
- mDndTileRecord.tileView = mQSTileView
mTestableLooper.runWithLooper {
mQsPanel = QSPanel(mContext, null)
mQsPanel.initialize()
@@ -80,63 +56,28 @@ class QSPanelTest : SysuiTestCase() {
mFooter = LinearLayout(mContext).apply { id = R.id.qs_footer }
mQsPanel.addView(mFooter)
mQsPanel.onFinishInflate()
- mQsPanel.setSecurityFooter(View(mContext), false)
- mQsPanel.setHeaderContainer(LinearLayout(mContext))
// Provides a parent with non-zero size for QSPanel
mParentView = FrameLayout(mContext).apply {
addView(mQsPanel)
}
-
- whenever(dndTile.tileSpec).thenReturn("dnd")
- whenever(mHost.tiles).thenReturn(emptyList())
- whenever(mHost.createTileView(any(), any(), anyBoolean())).thenReturn(mQSTileView)
- mQsPanel.addTile(mDndTileRecord)
}
}
@Test
- fun testSecurityFooter_appearsOnBottomOnSplitShade() {
- mQsPanel.onConfigurationChanged(getNewOrientationConfig(ORIENTATION_LANDSCAPE))
- mQsPanel.switchSecurityFooter(true)
+ fun testHasCollapseAccessibilityAction() {
+ val info = AccessibilityNodeInfo(mQsPanel)
+ mQsPanel.onInitializeAccessibilityNodeInfo(info)
- mTestableLooper.runWithLooper {
- mQsPanel.isExpanded = true
- }
-
- // After mFooter
- assertThat(mQsPanel.indexOfChild(mQsPanel.mSecurityFooter)).isEqualTo(
- mQsPanel.indexOfChild(mFooter) + 1
- )
+ assertThat(info.actions and AccessibilityNodeInfo.ACTION_COLLAPSE).isNotEqualTo(0)
+ assertThat(info.actions and AccessibilityNodeInfo.ACTION_EXPAND).isEqualTo(0)
}
@Test
- fun testSecurityFooter_appearsOnBottomIfPortrait() {
- mQsPanel.onConfigurationChanged(getNewOrientationConfig(ORIENTATION_PORTRAIT))
- mQsPanel.switchSecurityFooter(false)
+ fun testCollapseActionCallsRunnable() {
+ val mockRunnable = mock(Runnable::class.java)
+ mQsPanel.setCollapseExpandAction(mockRunnable)
- mTestableLooper.runWithLooper {
- mQsPanel.isExpanded = true
- }
-
- // After mFooter
- assertThat(mQsPanel.indexOfChild(mQsPanel.mSecurityFooter)).isEqualTo(
- mQsPanel.indexOfChild(mFooter) + 1
- )
+ mQsPanel.performAccessibilityAction(AccessibilityNodeInfo.ACTION_COLLAPSE, null)
+ verify(mockRunnable).run()
}
-
- @Test
- fun testSecurityFooter_appearsOnTopIfSmallScreenAndLandscape() {
- mQsPanel.onConfigurationChanged(getNewOrientationConfig(ORIENTATION_LANDSCAPE))
- mQsPanel.switchSecurityFooter(false)
-
- mTestableLooper.runWithLooper {
- mQsPanel.isExpanded = true
- }
-
- // -1 means that it is part of the mHeaderContainer
- assertThat(mQsPanel.indexOfChild(mQsPanel.mSecurityFooter)).isEqualTo(-1)
- }
-
- private fun getNewOrientationConfig(@Configuration.Orientation newOrientation: Int) =
- context.resources.configuration.apply { orientation = newOrientation }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index 15013469c6f7..a3c353b5a666 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -30,8 +30,11 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.DialogInterface;
+import android.content.Intent;
import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.VectorDrawable;
@@ -44,6 +47,7 @@ import android.testing.LayoutInflaterBuilder;
import android.testing.TestableImageView;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import android.testing.ViewUtils;
import android.text.SpannableStringBuilder;
import android.view.LayoutInflater;
import android.view.View;
@@ -53,11 +57,12 @@ import android.widget.TextView;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator;
-import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.policy.SecurityController;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -104,7 +109,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
@Mock
private DialogLaunchAnimator mDialogLaunchAnimator;
@Mock
- private FeatureFlags mFeatureFlags;
+ private BroadcastDispatcher mBroadcastDispatcher;
private TestableLooper mTestableLooper;
@@ -119,7 +124,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
.build().inflate(R.layout.quick_settings_security_footer, null, false);
mFooter = new QSSecurityFooter(mRootView, mUserTracker, new Handler(looper),
mActivityStarter, mSecurityController, mDialogLaunchAnimator, looper,
- mFeatureFlags);
+ mBroadcastDispatcher);
mFooterText = mRootView.findViewById(R.id.footer_text);
mPrimaryFooterIcon = mRootView.findViewById(R.id.primary_footer_icon);
@@ -127,6 +132,14 @@ public class QSSecurityFooterTest extends SysuiTestCase {
.thenReturn(DEVICE_OWNER_COMPONENT);
when(mSecurityController.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
.thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
+ ViewUtils.attachView(mRootView);
+
+ mFooter.init();
+ }
+
+ @After
+ public void tearDown() {
+ ViewUtils.detachView(mRootView);
}
@Test
@@ -769,8 +782,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
@Test
public void testVisibilityListener() {
final AtomicInteger lastVisibility = new AtomicInteger(-1);
- VisibilityChangedDispatcher.OnVisibilityChangedListener listener =
- (VisibilityChangedDispatcher.OnVisibilityChangedListener) lastVisibility::set;
+ VisibilityChangedDispatcher.OnVisibilityChangedListener listener = lastVisibility::set;
mFooter.setOnVisibilityChangedListener(listener);
@@ -785,6 +797,28 @@ public class QSSecurityFooterTest extends SysuiTestCase {
assertEquals(View.GONE, lastVisibility.get());
}
+ @Test
+ public void testBroadcastShowsDialog() {
+ // Setup dialog content
+ when(mSecurityController.isDeviceManaged()).thenReturn(true);
+ when(mSecurityController.getDeviceOwnerOrganizationName())
+ .thenReturn(MANAGING_ORGANIZATION);
+ when(mSecurityController.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
+ .thenReturn(DEVICE_OWNER_TYPE_FINANCED);
+
+ ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mBroadcastDispatcher).registerReceiverWithHandler(captor.capture(), any(), any(),
+ any());
+
+ // Pretend view is not visible temporarily
+ mRootView.onVisibilityAggregated(false);
+ captor.getValue().onReceive(mContext,
+ new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG));
+ mTestableLooper.processAllMessages();
+
+ assertTrue(mFooter.getDialog().isShowing());
+ mFooter.getDialog().dismiss();
+ }
private CharSequence addLink(CharSequence description) {
final SpannableStringBuilder message = new SpannableStringBuilder();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt
new file mode 100644
index 000000000000..a6a584d2e622
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt
@@ -0,0 +1,62 @@
+package com.android.systemui.qs
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.ViewGroup
+import android.view.accessibility.AccessibilityNodeInfo
+import android.widget.FrameLayout
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+@SmallTest
+class QuickQSPanelTest : SysuiTestCase() {
+
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var quickQSPanel: QuickQSPanel
+
+ private lateinit var parentView: ViewGroup
+
+ @Before
+ @Throws(Exception::class)
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+
+ testableLooper.runWithLooper {
+ quickQSPanel = QuickQSPanel(mContext, null)
+ quickQSPanel.initialize()
+
+ quickQSPanel.onFinishInflate()
+ // Provides a parent with non-zero size for QSPanel
+ parentView = FrameLayout(mContext).apply {
+ addView(quickQSPanel)
+ }
+ }
+ }
+
+ @Test
+ fun testHasExpandAccessibilityAction() {
+ val info = AccessibilityNodeInfo(quickQSPanel)
+ quickQSPanel.onInitializeAccessibilityNodeInfo(info)
+
+ Truth.assertThat(info.actions and AccessibilityNodeInfo.ACTION_EXPAND).isNotEqualTo(0)
+ Truth.assertThat(info.actions and AccessibilityNodeInfo.ACTION_COLLAPSE).isEqualTo(0)
+ }
+
+ @Test
+ fun testExpandActionCallsRunnable() {
+ val mockRunnable = Mockito.mock(Runnable::class.java)
+ quickQSPanel.setCollapseExpandAction(mockRunnable)
+
+ quickQSPanel.performAccessibilityAction(AccessibilityNodeInfo.ACTION_EXPAND, null)
+ Mockito.verify(mockRunnable).run()
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
index bd4bfff4c18a..5abc0e1f9c89 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.test.suitebuilder.annotation.SmallTest;
+import android.view.accessibility.AccessibilityNodeInfo;
import androidx.test.runner.AndroidJUnit4;
@@ -170,4 +171,36 @@ public class TileLayoutTest extends SysuiTestCase {
mTileLayout.measure(mLayoutSizeForOneTile, mLayoutSizeForOneTile);
assertEquals(0, mTileLayout.getMeasuredHeight());
}
+
+ @Test
+ public void testCollectionInfo() {
+ QSPanelControllerBase.TileRecord tileRecord1 = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord2 = createTileRecord();
+ AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(mTileLayout);
+ mTileLayout.addTile(tileRecord1);
+
+ mTileLayout.onInitializeAccessibilityNodeInfo(info);
+ AccessibilityNodeInfo.CollectionInfo collectionInfo = info.getCollectionInfo();
+ assertEquals(1, collectionInfo.getRowCount());
+ assertEquals(1, collectionInfo.getColumnCount()); // always use one column
+
+ mTileLayout.addTile(tileRecord2);
+ mTileLayout.onInitializeAccessibilityNodeInfo(info);
+ collectionInfo = info.getCollectionInfo();
+ assertEquals(2, collectionInfo.getRowCount());
+ assertEquals(1, collectionInfo.getColumnCount()); // always use one column
+ }
+
+ @Test
+ public void testSetPositionOnTiles() {
+ QSPanelControllerBase.TileRecord tileRecord1 = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord2 = createTileRecord();
+ mTileLayout.addTile(tileRecord1);
+ mTileLayout.addTile(tileRecord2);
+ mTileLayout.measure(mLayoutSizeForOneTile * 2, mLayoutSizeForOneTile * 2);
+ mTileLayout.layout(0, 0, mLayoutSizeForOneTile * 2, mLayoutSizeForOneTile * 2);
+
+ verify(tileRecord1.tileView).setPosition(0);
+ verify(tileRecord2.tileView).setPosition(1);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
index a2b5013c8c2c..9fdc2fd60870 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
@@ -23,6 +23,7 @@ import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.text.TextUtils
import android.view.View
+import android.view.accessibility.AccessibilityNodeInfo
import android.widget.TextView
import androidx.test.filters.SmallTest
import com.android.systemui.R
@@ -257,6 +258,28 @@ class QSTileViewImplTest : SysuiTestCase() {
assertThat((tileView.secondaryLabel as TextView).text).isEqualTo(onString)
}
+ @Test
+ fun testCollectionItemInfoHasPosition() {
+ val position = 5
+ tileView.setPosition(position)
+
+ val info = AccessibilityNodeInfo(tileView)
+ tileView.onInitializeAccessibilityNodeInfo(info)
+
+ assertThat(info.collectionItemInfo.rowIndex).isEqualTo(position)
+ assertThat(info.collectionItemInfo.rowSpan).isEqualTo(1)
+ assertThat(info.collectionItemInfo.columnIndex).isEqualTo(0)
+ assertThat(info.collectionItemInfo.columnSpan).isEqualTo(1)
+ }
+
+ @Test
+ fun testCollectionItemInfoNoPosition() {
+ val info = AccessibilityNodeInfo(tileView)
+ tileView.onInitializeAccessibilityNodeInfo(info)
+
+ assertThat(info.collectionItemInfo).isNull()
+ }
+
class FakeTileView(
context: Context,
icon: QSIconView,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 11f76a381ad4..fc4d9c42eb49 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -475,9 +475,10 @@ public class CommandQueueTest extends SysuiTestCase {
@Test
public void testHideAuthenticationDialog() {
- mCommandQueue.hideAuthenticationDialog();
+ final long id = 4;
+ mCommandQueue.hideAuthenticationDialog(id);
waitForIdleSync();
- verify(mCallbacks).hideAuthenticationDialog();
+ verify(mCallbacks).hideAuthenticationDialog(eq(id));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index e2d6ae07fe70..562c97017862 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -93,24 +93,34 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
.addOverride(R.bool.config_use_split_notification_shade, false)
context.getOrCreateTestableResources()
.addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
- transitionController = LockscreenShadeTransitionController(
- statusBarStateController = statusbarStateController,
- logger = logger,
- keyguardBypassController = keyguardBypassController,
- lockScreenUserManager = lockScreenUserManager,
- falsingCollector = falsingCollector,
- ambientState = ambientState,
- mediaHierarchyManager = mediaHierarchyManager,
- scrimController = scrimController,
- depthController = depthController,
- wakefulnessLifecycle = wakefulnessLifecycle,
- context = context,
- configurationController = configurationController,
- falsingManager = falsingManager,
- dumpManager = dumpManager,
- splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
- singleShadeOverScrollerFactory = { singleShadeOverScroller }
- )
+ transitionController =
+ LockscreenShadeTransitionController(
+ statusBarStateController = statusbarStateController,
+ logger = logger,
+ keyguardBypassController = keyguardBypassController,
+ lockScreenUserManager = lockScreenUserManager,
+ falsingCollector = falsingCollector,
+ ambientState = ambientState,
+ mediaHierarchyManager = mediaHierarchyManager,
+ depthController = depthController,
+ wakefulnessLifecycle = wakefulnessLifecycle,
+ context = context,
+ configurationController = configurationController,
+ falsingManager = falsingManager,
+ dumpManager = dumpManager,
+ splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
+ singleShadeOverScrollerFactory = { singleShadeOverScroller },
+ scrimTransitionController =
+ LockscreenShadeScrimTransitionController(
+ scrimController, context, configurationController, dumpManager),
+ keyguardTransitionControllerFactory = { notificationPanelController ->
+ LockscreenShadeKeyguardTransitionController(
+ mediaHierarchyManager,
+ notificationPanelController,
+ context,
+ configurationController,
+ dumpManager)
+ })
whenever(nsslController.view).thenReturn(stackscroller)
whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
transitionController.notificationPanelController = notificationPanelController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
index 4e07d5924229..cf996073f6a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
@@ -192,7 +192,8 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase {
argThat(intentFilter -> intentFilter.hasAction(Intent.ACTION_USER_SWITCHED)),
isNull(),
isNull(),
- eq(Context.RECEIVER_EXPORTED));
+ eq(Context.RECEIVER_EXPORTED),
+ isNull());
BroadcastReceiver callback = callbackCaptor.getValue();
Consumer<String> listener = mock(Consumer.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 142c2c1ed017..d6a2f0f22e5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -113,6 +113,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
private SessionTracker mSessionTracker;
@Mock
private LatencyTracker mLatencyTracker;
+ @Mock
+ private ScreenOffAnimationController mScreenOffAnimationController;
private BiometricUnlockController mBiometricUnlockController;
@Before
@@ -127,7 +129,6 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
when(mAuthController.isUdfpsFingerDown()).thenReturn(false);
when(mKeyguardBypassController.canPlaySubtleWindowAnimations()).thenReturn(true);
mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager);
- res.addOverride(com.android.internal.R.integer.config_wakeUpDelayDoze, 0);
mBiometricUnlockController = new BiometricUnlockController(mDozeScrimController,
mKeyguardViewMediator, mScrimController, mShadeController,
mNotificationShadeWindowController, mKeyguardStateController, mHandler,
@@ -135,7 +136,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
mMetricsLogger, mDumpManager, mPowerManager,
mNotificationMediaManager, mWakefulnessLifecycle, mScreenLifecycle,
mAuthController, mStatusBarStateController, mKeyguardUnlockAnimationController,
- mSessionTracker, mLatencyTracker);
+ mSessionTracker, mLatencyTracker, mScreenOffAnimationController);
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
mBiometricUnlockController.setBiometricModeListener(mBiometricModeListener);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index 077b41a0aa90..5f2bbd341962 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -126,12 +126,6 @@ public class DozeParametersTest extends SysuiTestCase {
setAodEnabledForTest(true);
setShouldControlUnlockedScreenOffForTest(true);
setDisplayNeedsBlankingForTest(false);
-
- // Default to false here (with one test to make sure that when it returns true, we respect
- // that). We'll test the specific conditions for this to return true/false in the
- // UnlockedScreenOffAnimationController's tests.
- when(mUnlockedScreenOffAnimationController.shouldPlayUnlockedScreenOffAnimation())
- .thenReturn(false);
}
@Test
@@ -180,12 +174,9 @@ public class DozeParametersTest extends SysuiTestCase {
*/
@Test
public void testControlUnlockedScreenOffAnimation_dozeAfterScreenOff_false() {
- mDozeParameters.mKeyguardVisibilityCallback.onKeyguardVisibilityChanged(true);
-
// If AOD is disabled, we shouldn't want to control screen off. Also, let's double check
// that when that value is updated, we called through to PowerManager.
setAodEnabledForTest(false);
-
assertFalse(mDozeParameters.shouldControlScreenOff());
assertTrue(mPowerManagerDozeAfterScreenOff);
@@ -197,6 +188,7 @@ public class DozeParametersTest extends SysuiTestCase {
@Test
public void testControlUnlockedScreenOffAnimationDisabled_dozeAfterScreenOff() {
+ setShouldControlUnlockedScreenOffForTest(true);
when(mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)).thenReturn(false);
assertFalse(mDozeParameters.shouldControlUnlockedScreenOff());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index 22bf6c8324ae..7ef656c780a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -876,7 +876,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
public void testSwitchesToBigClockInSplitShadeOnAod() {
mStatusBarStateController.setState(KEYGUARD);
enableSplitShade(/* enabled= */ true);
- when(mMediaDataManager.hasActiveMedia()).thenReturn(true);
+ when(mMediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true);
when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(2);
clearInvocations(mKeyguardStatusViewController);
@@ -904,7 +904,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mStatusBarStateController.setState(KEYGUARD);
enableSplitShade(/* enabled= */ true);
clearInvocations(mKeyguardStatusViewController);
- when(mMediaDataManager.hasActiveMedia()).thenReturn(true);
+ when(mMediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true);
// one notification + media player visible
when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
index 05a21db310fc..e2fabbd1c270 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
@@ -13,7 +13,6 @@ import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener
import com.android.systemui.recents.OverviewProxyService
@@ -114,25 +113,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarVisibleInSplitShade() {
enableSplitShade()
- useNewFooter(false)
-
- given(taskbarVisible = true,
- navigationMode = GESTURES_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0, // taskbar should disappear when shade is expanded
- expectedNotificationsMargin = NOTIFICATIONS_MARGIN)
-
- given(taskbarVisible = true,
- navigationMode = BUTTONS_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = STABLE_INSET_BOTTOM,
- expectedNotificationsMargin = NOTIFICATIONS_MARGIN)
- }
-
- @Test
- fun testTaskbarVisibleInSplitShade_newFooter() {
- enableSplitShade()
- useNewFooter(true)
given(taskbarVisible = true,
navigationMode = GESTURES_NAVIGATION,
@@ -153,25 +133,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
fun testTaskbarNotVisibleInSplitShade() {
// when taskbar is not visible, it means we're on the home screen
enableSplitShade()
- useNewFooter(false)
-
- given(taskbarVisible = false,
- navigationMode = GESTURES_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0)
-
- given(taskbarVisible = false,
- navigationMode = BUTTONS_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0, // qs goes full height as it's not obscuring nav buttons
- expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN)
- }
-
- @Test
- fun testTaskbarNotVisibleInSplitShade_newFooter() {
- // when taskbar is not visible, it means we're on the home screen
- enableSplitShade()
- useNewFooter(true)
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
@@ -190,24 +151,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarNotVisibleInSplitShadeWithCutout() {
enableSplitShade()
- useNewFooter(false)
-
- given(taskbarVisible = false,
- navigationMode = GESTURES_NAVIGATION,
- insets = windowInsets().withCutout())
- then(expectedContainerPadding = CUTOUT_HEIGHT)
-
- given(taskbarVisible = false,
- navigationMode = BUTTONS_NAVIGATION,
- insets = windowInsets().withCutout().withStableBottom())
- then(expectedContainerPadding = 0,
- expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN)
- }
-
- @Test
- fun testTaskbarNotVisibleInSplitShadeWithCutout_newFooter() {
- enableSplitShade()
- useNewFooter(true)
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
@@ -226,23 +169,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarVisibleInSinglePaneShade() {
disableSplitShade()
- useNewFooter(false)
-
- given(taskbarVisible = true,
- navigationMode = GESTURES_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0)
-
- given(taskbarVisible = true,
- navigationMode = BUTTONS_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = STABLE_INSET_BOTTOM)
- }
-
- @Test
- fun testTaskbarVisibleInSinglePaneShade_newFooter() {
- disableSplitShade()
- useNewFooter(true)
given(taskbarVisible = true,
navigationMode = GESTURES_NAVIGATION,
@@ -260,28 +186,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarNotVisibleInSinglePaneShade() {
disableSplitShade()
- useNewFooter(false)
-
- given(taskbarVisible = false,
- navigationMode = GESTURES_NAVIGATION,
- insets = emptyInsets())
- then(expectedContainerPadding = 0)
-
- given(taskbarVisible = false,
- navigationMode = GESTURES_NAVIGATION,
- insets = windowInsets().withCutout().withStableBottom())
- then(expectedContainerPadding = CUTOUT_HEIGHT)
-
- given(taskbarVisible = false,
- navigationMode = BUTTONS_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0, expectedQsPadding = STABLE_INSET_BOTTOM)
- }
-
- @Test
- fun testTaskbarNotVisibleInSinglePaneShade_newFooter() {
- disableSplitShade()
- useNewFooter(true)
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
@@ -303,27 +207,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
fun testCustomizingInSinglePaneShade() {
disableSplitShade()
controller.setCustomizerShowing(true)
- useNewFooter(false)
-
- // always sets spacings to 0
- given(taskbarVisible = false,
- navigationMode = GESTURES_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0,
- expectedNotificationsMargin = 0)
-
- given(taskbarVisible = false,
- navigationMode = BUTTONS_NAVIGATION,
- insets = emptyInsets())
- then(expectedContainerPadding = 0,
- expectedNotificationsMargin = 0)
- }
-
- @Test
- fun testCustomizingInSinglePaneShade_newFooter() {
- disableSplitShade()
- controller.setCustomizerShowing(true)
- useNewFooter(true)
// always sets spacings to 0
given(taskbarVisible = false,
@@ -343,27 +226,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
fun testDetailShowingInSinglePaneShade() {
disableSplitShade()
controller.setDetailShowing(true)
- useNewFooter(false)
-
- // always sets spacings to 0
- given(taskbarVisible = false,
- navigationMode = GESTURES_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0,
- expectedNotificationsMargin = 0)
-
- given(taskbarVisible = false,
- navigationMode = BUTTONS_NAVIGATION,
- insets = emptyInsets())
- then(expectedContainerPadding = 0,
- expectedNotificationsMargin = 0)
- }
-
- @Test
- fun testDetailShowingInSinglePaneShade_newFooter() {
- disableSplitShade()
- controller.setDetailShowing(true)
- useNewFooter(true)
// always sets spacings to 0
given(taskbarVisible = false,
@@ -383,25 +245,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
fun testDetailShowingInSplitShade() {
enableSplitShade()
controller.setDetailShowing(true)
- useNewFooter(false)
-
- given(taskbarVisible = false,
- navigationMode = GESTURES_NAVIGATION,
- insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0)
-
- // should not influence spacing
- given(taskbarVisible = false,
- navigationMode = BUTTONS_NAVIGATION,
- insets = emptyInsets())
- then(expectedContainerPadding = 0)
- }
-
- @Test
- fun testDetailShowingInSplitShade_newFooter() {
- enableSplitShade()
- controller.setDetailShowing(true)
- useNewFooter(true)
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
@@ -531,7 +374,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testWindowInsetDebounce() {
disableSplitShade()
- useNewFooter(true)
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
@@ -596,13 +438,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
verify(notificationsQSContainer)
.setPadding(anyInt(), anyInt(), anyInt(), eq(expectedContainerPadding))
verify(notificationsQSContainer).setNotificationsMarginBottom(expectedNotificationsMargin)
- val newFooter = featureFlags.isEnabled(Flags.NEW_FOOTER)
- if (newFooter) {
- verify(notificationsQSContainer)
+ verify(notificationsQSContainer)
.setQSContainerPaddingBottom(expectedQsPadding)
- } else {
- verify(notificationsQSContainer).setQSScrollPaddingBottom(expectedQsPadding)
- }
Mockito.clearInvocations(notificationsQSContainer)
}
@@ -620,10 +457,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
return this
}
- private fun useNewFooter(useNewFooter: Boolean) {
- whenever(featureFlags.isEnabled(Flags.NEW_FOOTER)).thenReturn(useNewFooter)
- }
-
private fun getConstraintSetLayout(@IdRes id: Int): ConstraintSet.Layout {
return constraintSetCaptor.value.getConstraint(id).layout
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
index 79cbed80437c..ddccd834f76e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone;
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.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static com.google.common.truth.Truth.assertThat;
@@ -92,7 +93,12 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
mColorExtractor, mDumpManager, mKeyguardStateController,
- mScreenOffAnimationController, mAuthController);
+ mScreenOffAnimationController, mAuthController) {
+ @Override
+ protected boolean isDebuggable() {
+ return false;
+ }
+ };
mNotificationShadeWindowController.setScrimsVisibilityListener((visibility) -> {});
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
@@ -232,6 +238,22 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
}
@Test
+ public void setKeyguardShowing_enablesSecureFlag() {
+ mNotificationShadeWindowController.setBouncerShowing(true);
+
+ verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+ assertThat((mLayoutParameters.getValue().flags & FLAG_SECURE) != 0).isTrue();
+ }
+
+ @Test
+ public void setKeyguardNotShowing_disablesSecureFlag() {
+ mNotificationShadeWindowController.setBouncerShowing(false);
+
+ verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+ assertThat((mLayoutParameters.getValue().flags & FLAG_SECURE) == 0).isTrue();
+ }
+
+ @Test
public void rotationBecameAllowed_layoutParamsUpdated() {
mNotificationShadeWindowController.setKeyguardShowing(true);
when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index b3f8f9114021..509fa3b01b0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -49,9 +49,11 @@ import android.view.View;
import androidx.test.filters.SmallTest;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.DejankUtils;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.scrim.ScrimView;
@@ -1235,39 +1237,114 @@ public class ScrimControllerTest extends SysuiTestCase {
}
@Test
- public void testNotificationTransparency_followsPanelExpansionInShadeLockedState() {
+ public void expansionNotificationAlpha_shadeLocked_bouncerActive_usesBouncerInterpolator() {
when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(true);
mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0f, /* expansion */ 0.8f);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0f, /* expansion */ 0.2f);
+ float expansion = 0.8f;
+ float expectedAlpha =
+ BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, expectedAlpha, expansion);
+
+ expansion = 0.2f;
+ expectedAlpha = BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, expectedAlpha, expansion);
+ }
+
+ @Test
+ public void expansionNotificationAlpha_shadeLocked_bouncerNotActive_usesShadeInterpolator() {
+ when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(false);
+
+ mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
+
+ float expansion = 0.8f;
+ float expectedAlpha = ShadeInterpolation.getNotificationScrimAlpha(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, expectedAlpha, expansion);
+
+ expansion = 0.2f;
+ expectedAlpha = ShadeInterpolation.getNotificationScrimAlpha(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, expectedAlpha, expansion);
}
@Test
- public void testNotificationTransparency_unnocclusion() {
+ public void notificationAlpha_unnocclusionAnimating_bouncerActive_usesKeyguardNotifAlpha() {
when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(true);
mScrimController.transitionTo(ScrimState.KEYGUARD);
mScrimController.setUnocclusionAnimationRunning(true);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0f, /* expansion */ 0f);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0f, /* expansion */ 1.0f);
+ assertAlphaAfterExpansion(
+ mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 0f);
+ assertAlphaAfterExpansion(
+ mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 0.4f);
+ assertAlphaAfterExpansion(
+ mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 1.0f);
// Verify normal behavior after
mScrimController.setUnocclusionAnimationRunning(false);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 1f, /* expansion */ 0.4f);
+ float expansion = 0.4f;
+ float alpha = 1 - BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
}
@Test
- public void testNotificationTransparency_inKeyguardState() {
+ public void notificationAlpha_unnocclusionAnimating_bouncerNotActive_usesKeyguardNotifAlpha() {
+ when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(false);
+
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ mScrimController.setUnocclusionAnimationRunning(true);
+
+ assertAlphaAfterExpansion(
+ mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 0f);
+ assertAlphaAfterExpansion(
+ mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 0.4f);
+ assertAlphaAfterExpansion(
+ mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 1.0f);
+
+ // Verify normal behavior after
+ mScrimController.setUnocclusionAnimationRunning(false);
+ float expansion = 0.4f;
+ float alpha = 1 - ShadeInterpolation.getNotificationScrimAlpha(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
+ }
+
+ @Test
+ public void notificationAlpha_inKeyguardState_bouncerActive_usesInvertedBouncerInterpolator() {
when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(true);
mScrimController.transitionTo(ScrimState.KEYGUARD);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 1f, /* expansion */ 0.8f);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 1f, /* expansion */ 0.4f);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 1f, /* expansion */ 0.2f);
+ float expansion = 0.8f;
+ float alpha = 1 - BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
+
+ expansion = 0.4f;
+ alpha = 1 - BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
+
+ expansion = 0.2f;
+ alpha = 1 - BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
+ }
+
+ @Test
+ public void notificationAlpha_inKeyguardState_bouncerNotActive_usesInvertedShadeInterpolator() {
+ when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(false);
+
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+
+ float expansion = 0.8f;
+ float alpha = 1 - ShadeInterpolation.getNotificationScrimAlpha(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
+
+ expansion = 0.4f;
+ alpha = 1 - ShadeInterpolation.getNotificationScrimAlpha(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
+
+ expansion = 0.2f;
+ alpha = 1 - ShadeInterpolation.getNotificationScrimAlpha(expansion);
+ assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
}
@Test
@@ -1383,11 +1460,29 @@ public class ScrimControllerTest extends SysuiTestCase {
.isEqualTo(ScrimState.KEYGUARD.getBehindTint());
}
+ @Test
+ public void testHidesScrimFlickerInActivity() {
+ mScrimController.setKeyguardOccluded(true);
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ finishAnimationsImmediately();
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT));
+
+ mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
+ finishAnimationsImmediately();
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT));
+ }
+
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
mScrimController.setRawPanelExpansionFraction(expansion);
finishAnimationsImmediately();
// alpha is not changing linearly thus 0.2 of leeway when asserting
- assertEquals(expectedAlpha, mNotificationsScrim.getViewAlpha(), 0.2);
+ assertEquals(expectedAlpha, scrim.getViewAlpha(), 0.2);
}
private void assertScrimTinted(Map<ScrimView, Boolean> scrimToTint) {
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 0936b773d4b3..050563a5707c 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
@@ -31,7 +31,6 @@ import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.StatusBarStateControllerImpl
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.settings.GlobalSettings
-import junit.framework.Assert.assertFalse
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -134,7 +133,7 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
*/
@Test
fun testAodUiShownIfNotInteractive() {
- `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true)
+ `when`(dozeParameters.shouldControlUnlockedScreenOff()).thenReturn(true)
`when`(powerManager.isInteractive).thenReturn(false)
val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
@@ -157,7 +156,7 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
*/
@Test
fun testAodUiNotShownIfInteractive() {
- `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true)
+ `when`(dozeParameters.shouldControlUnlockedScreenOff()).thenReturn(true)
`when`(powerManager.isInteractive).thenReturn(true)
val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
@@ -168,13 +167,4 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
verify(notificationPanelViewController, never()).showAodUi()
}
-
- @Test
- fun testNoAnimationPlaying_dozeParamsCanNotControlScreenOff() {
- `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(false)
-
- assertFalse(controller.shouldPlayUnlockedScreenOffAnimation())
- controller.startAnimation()
- assertFalse(controller.isAnimationPlaying())
- }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
index 3a5d9ee16b0a..146b56e49e65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
@@ -5,22 +5,22 @@ import android.content.res.Configuration
/** Fake implementation of [ConfigurationController] for tests. */
class FakeConfigurationController : ConfigurationController {
- private var listener: ConfigurationController.ConfigurationListener? = null
+ private var listeners = mutableListOf<ConfigurationController.ConfigurationListener>()
override fun addCallback(listener: ConfigurationController.ConfigurationListener) {
- this.listener = listener
+ listeners += listener
}
override fun removeCallback(listener: ConfigurationController.ConfigurationListener) {
- this.listener = null
+ listeners -= listener
}
override fun onConfigurationChanged(newConfiguration: Configuration?) {
- listener?.onConfigChanged(newConfiguration)
+ listeners.forEach { it.onConfigChanged(newConfiguration) }
}
override fun notifyThemeChanged() {
- listener?.onThemeChanged()
+ listeners.forEach { it.onThemeChanged() }
}
fun notifyConfigurationChanged() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
index 1caacb89ba10..799dafcd01b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
@@ -97,6 +97,7 @@ class UserSwitcherControllerTest : SysuiTestCase() {
@Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
private lateinit var testableLooper: TestableLooper
private lateinit var bgExecutor: FakeExecutor
+ private lateinit var longRunningExecutor: FakeExecutor
private lateinit var uiExecutor: FakeExecutor
private lateinit var uiEventLogger: UiEventLoggerFake
private lateinit var userSwitcherController: UserSwitcherController
@@ -117,6 +118,7 @@ class UserSwitcherControllerTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
bgExecutor = FakeExecutor(FakeSystemClock())
+ longRunningExecutor = FakeExecutor(FakeSystemClock())
uiExecutor = FakeExecutor(FakeSystemClock())
uiEventLogger = UiEventLoggerFake()
@@ -167,6 +169,7 @@ class UserSwitcherControllerTest : SysuiTestCase() {
telephonyListenerManager,
secureSettings,
bgExecutor,
+ longRunningExecutor,
uiExecutor,
interactionJankMonitor,
latencyTracker,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt
index 1fb2aec6f06c..436f5b827ec6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt
@@ -88,14 +88,14 @@ class RingerModeLiveDataTest : SysuiTestCase() {
fun testOnActive_broadcastRegistered() {
liveData.observeForever(observer)
verify(broadcastDispatcher)
- .registerReceiver(any(), any(), eq(executor), eq(UserHandle.ALL), anyInt())
+ .registerReceiver(any(), any(), eq(executor), eq(UserHandle.ALL), anyInt(), any())
}
@Test
fun testOnActive_intentFilterHasIntent() {
liveData.observeForever(observer)
verify(broadcastDispatcher).registerReceiver(any(), capture(intentFilterCaptor), any(),
- any(), anyInt())
+ any(), anyInt(), any())
assertTrue(intentFilterCaptor.value.hasAction(INTENT))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
index 68027450045b..de2efc71b3a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
@@ -198,8 +198,7 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase {
}
@Test
- public void getQuickAccessUiIntent_hasCards_useTargetActivityFalse_startsWalletActivity() {
- when(mQuickAccessWalletClient.useTargetActivityForQuickAccess()).thenReturn(false);
+ public void getQuickAccessUiIntent_hasCards_noPendingIntent_startsWalletActivity() {
mController.startQuickAccessUiIntent(mActivityStarter, mAnimationController, true);
verify(mActivityStarter).startActivity(mIntentCaptor.capture(), eq(true),
any(ActivityLaunchAnimator.Controller.class), eq(true));
@@ -211,8 +210,7 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase {
}
@Test
- public void getQuickAccessUiIntent_noCards_useTargetActivityFalse_isWalletActivity() {
- when(mQuickAccessWalletClient.useTargetActivityForQuickAccess()).thenReturn(false);
+ public void getQuickAccessUiIntent_noCards_noPendingIntent_startsWalletActivity() {
mController.startQuickAccessUiIntent(mActivityStarter, mAnimationController, false);
verify(mActivityStarter).postStartActivityDismissingKeyguard(mIntentCaptor.capture(), eq(0),
any(ActivityLaunchAnimator.Controller.class));
@@ -236,7 +234,6 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase {
PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE));
return null;
}).when(mQuickAccessWalletClient).getWalletPendingIntent(any(), any());
- when(mQuickAccessWalletClient.useTargetActivityForQuickAccess()).thenReturn(true);
mController.startQuickAccessUiIntent(mActivityStarter, mAnimationController, true);
verify(mActivityStarter).postStartActivityDismissingKeyguard(mPendingIntentCaptor.capture(),
any(ActivityLaunchAnimator.Controller.class));
diff --git a/services/core/Android.bp b/services/core/Android.bp
index f1b81584f2a7..5406f711b73d 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -162,7 +162,6 @@ java_library_static {
"android.hardware.biometrics.fingerprint-V2-java",
"android.hardware.oemlock-V1.0-java",
"android.hardware.configstore-V1.1-java",
- "android.hardware.contexthub-V1.0-java",
"android.hardware.ir-V1-java",
"android.hardware.rebootescrow-V1-java",
"android.hardware.soundtrigger-V2.3-java",
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index e924012c8892..99e12a8f9f55 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -119,14 +119,13 @@ public class DynamicSystemService extends IDynamicSystemService.Stub {
@Override
@EnforcePermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
- public boolean createPartition(String name, long size, boolean readOnly)
- throws RemoteException {
+ public int createPartition(String name, long size, boolean readOnly) throws RemoteException {
IGsiService service = getGsiService();
- if (service.createPartition(name, size, readOnly) != 0) {
- Slog.i(TAG, "Failed to install " + name);
- return false;
+ int status = service.createPartition(name, size, readOnly);
+ if (status != IGsiService.INSTALL_OK) {
+ Slog.i(TAG, "Failed to create partition: " + name);
}
- return true;
+ return status;
}
@Override
diff --git a/services/core/java/com/android/server/EntropyMixer.java b/services/core/java/com/android/server/EntropyMixer.java
index a83c981235df..d08d90c31134 100644
--- a/services/core/java/com/android/server/EntropyMixer.java
+++ b/services/core/java/com/android/server/EntropyMixer.java
@@ -25,41 +25,63 @@ import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
+import android.util.AtomicFile;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
/**
- * A service designed to load and periodically save &quot;randomness&quot;
- * for the Linux kernel RNG.
- *
- * <p>When a Linux system starts up, the entropy pool associated with
- * {@code /dev/random} may be in a fairly predictable state. Applications which
- * depend strongly on randomness may find {@code /dev/random} or
- * {@code /dev/urandom} returning predictable data. In order to counteract
- * this effect, it's helpful to carry the entropy pool information across
- * shutdowns and startups.
+ * A service that loads and periodically saves &quot;randomness&quot; for the
+ * Linux kernel RNG.
*
- * <p>This class was modeled after the script in the
- * <a href="https://man7.org/linux/man-pages/man4/random.4.html">
- * random(4) manual page</a>.
+ * <p>When a Linux system starts up, the entropy pool associated with {@code
+ * /dev/urandom}, {@code /dev/random}, and {@code getrandom()} may be in a
+ * fairly predictable state, depending on the entropy sources available to the
+ * kernel. Applications that depend on randomness may find these APIs returning
+ * predictable data. To counteract this effect, this service maintains a seed
+ * file across shutdowns and startups, and also mixes some device and
+ * boot-specific information into the pool.
*/
public class EntropyMixer extends Binder {
private static final String TAG = "EntropyMixer";
- private static final int ENTROPY_WHAT = 1;
- private static final int ENTROPY_WRITE_PERIOD = 3 * 60 * 60 * 1000; // 3 hrs
+ private static final int UPDATE_SEED_MSG = 1;
+ private static final int SEED_UPDATE_PERIOD = 3 * 60 * 60 * 1000; // 3 hrs
private static final long START_TIME = System.currentTimeMillis();
private static final long START_NANOTIME = System.nanoTime();
- private final String randomDevice;
- private final String entropyFile;
+ /*
+ * The size of the seed file in bytes. This must be at least the size of a
+ * SHA-256 digest (32 bytes). It *should* also be at least the size of the
+ * kernel's entropy pool (/proc/sys/kernel/random/poolsize divided by 8),
+ * which historically was 512 bytes, but changed to 32 bytes in Linux v5.18.
+ * There's actually no real need for more than a 32-byte seed, even with
+ * older kernels; however, we take the conservative approach of staying with
+ * the 512-byte size for now, as the cost is very small.
+ */
+ @VisibleForTesting
+ static final int SEED_FILE_SIZE = 512;
+
+ @VisibleForTesting
+ static final String DEVICE_SPECIFIC_INFO_HEADER =
+ "Copyright (C) 2009 The Android Open Source Project\n" +
+ "All Your Randomness Are Belong To Us\n";
+
+ private final AtomicFile seedFile;
+ private final File randomReadDevice;
+ private final File randomWriteDevice; // separate from randomReadDevice only for testing
/**
- * Handler that periodically updates the entropy on disk.
+ * Handler that periodically updates the seed file.
*/
private final Handler mHandler = new Handler(IoThread.getHandler().getLooper()) {
// IMPLEMENTATION NOTE: This handler runs on the I/O thread to avoid I/O on the main thread.
@@ -67,40 +89,36 @@ public class EntropyMixer extends Binder {
// own ID space for the "what" parameter of messages seen by the handler.
@Override
public void handleMessage(Message msg) {
- if (msg.what != ENTROPY_WHAT) {
+ if (msg.what != UPDATE_SEED_MSG) {
Slog.e(TAG, "Will not process invalid message");
return;
}
- writeEntropy();
- scheduleEntropyWriter();
+ updateSeedFile();
+ scheduleSeedUpdater();
}
};
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- writeEntropy();
+ updateSeedFile();
}
};
public EntropyMixer(Context context) {
- this(context, getSystemDir() + "/entropy.dat", "/dev/urandom");
+ this(context, new File(getSystemDir(), "entropy.dat"),
+ new File("/dev/urandom"), new File("/dev/urandom"));
}
- /** Test only interface, not for public use */
- public EntropyMixer(
- Context context,
- String entropyFile,
- String randomDevice) {
- if (randomDevice == null) { throw new NullPointerException("randomDevice"); }
- if (entropyFile == null) { throw new NullPointerException("entropyFile"); }
+ @VisibleForTesting
+ EntropyMixer(Context context, File seedFile, File randomReadDevice, File randomWriteDevice) {
+ this.seedFile = new AtomicFile(Preconditions.checkNotNull(seedFile));
+ this.randomReadDevice = Preconditions.checkNotNull(randomReadDevice);
+ this.randomWriteDevice = Preconditions.checkNotNull(randomWriteDevice);
- this.randomDevice = randomDevice;
- this.entropyFile = entropyFile;
loadInitialEntropy();
- addDeviceSpecificEntropy();
- writeEntropy();
- scheduleEntropyWriter();
+ updateSeedFile();
+ scheduleSeedUpdater();
IntentFilter broadcastFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
broadcastFilter.addAction(Intent.ACTION_POWER_CONNECTED);
broadcastFilter.addAction(Intent.ACTION_REBOOT);
@@ -112,76 +130,147 @@ public class EntropyMixer extends Binder {
);
}
- private void scheduleEntropyWriter() {
- mHandler.removeMessages(ENTROPY_WHAT);
- mHandler.sendEmptyMessageDelayed(ENTROPY_WHAT, ENTROPY_WRITE_PERIOD);
+ private void scheduleSeedUpdater() {
+ mHandler.removeMessages(UPDATE_SEED_MSG);
+ mHandler.sendEmptyMessageDelayed(UPDATE_SEED_MSG, SEED_UPDATE_PERIOD);
}
private void loadInitialEntropy() {
- try {
- RandomBlock.fromFile(entropyFile).toFile(randomDevice, false);
- } catch (FileNotFoundException e) {
- Slog.w(TAG, "No existing entropy file -- first boot?");
+ byte[] seed = readSeedFile();
+ try (FileOutputStream out = new FileOutputStream(randomWriteDevice)) {
+ if (seed.length != 0) {
+ out.write(seed);
+ Slog.i(TAG, "Loaded existing seed file");
+ }
+ out.write(getDeviceSpecificInformation());
} catch (IOException e) {
- Slog.w(TAG, "Failure loading existing entropy file", e);
+ Slog.e(TAG, "Error writing to " + randomWriteDevice, e);
}
}
- private void writeEntropy() {
+ private byte[] readSeedFile() {
try {
- Slog.i(TAG, "Writing entropy...");
- RandomBlock.fromFile(randomDevice).toFile(entropyFile, true);
+ return seedFile.readFully();
+ } catch (FileNotFoundException e) {
+ return new byte[0];
} catch (IOException e) {
- Slog.w(TAG, "Unable to write entropy", e);
+ Slog.e(TAG, "Error reading " + seedFile.getBaseFile(), e);
+ return new byte[0];
}
}
/**
- * Add additional information to the kernel entropy pool. The
- * information isn't necessarily "random", but that's ok. Even
- * sending non-random information to {@code /dev/urandom} is useful
- * because, while it doesn't increase the "quality" of the entropy pool,
- * it mixes more bits into the pool, which gives us a higher degree
- * of uncertainty in the generated randomness. Like nature, writes to
- * the random device can only cause the quality of the entropy in the
- * kernel to stay the same or increase.
+ * Update (or create) the seed file.
+ *
+ * <p>Traditionally, the recommended way to update a seed file on Linux was
+ * to simply copy some bytes from /dev/urandom. However, that isn't
+ * actually a good way to do it, because writes to /dev/urandom aren't
+ * guaranteed to immediately affect reads from /dev/urandom. This can cause
+ * the new seed file to contain less entropy than the old one!
*
- * <p>For maximum effect, we try to target information which varies
- * on a per-device basis, and is not easily observable to an
- * attacker.
+ * <p>Instead, we generate the new seed by hashing the old seed together
+ * with some bytes from /dev/urandom, following the example of <a
+ * href="https://git.zx2c4.com/seedrng/tree/README.md">SeedRNG</a>. This
+ * ensures that the new seed is at least as entropic as the old seed.
*/
- private void addDeviceSpecificEntropy() {
- PrintWriter out = null;
+ private void updateSeedFile() {
+ byte[] oldSeed = readSeedFile();
+ byte[] newSeed = new byte[SEED_FILE_SIZE];
+
+ try (FileInputStream in = new FileInputStream(randomReadDevice)) {
+ if (in.read(newSeed) != newSeed.length) {
+ throw new IOException("unexpected EOF");
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Error reading " + randomReadDevice +
+ "; seed file won't be properly updated", e);
+ // Continue on; at least we'll have new timestamps...
+ }
+
+ // newSeed = newSeed[:-32] ||
+ // SHA-256(fixed_prefix || real_time || boot_time ||
+ // old_seed_len || old_seed || new_seed_len || new_seed)
+ MessageDigest sha256;
try {
- out = new PrintWriter(new FileOutputStream(randomDevice));
- out.println("Copyright (C) 2009 The Android Open Source Project");
- out.println("All Your Randomness Are Belong To Us");
- out.println(START_TIME);
- out.println(START_NANOTIME);
- out.println(SystemProperties.get("ro.serialno"));
- out.println(SystemProperties.get("ro.bootmode"));
- out.println(SystemProperties.get("ro.baseband"));
- out.println(SystemProperties.get("ro.carrier"));
- out.println(SystemProperties.get("ro.bootloader"));
- out.println(SystemProperties.get("ro.hardware"));
- out.println(SystemProperties.get("ro.revision"));
- out.println(SystemProperties.get("ro.build.fingerprint"));
- out.println(new Object().hashCode());
- out.println(System.currentTimeMillis());
- out.println(System.nanoTime());
+ sha256 = MessageDigest.getInstance("SHA-256");
+ } catch (NoSuchAlgorithmException e) {
+ Slog.wtf(TAG, "SHA-256 algorithm not found; seed file won't be updated", e);
+ return;
+ }
+ // This fixed prefix should be changed if the fields that are hashed change.
+ sha256.update("Android EntropyMixer v1".getBytes());
+ sha256.update(longToBytes(System.currentTimeMillis()));
+ sha256.update(longToBytes(System.nanoTime()));
+ sha256.update(longToBytes(oldSeed.length));
+ sha256.update(oldSeed);
+ sha256.update(longToBytes(newSeed.length));
+ sha256.update(newSeed);
+ byte[] digest = sha256.digest();
+ System.arraycopy(digest, 0, newSeed, newSeed.length - digest.length, digest.length);
+
+ writeNewSeed(newSeed);
+ if (oldSeed.length == 0) {
+ Slog.i(TAG, "Created seed file");
+ } else {
+ Slog.i(TAG, "Updated seed file");
+ }
+ }
+
+ private void writeNewSeed(byte[] newSeed) {
+ FileOutputStream out = null;
+ try {
+ out = seedFile.startWrite();
+ out.write(newSeed);
+ seedFile.finishWrite(out);
} catch (IOException e) {
- Slog.w(TAG, "Unable to add device specific data to the entropy pool", e);
- } finally {
- if (out != null) {
- out.close();
- }
+ Slog.e(TAG, "Error writing " + seedFile.getBaseFile(), e);
+ seedFile.failWrite(out);
}
}
- private static String getSystemDir() {
+ private static byte[] longToBytes(long x) {
+ ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
+ buffer.putLong(x);
+ return buffer.array();
+ }
+
+ /**
+ * Get some device and boot-specific information to mix into the kernel's
+ * entropy pool. This information probably won't contain much actual
+ * entropy, but that's fine because we don't ask the kernel to credit it.
+ * Writes to {@code /dev/urandom} can only increase or have no effect on the
+ * quality of random numbers, never decrease it.
+ *
+ * <p>The main goal here is just to initialize the entropy pool differently
+ * on devices that might otherwise be identical and have very little other
+ * entropy available. Therefore, we include various system properties that
+ * can vary on a per-device and/or per-build basis. We also include some
+ * timestamps, as these might vary on a per-boot basis and be not easily
+ * observable or guessable by an attacker.
+ */
+ private byte[] getDeviceSpecificInformation() {
+ StringBuilder b = new StringBuilder();
+ b.append(DEVICE_SPECIFIC_INFO_HEADER);
+ b.append(START_TIME).append('\n');
+ b.append(START_NANOTIME).append('\n');
+ b.append(SystemProperties.get("ro.serialno")).append('\n');
+ b.append(SystemProperties.get("ro.bootmode")).append('\n');
+ b.append(SystemProperties.get("ro.baseband")).append('\n');
+ b.append(SystemProperties.get("ro.carrier")).append('\n');
+ b.append(SystemProperties.get("ro.bootloader")).append('\n');
+ b.append(SystemProperties.get("ro.hardware")).append('\n');
+ b.append(SystemProperties.get("ro.revision")).append('\n');
+ b.append(SystemProperties.get("ro.build.fingerprint")).append('\n');
+ b.append(new Object().hashCode()).append('\n');
+ b.append(System.currentTimeMillis()).append('\n');
+ b.append(System.nanoTime()).append('\n');
+ return b.toString().getBytes();
+ }
+
+ private static File getSystemDir() {
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
- return systemDir.toString();
+ return systemDir;
}
}
diff --git a/services/core/java/com/android/server/RandomBlock.java b/services/core/java/com/android/server/RandomBlock.java
deleted file mode 100644
index 6d6d9010a8d9..000000000000
--- a/services/core/java/com/android/server/RandomBlock.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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;
-
-import android.util.Slog;
-
-import java.io.Closeable;
-import java.io.DataOutput;
-import java.io.EOFException;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-
-/**
- * A block of 512 random {@code byte}s.
- */
-class RandomBlock {
-
- private static final String TAG = "RandomBlock";
- private static final boolean DEBUG = false;
- private static final int BLOCK_SIZE = 512;
- private byte[] block = new byte[BLOCK_SIZE];
-
- private RandomBlock() { }
-
- static RandomBlock fromFile(String filename) throws IOException {
- if (DEBUG) Slog.v(TAG, "reading from file " + filename);
- InputStream stream = null;
- try {
- stream = new FileInputStream(filename);
- return fromStream(stream);
- } finally {
- close(stream);
- }
- }
-
- private static RandomBlock fromStream(InputStream in) throws IOException {
- RandomBlock retval = new RandomBlock();
- int total = 0;
- while(total < BLOCK_SIZE) {
- int result = in.read(retval.block, total, BLOCK_SIZE - total);
- if (result == -1) {
- throw new EOFException();
- }
- total += result;
- }
- return retval;
- }
-
- void toFile(String filename, boolean sync) throws IOException {
- if (DEBUG) Slog.v(TAG, "writing to file " + filename);
- RandomAccessFile out = null;
- try {
- out = new RandomAccessFile(filename, sync ? "rws" : "rw");
- toDataOut(out);
- truncateIfPossible(out);
- } finally {
- close(out);
- }
- }
-
- private static void truncateIfPossible(RandomAccessFile f) {
- try {
- f.setLength(BLOCK_SIZE);
- } catch (IOException e) {
- // ignore this exception. Sometimes, the file we're trying to
- // write is a character device, such as /dev/urandom, and
- // these character devices do not support setting the length.
- }
- }
-
- private void toDataOut(DataOutput out) throws IOException {
- out.write(block);
- }
-
- private static void close(Closeable c) {
- try {
- if (c == null) {
- return;
- }
- c.close();
- } catch (IOException e) {
- Slog.w(TAG, "IOException thrown while closing Closeable", e);
- }
- }
-}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 839cdc6eaca3..a67b858d7b63 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1036,12 +1036,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
callingFeatureId, callback, eventList, notifyNow, subId);
}
- private void listen(String callingPackage, @Nullable String callingFeatureId,
- IPhoneStateListener callback, Set<Integer> events, boolean notifyNow, int subId) {
- listen(false, false, callingPackage,
- callingFeatureId, callback, events, notifyNow, subId);
- }
-
private void listen(boolean renounceFineLocationAccess,
boolean renounceCoarseLocationAccess, String callingPackage,
@Nullable String callingFeatureId, IPhoneStateListener callback,
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 2f84ec5489fd..e68a0a6acaf6 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -38,6 +38,7 @@ import android.app.ActivityTaskManager;
import android.app.AlarmManager;
import android.app.IOnProjectionStateChangedListener;
import android.app.IUiModeManager;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -149,6 +150,8 @@ final class UiModeManagerService extends SystemService {
private int mCarModeEnableFlags;
private boolean mSetupWizardComplete;
+ // flag set by resource, whether to start dream immediately upon docking even if unlocked.
+ private boolean mStartDreamImmediatelyOnDock = true;
// flag set by resource, whether to enable Car dock launch when starting car mode.
private boolean mEnableCarDockLaunch = true;
// flag set by resource, whether to lock UI mode to the default one or not.
@@ -173,6 +176,7 @@ final class UiModeManagerService extends SystemService {
private ActivityTaskManagerInternal mActivityTaskManager;
private AlarmManager mAlarmManager;
private PowerManager mPowerManager;
+ private KeyguardManager mKeyguardManager;
// In automatic scheduling, the user is able
// to override the computed night mode until the two match
@@ -374,6 +378,7 @@ final class UiModeManagerService extends SystemService {
synchronized (mLock) {
final Context context = getContext();
mSystemReady = true;
+ mKeyguardManager = context.getSystemService(KeyguardManager.class);
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
mWindowManager = LocalServices.getService(WindowManagerInternal.class);
@@ -412,6 +417,8 @@ final class UiModeManagerService extends SystemService {
verifySetupWizardCompleted();
final Resources res = context.getResources();
+ mStartDreamImmediatelyOnDock = res.getBoolean(
+ com.android.internal.R.bool.config_startDreamImmediatelyOnDock);
mNightMode = res.getInteger(
com.android.internal.R.integer.config_defaultNightMode);
mDefaultUiModeType = res.getInteger(
@@ -1294,6 +1301,8 @@ final class UiModeManagerService extends SystemService {
pw.print(" mDockState="); pw.print(mDockState);
pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
+ pw.print(" mStartDreamImmediatelyOnDock="); pw.print(mStartDreamImmediatelyOnDock);
+
pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" (");
pw.print(Shell.nightModeToStr(mNightMode, mNightModeCustomType)); pw.print(") ");
pw.print(" mOverrideOn/Off="); pw.print(mOverrideNightModeOn);
@@ -1803,8 +1812,9 @@ final class UiModeManagerService extends SystemService {
// Send the new configuration.
applyConfigurationExternallyLocked();
- // If we did not start a dock app, then start dreaming if supported.
- if (category != null && !dockAppStarted) {
+ // If we did not start a dock app, then start dreaming if appropriate.
+ if (category != null && !dockAppStarted && (mStartDreamImmediatelyOnDock
+ || mKeyguardManager.isKeyguardLocked())) {
Sandman.startDreamWhenDockedIfAppropriate(getContext());
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index be0d79776069..07c281864c9c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -30,6 +30,7 @@ import static android.app.ActivityManager.INSTR_FLAG_DISABLE_ISOLATED_STORAGE;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS;
import static android.app.ActivityManager.INSTR_FLAG_NO_RESTART;
import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
@@ -207,7 +208,7 @@ import android.app.usage.UsageStatsManagerInternal;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetManagerInternal;
import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
+import android.compat.annotation.Disabled;
import android.content.AttributionSource;
import android.content.AutofillOptions;
import android.content.BroadcastReceiver;
@@ -460,14 +461,6 @@ public class ActivityManagerService extends IActivityManager.Stub
private static final String SYSTEM_PROPERTY_DEVICE_PROVISIONED =
"persist.sys.device_provisioned";
- /**
- * Enabling this flag enforces the requirement for context registered receivers to use one of
- * {@link Context#RECEIVER_EXPORTED} or {@link Context#RECEIVER_NOT_EXPORTED} for unprotected
- * broadcasts
- */
- private static final boolean ENFORCE_DYNAMIC_RECEIVER_EXPLICIT_EXPORT =
- SystemProperties.getBoolean("fw.enforce_dynamic_receiver_explicit_export", false);
-
static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
@@ -584,7 +577,7 @@ public class ActivityManagerService extends IActivityManager.Stub
* unprotected broadcast in code.
*/
@ChangeId
- @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+ @Disabled
private static final long DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED = 161145287L;
/**
@@ -1483,6 +1476,7 @@ public class ActivityManagerService extends IActivityManager.Stub
final ActivityThread mSystemThread;
final UidObserverController mUidObserverController;
+ private volatile IUidObserver mNetworkPolicyUidObserver;
final AppRestrictionController mAppRestrictionController;
@@ -13068,25 +13062,14 @@ public class ActivityManagerService extends IActivityManager.Stub
// sticky broadcast, no flag specified (flag isn't required)
flags |= Context.RECEIVER_EXPORTED;
} else if (requireExplicitFlagForDynamicReceivers && !explicitExportStateDefined) {
- if (ENFORCE_DYNAMIC_RECEIVER_EXPLICIT_EXPORT) {
- throw new SecurityException(
- callerPackage + ": Targeting T+ (version "
- + Build.VERSION_CODES.TIRAMISU
- + " and above) requires that one of RECEIVER_EXPORTED or "
- + "RECEIVER_NOT_EXPORTED be specified when registering a "
- + "receiver");
- } else {
- Slog.wtf(TAG,
- callerPackage + ": Targeting T+ (version "
- + Build.VERSION_CODES.TIRAMISU
- + " and above) requires that one of RECEIVER_EXPORTED or "
- + "RECEIVER_NOT_EXPORTED be specified when registering a "
- + "receiver");
- // Assume default behavior-- flag check is not enforced
- flags |= Context.RECEIVER_EXPORTED;
- }
- } else if (!requireExplicitFlagForDynamicReceivers) {
- // Change is not enabled, thus not targeting T+. Assume exported.
+ throw new SecurityException(
+ callerPackage + ": One of RECEIVER_EXPORTED or "
+ + "RECEIVER_NOT_EXPORTED should be specified when a receiver "
+ + "isn't being registered exclusively for system broadcasts");
+ // Assume default behavior-- flag check is not enforced
+ } else if (!requireExplicitFlagForDynamicReceivers && (
+ (flags & Context.RECEIVER_NOT_EXPORTED) == 0)) {
+ // Change is not enabled, assume exported unless otherwise specified.
flags |= Context.RECEIVER_EXPORTED;
}
} else if ((flags & Context.RECEIVER_NOT_EXPORTED) == 0) {
@@ -17232,17 +17215,17 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public boolean isUidCurrentlyInstrumented(int uid) {
+ public int getInstrumentationSourceUid(int uid) {
synchronized (mProcLock) {
for (int i = mActiveInstrumentation.size() - 1; i >= 0; i--) {
ActiveInstrumentation activeInst = mActiveInstrumentation.get(i);
if (!activeInst.mFinished && activeInst.mTargetInfo != null
&& activeInst.mTargetInfo.uid == uid) {
- return true;
+ return activeInst.mSourceUid;
}
}
}
- return false;
+ return INVALID_UID;
}
@Override
@@ -17300,6 +17283,19 @@ public class ActivityManagerService extends IActivityManager.Stub
if (isNewPending && mOomAdjuster != null) { // It can be null in unit test.
mOomAdjuster.mCachedAppOptimizer.unfreezeProcess(pid);
}
+ // We need to update the network rules for the app coming to the top state so that
+ // it can access network when the device or the app is in a restricted state
+ // (e.g. battery/data saver) but since waiting for updateOomAdj to complete and then
+ // informing NetworkPolicyManager might get delayed, informing the state change as soon
+ // as we know app is going to come to the top state.
+ if (mNetworkPolicyUidObserver != null) {
+ try {
+ mNetworkPolicyUidObserver.onUidStateChanged(uid, PROCESS_STATE_TOP,
+ mProcessList.getProcStateSeqCounter(), PROCESS_CAPABILITY_ALL);
+ } catch (RemoteException e) {
+ // Should not happen; call is within the same process
+ }
+ }
}
@Override
@@ -17497,6 +17493,14 @@ public class ActivityManagerService extends IActivityManager.Stub
public void restart() {
ActivityManagerService.this.restart();
}
+
+ @Override
+ public void registerNetworkPolicyUidObserver(@NonNull IUidObserver observer,
+ int which, int cutpoint, @NonNull String callingPackage) {
+ mNetworkPolicyUidObserver = observer;
+ mUidObserverController.register(observer, which, cutpoint, callingPackage,
+ Binder.getCallingUid());
+ }
}
long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
diff --git a/services/core/java/com/android/server/am/AnrHelper.java b/services/core/java/com/android/server/am/AnrHelper.java
index 1e1024e86314..e3544953e63d 100644
--- a/services/core/java/com/android/server/am/AnrHelper.java
+++ b/services/core/java/com/android/server/am/AnrHelper.java
@@ -79,6 +79,11 @@ class AnrHelper {
WindowProcessController parentProcess, boolean aboveSystem, String annotation) {
final int incomingPid = anrProcess.mPid;
synchronized (mAnrRecords) {
+ if (incomingPid == 0) {
+ // Extreme corner case such as zygote is no response to return pid for the process.
+ Slog.i(TAG, "Skip zero pid ANR, process=" + anrProcess.processName);
+ return;
+ }
if (mProcessingPid == incomingPid) {
Slog.i(TAG, "Skip duplicated ANR, pid=" + incomingPid + " " + annotation);
return;
diff --git a/services/core/java/com/android/server/am/AppBatteryExemptionTracker.java b/services/core/java/com/android/server/am/AppBatteryExemptionTracker.java
index 6f11b0001c7a..b07d9a6b258c 100644
--- a/services/core/java/com/android/server/am/AppBatteryExemptionTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryExemptionTracker.java
@@ -39,6 +39,7 @@ import com.android.server.am.AppBatteryExemptionTracker.UidBatteryStates;
import com.android.server.am.AppBatteryTracker.AppBatteryPolicy;
import com.android.server.am.AppBatteryTracker.BatteryUsage;
import com.android.server.am.AppBatteryTracker.ImmutableBatteryUsage;
+import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.am.BaseAppStateTimeEvents.BaseTimeEvent;
import com.android.server.am.BaseAppStateTracker.Injector;
import com.android.server.am.BaseAppStateTracker.StateListener;
@@ -85,6 +86,11 @@ final class AppBatteryExemptionTracker
}
@Override
+ @TrackerType int getType() {
+ return AppRestrictionController.TRACKER_TYPE_BATTERY_EXEMPTION;
+ }
+
+ @Override
void onSystemReady() {
super.onSystemReady();
mAppRestrictionController.forEachTracker(tracker -> {
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 0cbc7ad404f5..032b129c4256 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -55,6 +55,7 @@ import android.os.BatteryConsumer.Dimensions;
import android.os.BatteryStatsInternal;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
+import android.os.Build;
import android.os.PowerExemptionManager;
import android.os.PowerExemptionManager.ReasonCode;
import android.os.SystemClock;
@@ -62,6 +63,7 @@ import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.ArraySet;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -73,6 +75,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.am.AppBatteryTracker.AppBatteryPolicy;
+import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.am.AppRestrictionController.UidBatteryUsageProvider;
import com.android.server.pm.UserManagerInternal;
@@ -80,6 +83,7 @@ import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
/**
* The battery usage tracker for apps, currently we are focusing on background + FGS battery here.
@@ -90,6 +94,9 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
static final boolean DEBUG_BACKGROUND_BATTERY_TRACKER = false;
+ static final boolean DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE =
+ DEBUG_BACKGROUND_BATTERY_TRACKER | Build.IS_DEBUGGABLE;
+
// As we don't support realtime per-UID battery usage stats yet, we're polling the stats
// in a regular time basis.
private final long mBatteryUsageStatsPollingIntervalMs;
@@ -169,7 +176,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
private long mLastUidBatteryUsageStartTs;
// For debug only.
- private final SparseArray<BatteryUsage> mDebugUidPercentages = new SparseArray<>();
+ private final SparseArray<ImmutableBatteryUsage> mDebugUidPercentages = new SparseArray<>();
AppBatteryTracker(Context context, AppRestrictionController controller) {
this(context, controller, null, null);
@@ -195,6 +202,11 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
}
@Override
+ @TrackerType int getType() {
+ return AppRestrictionController.TRACKER_TYPE_BATTERY;
+ }
+
+ @Override
void onSystemReady() {
super.onSystemReady();
final UserManagerInternal um = mInjector.getUserManagerInternal();
@@ -331,10 +343,12 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
bgPolicy.mBgCurrentDrainExemptedTypes);
// It's possible the exemptedUsage could be larger than actualUsage,
// as the former one is an approximate value.
- final BatteryUsage bgUsage = actualUsage.mutate()
+ final ImmutableBatteryUsage bgUsage = actualUsage.mutate()
.subtract(exemptedUsage)
- .calcPercentage(uid, bgPolicy);
- if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
+ .calcPercentage(uid, bgPolicy)
+ .unmutate();
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE
+ && !BATTERY_USAGE_NONE.equals(actualUsage)) {
Slog.i(TAG, String.format(
"UID %d: %s (%s) | %s | %s over the past %s",
uid,
@@ -414,7 +428,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
}
}
- if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE) {
Slog.i(TAG, "updateBatteryUsageStatsOnce");
}
@@ -471,14 +485,17 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
final BatteryUsage lastUsage = mLastUidBatteryUsage.get(uid, BATTERY_USAGE_NONE);
final BatteryUsage curUsage = buf.valueAt(i);
final BatteryUsage before;
+ final BatteryUsage totalUsage;
if (index >= 0) {
- before = mUidBatteryUsage.valueAt(index);
- before.subtract(lastUsage).add(curUsage);
+ totalUsage = mUidBatteryUsage.valueAt(index);
+ before = DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE
+ ? new BatteryUsage(totalUsage) : BATTERY_USAGE_NONE;
+ totalUsage.subtract(lastUsage).add(curUsage);
} else {
- before = BATTERY_USAGE_NONE;
+ before = totalUsage = BATTERY_USAGE_NONE;
mUidBatteryUsage.put(uid, curUsage);
}
- if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE) {
final BatteryUsage actualDelta = new BatteryUsage(curUsage).subtract(lastUsage);
String msg = "Updating mUidBatteryUsage uid=" + uid + ", before=" + before
+ ", after=" + mUidBatteryUsage.get(uid, BATTERY_USAGE_NONE)
@@ -490,7 +507,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
if (!actualDelta.isValid()) {
// Something is wrong, the battery usage shouldn't be negative.
Slog.e(TAG, msg);
- } else {
+ } else if (!BATTERY_USAGE_NONE.equals(actualDelta)) {
Slog.i(TAG, msg);
}
}
@@ -513,11 +530,16 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
copyUidBatteryUsage(buf, mUidBatteryUsageInWindow);
}
}
- if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE) {
synchronized (mLock) {
for (int i = 0, size = mUidBatteryUsageInWindow.size(); i < size; i++) {
+ final ImmutableBatteryUsage usage = mUidBatteryUsageInWindow.valueAt(i);
+ if (BATTERY_USAGE_NONE.equals(usage)) {
+ // Skip the logging to avoid spamming.
+ continue;
+ }
Slog.i(TAG, "mUidBatteryUsageInWindow uid=" + mUidBatteryUsageInWindow.keyAt(i)
- + " usage=" + mUidBatteryUsageInWindow.valueAt(i));
+ + " usage=" + usage);
}
}
}
@@ -546,7 +568,19 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
for (UidBatteryConsumer uidConsumer : uidConsumers) {
// TODO: b/200326767 - as we are not supporting per proc state attribution yet,
// we couldn't distinguish between a real FGS vs. a bound FGS proc state.
- final int uid = uidConsumer.getUid();
+ final int rawUid = uidConsumer.getUid();
+ if (UserHandle.isIsolated(rawUid)) {
+ // Isolated processes should have been attributed to their parent processes.
+ continue;
+ }
+ int uid = rawUid;
+ // Keep the logic in sync with BatteryAppListPreferenceController.java
+ // Check if this UID is a shared GID. If so, we combine it with the OWNER's
+ // actual app UID.
+ final int sharedAppId = UserHandle.getAppIdFromSharedAppGid(uid);
+ if (sharedAppId > 0) {
+ uid = UserHandle.getUid(UserHandle.USER_SYSTEM, sharedAppId);
+ }
final BatteryUsage bgUsage = new BatteryUsage(uidConsumer, bgPolicy)
.scale(scale);
int index = buf.indexOfKey(uid);
@@ -556,9 +590,13 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
final BatteryUsage before = buf.valueAt(index);
before.add(bgUsage);
}
- if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
- Slog.i(TAG, "updateBatteryUsageStatsOnceInternal uid=" + uid
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE
+ && !BATTERY_USAGE_NONE.equals(bgUsage)) {
+ Slog.i(TAG, "updateBatteryUsageStatsOnceInternal uid=" + rawUid
+ ", bgUsage=" + bgUsage
+ + (rawUid == uid ? ""
+ : ", realUid=" + uid
+ + ", realUsage=" + buf.get(uid))
+ ", start=" + start
+ ", end=" + end);
}
@@ -610,7 +648,8 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
void setDebugUidPercentage(int[] uids, double[][] percentages) {
mDebugUidPercentages.clear();
for (int i = 0; i < uids.length; i++) {
- mDebugUidPercentages.put(uids[i], new BatteryUsage().setPercentage(percentages[i]));
+ mDebugUidPercentages.put(uids[i],
+ new BatteryUsage().setPercentage(percentages[i]).unmutate());
}
scheduleBgBatteryUsageStatsCheck();
}
@@ -636,7 +675,20 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
void dump(PrintWriter pw, String prefix) {
pw.print(prefix);
pw.println("APP BATTERY STATE TRACKER:");
+ // Force an update.
updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+ // Force a check.
+ scheduleBgBatteryUsageStatsCheck();
+ // Wait for its completion (as it runs in handler thread for the sake of thread safe)
+ final CountDownLatch latch = new CountDownLatch(1);
+ mBgHandler.getLooper().getQueue().addIdleHandler(() -> {
+ latch.countDown();
+ return false;
+ });
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ }
synchronized (mLock) {
final SparseArray<ImmutableBatteryUsage> uidConsumers = mUidBatteryUsageInWindow;
pw.print(" " + prefix);
@@ -708,6 +760,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
final double foregroundUsage = usage.getUsagePowerMah(PROCESS_STATE_FOREGROUND);
final double backgroundUsage = usage.getUsagePowerMah(PROCESS_STATE_BACKGROUND);
final double fgsUsage = usage.getUsagePowerMah(PROCESS_STATE_FOREGROUND_SERVICE);
+ final double cachedUsage = usage.getUsagePowerMah(PROCESS_STATE_CACHED);
if (foregroundUsage == 0 && backgroundUsage == 0 && fgsUsage == 0) {
return;
@@ -724,6 +777,9 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
dumpProcessStateStats(proto,
AppBatteryStatsProto.UidStats.ProcessStateStats.FOREGROUND_SERVICE,
fgsUsage);
+ dumpProcessStateStats(proto,
+ AppBatteryStatsProto.UidStats.ProcessStateStats.CACHED,
+ cachedUsage);
proto.end(token);
}
@@ -801,8 +857,12 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
}
private BatteryUsage setToInternal(@NonNull BatteryUsage other) {
- for (int i = 0; i < other.mUsage.length; i++) {
- mUsage[i] = other.mUsage[i];
+ System.arraycopy(other.mUsage, 0, mUsage, 0, other.mUsage.length);
+ if (other.mPercentage != null) {
+ mPercentage = new double[other.mPercentage.length];
+ System.arraycopy(other.mPercentage, 0, mPercentage, 0, other.mPercentage.length);
+ } else {
+ mPercentage = null;
}
return this;
}
@@ -864,9 +924,14 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
double getUsagePowerMah(@BatteryConsumer.ProcessState int processState) {
switch (processState) {
- case PROCESS_STATE_FOREGROUND: return mUsage[1];
- case PROCESS_STATE_BACKGROUND: return mUsage[2];
- case PROCESS_STATE_FOREGROUND_SERVICE: return mUsage[3];
+ case PROCESS_STATE_FOREGROUND:
+ return mUsage[BATTERY_USAGE_INDEX_FOREGROUND];
+ case PROCESS_STATE_BACKGROUND:
+ return mUsage[BATTERY_USAGE_INDEX_BACKGROUND];
+ case PROCESS_STATE_FOREGROUND_SERVICE:
+ return mUsage[BATTERY_USAGE_INDEX_FOREGROUND_SERVICE];
+ case PROCESS_STATE_CACHED:
+ return mUsage[BATTERY_USAGE_INDEX_CACHED];
}
return 0;
}
@@ -1282,11 +1347,12 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
/**
* List of the packages with significant background battery usage, key is the UID of
- * the package and value is an array of the timestamps when the UID is found guilty and
- * should be moved to the next level of restriction.
+ * the package and value is the pair of {timestamp[], battery usage snapshot[]}
+ * when the UID is found guilty and should be moved to the next level of restriction.
*/
@GuardedBy("mLock")
- private final SparseArray<long[]> mHighBgBatteryPackages = new SparseArray<>();
+ private final SparseArray<Pair<long[], ImmutableBatteryUsage[]>> mHighBgBatteryPackages =
+ new SparseArray<>();
@NonNull
private final Object mLock;
@@ -1516,8 +1582,9 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
return RESTRICTION_LEVEL_UNKNOWN;
}
synchronized (mLock) {
- final long[] ts = mHighBgBatteryPackages.get(uid);
- if (ts != null) {
+ final Pair<long[], ImmutableBatteryUsage[]> pair = mHighBgBatteryPackages.get(uid);
+ if (pair != null) {
+ final long[] ts = pair.first;
final int restrictedLevel = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] > 0
? RESTRICTION_LEVEL_RESTRICTED_BUCKET
: RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
@@ -1586,10 +1653,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
return sb.toString();
}
- void handleUidBatteryUsage(final int uid, final BatteryUsage usage) {
+ void handleUidBatteryUsage(final int uid, final ImmutableBatteryUsage usage) {
final @ReasonCode int reason = shouldExemptUid(uid);
if (reason != REASON_DENIED) {
- if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE && !BATTERY_USAGE_NONE.equals(usage)) {
Slog.i(TAG, "Exempting battery usage in " + UserHandle.formatUid(uid)
+ " " + PowerExemptionManager.reasonCodeToString(reason));
}
@@ -1597,6 +1664,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
}
boolean notifyController = false;
boolean excessive = false;
+ int index = 0;
final double rbPercentage = sumPercentageOfTypes(usage.getPercentage(),
mBgCurrentDrainRestrictedBucketTypes);
final double brPercentage = sumPercentageOfTypes(usage.getPercentage(),
@@ -1610,33 +1678,41 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
final long now = SystemClock.elapsedRealtime();
final int thresholdIndex = getCurrentDrainThresholdIndex(uid, now,
mBgCurrentDrainWindowMs);
- final int index = mHighBgBatteryPackages.indexOfKey(uid);
+ index = mHighBgBatteryPackages.indexOfKey(uid);
final boolean decoupleThresholds = mBgCurrentDrainDecoupleThresholds;
final double rbThreshold = mBgCurrentDrainRestrictedBucketThreshold[thresholdIndex];
final double brThreshold = mBgCurrentDrainBgRestrictedThreshold[thresholdIndex];
if (index < 0) {
long[] ts = null;
+ ImmutableBatteryUsage[] usages = null;
if (rbPercentage >= rbThreshold) {
// New findings to us, track it and let the controller know.
ts = new long[TIME_STAMP_INDEX_LAST];
ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now;
- mHighBgBatteryPackages.put(uid, ts);
+ usages = new ImmutableBatteryUsage[TIME_STAMP_INDEX_LAST];
+ usages[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage;
+ mHighBgBatteryPackages.put(uid, Pair.create(ts, usages));
notifyController = excessive = true;
}
if (decoupleThresholds && brPercentage >= brThreshold) {
if (ts == null) {
ts = new long[TIME_STAMP_INDEX_LAST];
- mHighBgBatteryPackages.put(uid, ts);
+ usages = new ImmutableBatteryUsage[TIME_STAMP_INDEX_LAST];
+ mHighBgBatteryPackages.put(uid, Pair.create(ts, usages));
}
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = now;
+ usages[TIME_STAMP_INDEX_BG_RESTRICTED] = usage;
notifyController = excessive = true;
}
} else {
- final long[] ts = mHighBgBatteryPackages.valueAt(index);
+ final Pair<long[], ImmutableBatteryUsage[]> pair =
+ mHighBgBatteryPackages.valueAt(index);
+ final long[] ts = pair.first;
final long lastRestrictBucketTs = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET];
if (rbPercentage >= rbThreshold) {
if (lastRestrictBucketTs == 0) {
ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now;
+ pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage;
}
notifyController = excessive = true;
} else {
@@ -1655,6 +1731,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
&& (now > lastRestrictBucketTs + mBgCurrentDrainWindowMs));
if (notifyController) {
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = now;
+ pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage;
}
excessive = true;
} else {
@@ -1662,13 +1739,14 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
// user consent to unrestrict it; or if it's in restricted bucket level,
// resetting this won't lift it from that level.
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = 0;
+ pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = null;
// Now need to notify the controller.
}
}
}
if (excessive) {
- if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE) {
Slog.i(TAG, "Excessive background current drain " + uid + " "
+ usage + " (" + usage.percentageToString() + " ) over "
+ TimeUtils.formatDuration(mBgCurrentDrainWindowMs));
@@ -1679,7 +1757,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE, true);
}
} else {
- if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE && index >= 0) {
Slog.i(TAG, "Background current drain backs to normal " + uid + " "
+ usage + " (" + usage.percentageToString() + " ) over "
+ TimeUtils.formatDuration(mBgCurrentDrainWindowMs));
@@ -1749,9 +1827,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
synchronized (mLock) {
// User has explicitly removed it from background restricted level,
// clear the timestamp of the background-restricted
- final long[] ts = mHighBgBatteryPackages.get(uid);
- if (ts != null) {
- ts[TIME_STAMP_INDEX_BG_RESTRICTED] = 0;
+ final Pair<long[], ImmutableBatteryUsage[]> pair = mHighBgBatteryPackages.get(uid);
+ if (pair != null) {
+ pair.first[TIME_STAMP_INDEX_BG_RESTRICTED] = 0;
+ pair.second[TIME_STAMP_INDEX_BG_RESTRICTED] = null;
}
}
}
@@ -1826,6 +1905,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
pw.print(KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_BY_BG_LOCATION);
pw.print('=');
pw.println(mBgCurrentDrainHighThresholdByBgLocation);
+ pw.print(prefix);
+ pw.print("Full charge capacity=");
+ pw.print(mBatteryFullChargeMah);
+ pw.println(" mAh");
pw.print(prefix);
pw.println("Excessive current drain detected:");
@@ -1836,18 +1919,24 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
final long now = SystemClock.elapsedRealtime();
for (int i = 0; i < size; i++) {
final int uid = mHighBgBatteryPackages.keyAt(i);
- final long[] ts = mHighBgBatteryPackages.valueAt(i);
+ final Pair<long[], ImmutableBatteryUsage[]> pair =
+ mHighBgBatteryPackages.valueAt(i);
+ final long[] ts = pair.first;
+ final ImmutableBatteryUsage[] usages = pair.second;
final int thresholdIndex = getCurrentDrainThresholdIndex(uid, now,
mBgCurrentDrainWindowMs);
- pw.format("%s%s: (threshold=%4.2f%%/%4.2f%%) %s/%s\n",
+ pw.format("%s%s: (threshold=%4.2f%%/%4.2f%%) %s / %s\n",
prefix,
UserHandle.formatUid(uid),
mBgCurrentDrainRestrictedBucketThreshold[thresholdIndex],
mBgCurrentDrainBgRestrictedThreshold[thresholdIndex],
- ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] == 0 ? "0"
- : formatTime(ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET], now),
- ts[TIME_STAMP_INDEX_BG_RESTRICTED] == 0 ? "0"
- : formatTime(ts[TIME_STAMP_INDEX_BG_RESTRICTED], now));
+ formatHighBgBatteryRecord(
+ ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET], now,
+ usages[TIME_STAMP_INDEX_RESTRICTED_BUCKET]),
+ formatHighBgBatteryRecord(
+ ts[TIME_STAMP_INDEX_BG_RESTRICTED], now,
+ usages[TIME_STAMP_INDEX_BG_RESTRICTED])
+ );
}
} else {
pw.print(prefix);
@@ -1856,5 +1945,14 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
}
}
}
+
+ private String formatHighBgBatteryRecord(long ts, long now, ImmutableBatteryUsage usage) {
+ if (ts > 0 && usage != null) {
+ return String.format("%s %s (%s)",
+ formatTime(ts, now), usage.toString(), usage.percentageToString());
+ } else {
+ return "0";
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java b/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
index 9e3cae63278c..9bed077785f5 100644
--- a/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
+++ b/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
@@ -26,6 +26,7 @@ import android.app.ActivityManagerInternal.BindServiceEventListener;
import android.content.Context;
import com.android.server.am.AppBindServiceEventsTracker.AppBindServiceEventsPolicy;
+import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.am.BaseAppStateTimeSlotEventsTracker.SimpleAppStateTimeslotEvents;
import com.android.server.am.BaseAppStateTracker.Injector;
@@ -59,6 +60,11 @@ final class AppBindServiceEventsTracker extends BaseAppStateTimeSlotEventsTracke
}
@Override
+ @TrackerType int getType() {
+ return AppRestrictionController.TRACKER_TYPE_BIND_SERVICE_EVENTS;
+ }
+
+ @Override
void onSystemReady() {
super.onSystemReady();
mInjector.getActivityManagerInternal().addBindServiceEventListener(this);
diff --git a/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java b/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
index cafae40613a2..a9155a115389 100644
--- a/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
+++ b/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
@@ -26,6 +26,7 @@ import android.app.ActivityManagerInternal.BroadcastEventListener;
import android.content.Context;
import com.android.server.am.AppBroadcastEventsTracker.AppBroadcastEventsPolicy;
+import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.am.BaseAppStateTimeSlotEventsTracker.SimpleAppStateTimeslotEvents;
import com.android.server.am.BaseAppStateTracker.Injector;
@@ -58,6 +59,11 @@ final class AppBroadcastEventsTracker extends BaseAppStateTimeSlotEventsTracker
}
@Override
+ @TrackerType int getType() {
+ return AppRestrictionController.TRACKER_TYPE_BROADCAST_EVENTS;
+ }
+
+ @Override
void onSystemReady() {
super.onSystemReady();
mInjector.getActivityManagerInternal().addBroadcastEventListener(this);
diff --git a/services/core/java/com/android/server/am/AppFGSTracker.java b/services/core/java/com/android/server/am/AppFGSTracker.java
index 246725e03ba6..ddd27647c970 100644
--- a/services/core/java/com/android/server/am/AppFGSTracker.java
+++ b/services/core/java/com/android/server/am/AppFGSTracker.java
@@ -52,8 +52,10 @@ import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.SomeArgs;
import com.android.server.am.AppFGSTracker.AppFGSPolicy;
import com.android.server.am.AppFGSTracker.PackageDurations;
+import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.am.BaseAppStateEventsTracker.BaseAppStateEventsPolicy;
import com.android.server.am.BaseAppStateTimeEvents.BaseTimeEvent;
import com.android.server.am.BaseAppStateTracker.Injector;
@@ -111,9 +113,14 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac
@Override
public void onForegroundServiceNotificationUpdated(String packageName, int uid,
- int foregroundId) {
- mHandler.obtainMessage(MyHandler.MSG_FOREGROUND_SERVICES_NOTIFICATION_UPDATED,
- uid, foregroundId, packageName).sendToTarget();
+ int foregroundId, boolean canceling) {
+ final SomeArgs args = SomeArgs.obtain();
+ args.argi1 = uid;
+ args.argi2 = foregroundId;
+ args.arg1 = packageName;
+ args.arg2 = canceling ? Boolean.TRUE : Boolean.FALSE;
+ mHandler.obtainMessage(MyHandler.MSG_FOREGROUND_SERVICES_NOTIFICATION_UPDATED, args)
+ .sendToTarget();
}
private static class MyHandler extends Handler {
@@ -148,8 +155,10 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac
(String) msg.obj, msg.arg1, msg.arg2);
break;
case MSG_FOREGROUND_SERVICES_NOTIFICATION_UPDATED:
+ final SomeArgs args = (SomeArgs) msg.obj;
mTracker.handleForegroundServiceNotificationUpdated(
- (String) msg.obj, msg.arg1, msg.arg2);
+ (String) args.arg1, args.argi1, args.argi2, (Boolean) args.arg2);
+ args.recycle();
break;
case MSG_CHECK_LONG_RUNNING_FGS:
mTracker.checkLongRunningFgs();
@@ -176,6 +185,11 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac
}
@Override
+ @TrackerType int getType() {
+ return AppRestrictionController.TRACKER_TYPE_FGS;
+ }
+
+ @Override
void onSystemReady() {
super.onSystemReady();
mInjector.getActivityManagerInternal().addForegroundServiceStateListener(this);
@@ -235,18 +249,18 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac
}
private void handleForegroundServiceNotificationUpdated(String packageName, int uid,
- int notificationId) {
+ int notificationId, boolean canceling) {
synchronized (mLock) {
SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, packageName);
- if (notificationId > 0) {
+ if (!canceling) {
if (notificationIDs == null) {
notificationIDs = new SparseBooleanArray();
mFGSNotificationIDs.put(uid, packageName, notificationIDs);
}
notificationIDs.put(notificationId, false);
- } else if (notificationId < 0) {
+ } else {
if (notificationIDs != null) {
- final int indexOfKey = notificationIDs.indexOfKey(-notificationId);
+ final int indexOfKey = notificationIDs.indexOfKey(notificationId);
if (indexOfKey >= 0) {
final boolean wasVisible = notificationIDs.valueAt(indexOfKey);
notificationIDs.removeAt(indexOfKey);
diff --git a/services/core/java/com/android/server/am/AppMediaSessionTracker.java b/services/core/java/com/android/server/am/AppMediaSessionTracker.java
index 4ce23f7c02fb..7daa93ed8a0d 100644
--- a/services/core/java/com/android/server/am/AppMediaSessionTracker.java
+++ b/services/core/java/com/android/server/am/AppMediaSessionTracker.java
@@ -36,6 +36,7 @@ import android.util.SparseArray;
import com.android.internal.app.ProcessMap;
import com.android.server.am.AppMediaSessionTracker.AppMediaSessionPolicy;
+import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.am.BaseAppStateDurationsTracker.SimplePackageDurations;
import com.android.server.am.BaseAppStateEventsTracker.BaseAppStateEventsPolicy;
@@ -161,6 +162,11 @@ final class AppMediaSessionTracker
}
@Override
+ @TrackerType int getType() {
+ return AppRestrictionController.TRACKER_TYPE_MEDIA_SESSION;
+ }
+
+ @Override
void dump(PrintWriter pw, String prefix) {
pw.print(prefix);
pw.println("APP MEDIA SESSION TRACKER:");
diff --git a/services/core/java/com/android/server/am/AppPermissionTracker.java b/services/core/java/com/android/server/am/AppPermissionTracker.java
index 622d7465d4bf..722d0d4faf15 100644
--- a/services/core/java/com/android/server/am/AppPermissionTracker.java
+++ b/services/core/java/com/android/server/am/AppPermissionTracker.java
@@ -58,6 +58,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
import com.android.server.am.AppPermissionTracker.AppPermissionPolicy;
+import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import java.io.PrintWriter;
@@ -104,6 +105,11 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy
}
@Override
+ @TrackerType int getType() {
+ return AppRestrictionController.TRACKER_TYPE_PERMISSION;
+ }
+
+ @Override
public void onPermissionsChanged(int uid) {
mHandler.obtainMessage(MyHandler.MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
}
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index de94929fbafc..6f7435943d45 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -27,6 +27,7 @@ import static android.app.ActivityManager.RESTRICTION_LEVEL_HIBERNATION;
import static android.app.ActivityManager.RESTRICTION_LEVEL_MAX;
import static android.app.ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET;
import static android.app.ActivityManager.RESTRICTION_LEVEL_UNKNOWN;
+import static android.app.ActivityManager.RESTRICTION_LEVEL_UNRESTRICTED;
import static android.app.ActivityManager.UID_OBSERVER_ACTIVE;
import static android.app.ActivityManager.UID_OBSERVER_GONE;
import static android.app.ActivityManager.UID_OBSERVER_IDLE;
@@ -70,6 +71,7 @@ import static android.os.PowerExemptionManager.REASON_ROLE_EMERGENCY;
import static android.os.PowerExemptionManager.REASON_SYSTEM_ALLOW_LISTED;
import static android.os.PowerExemptionManager.REASON_SYSTEM_MODULE;
import static android.os.PowerExemptionManager.REASON_SYSTEM_UID;
+import static android.os.PowerExemptionManager.getExemptionReasonForStatsd;
import static android.os.PowerExemptionManager.reasonCodeToString;
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
@@ -80,7 +82,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA
import static com.android.server.am.AppFGSTracker.foregroundServiceTypeToIndex;
import static com.android.server.am.BaseAppStateTracker.ONE_DAY;
-import android.annotation.ElapsedRealtimeLong;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -114,12 +116,14 @@ import android.content.pm.ServiceInfo.ForegroundServiceType;
import android.database.ContentObserver;
import android.graphics.drawable.Icon;
import android.net.Uri;
+import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerExemptionManager.ExemptionReason;
import android.os.PowerExemptionManager.ReasonCode;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -131,17 +135,24 @@ import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.ArraySet;
+import android.util.AtomicFile;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseArrayMap;
import android.util.TimeUtils;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.function.TriConsumer;
import com.android.server.AppStateTracker;
import com.android.server.LocalServices;
@@ -152,6 +163,15 @@ import com.android.server.pm.UserManagerInternal;
import com.android.server.usage.AppStandbyInternal;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -163,6 +183,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
/**
@@ -192,6 +213,16 @@ public final class AppRestrictionController {
*/
private static final boolean ENABLE_SHOW_FGS_MANAGER_ACTION_ON_BG_RESTRICTION = false;
+ private static final String APP_RESTRICTION_SETTINGS_DIRNAME = "apprestriction";
+ private static final String APP_RESTRICTION_SETTINGS_FILENAME = "settings.xml";
+
+ private static final String TAG_SETTINGS = "settings";
+ private static final String ATTR_PACKAGE = "package";
+ private static final String ATTR_UID = "uid";
+ private static final String ATTR_CUR_LEVEL = "curlevel";
+ private static final String ATTR_LEVEL_TS = "levelts";
+ private static final String ATTR_REASON = "reason";
+
private final Context mContext;
private final HandlerThread mBgHandlerThread;
private final BgHandler mBgHandler;
@@ -200,8 +231,9 @@ public final class AppRestrictionController {
// No lock is needed, as it's immutable after initialization in constructor.
private final ArrayList<BaseAppStateTracker> mAppStateTrackers = new ArrayList<>();
+ @VisibleForTesting
@GuardedBy("mSettingsLock")
- private final RestrictionSettings mRestrictionSettings = new RestrictionSettings();
+ final RestrictionSettings mRestrictionSettings = new RestrictionSettings();
private final CopyOnWriteArraySet<AppBackgroundRestrictionListener> mRestrictionListeners =
new CopyOnWriteArraySet<>();
@@ -264,8 +296,33 @@ public final class AppRestrictionController {
@GuardedBy("mCarrierPrivilegedLock")
private List<String> mCarrierPrivilegedApps;
+ /**
+ * Whether or not we've loaded the restriction settings from the persistent storage.
+ */
+ private final AtomicBoolean mRestrictionSettingsXmlLoaded = new AtomicBoolean();
+
final ActivityManagerService mActivityManagerService;
+ static final int TRACKER_TYPE_UNKNOWN = 0;
+ static final int TRACKER_TYPE_BATTERY = 1;
+ static final int TRACKER_TYPE_BATTERY_EXEMPTION = 2;
+ static final int TRACKER_TYPE_FGS = 3;
+ static final int TRACKER_TYPE_MEDIA_SESSION = 4;
+ static final int TRACKER_TYPE_PERMISSION = 5;
+ static final int TRACKER_TYPE_BROADCAST_EVENTS = 6;
+ static final int TRACKER_TYPE_BIND_SERVICE_EVENTS = 7;
+ @IntDef(prefix = { "TRACKER_TYPE_" }, value = {
+ TRACKER_TYPE_UNKNOWN,
+ TRACKER_TYPE_BATTERY,
+ TRACKER_TYPE_BATTERY_EXEMPTION,
+ TRACKER_TYPE_FGS,
+ TRACKER_TYPE_MEDIA_SESSION,
+ TRACKER_TYPE_PERMISSION,
+ TRACKER_TYPE_BROADCAST_EVENTS,
+ TRACKER_TYPE_BIND_SERVICE_EVENTS,
+ })
+ @interface TrackerType {}
+
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -363,10 +420,10 @@ public final class AppRestrictionController {
private @RestrictionLevel int mCurrentRestrictionLevel;
private @RestrictionLevel int mLastRestrictionLevel;
- private @ElapsedRealtimeLong long mLevelChangeTimeElapsed;
+ private @CurrentTimeMillisLong long mLevelChangeTime;
private int mReason;
- private @ElapsedRealtimeLong long[] mLastNotificationShownTimeElapsed;
+ private @CurrentTimeMillisLong long[] mLastNotificationShownTime;
private int[] mNotificationId;
PkgSettings(String packageName, int uid) {
@@ -380,7 +437,7 @@ public final class AppRestrictionController {
if (level != mCurrentRestrictionLevel) {
mLastRestrictionLevel = mCurrentRestrictionLevel;
mCurrentRestrictionLevel = level;
- mLevelChangeTimeElapsed = SystemClock.elapsedRealtime();
+ mLevelChangeTime = mInjector.currentTimeMillis();
mReason = (REASON_MAIN_MASK & reason) | (REASON_SUB_MASK & subReason);
mBgHandler.obtainMessage(BgHandler.MSG_APP_RESTRICTION_LEVEL_CHANGED,
mUid, level, mPackageName).sendToTarget();
@@ -407,7 +464,7 @@ public final class AppRestrictionController {
return sb.toString();
}
- void dump(PrintWriter pw, @ElapsedRealtimeLong long nowElapsed) {
+ void dump(PrintWriter pw, @CurrentTimeMillisLong long now) {
synchronized (mSettingsLock) {
pw.print(toString());
if (mLastRestrictionLevel != RESTRICTION_LEVEL_UNKNOWN) {
@@ -415,15 +472,14 @@ public final class AppRestrictionController {
pw.print(ActivityManager.restrictionLevelToName(mLastRestrictionLevel));
}
pw.print(" levelChange=");
- TimeUtils.formatDuration(mLevelChangeTimeElapsed - nowElapsed, pw);
- if (mLastNotificationShownTimeElapsed != null) {
- for (int i = 0; i < mLastNotificationShownTimeElapsed.length; i++) {
- if (mLastNotificationShownTimeElapsed[i] > 0) {
+ TimeUtils.formatDuration(mLevelChangeTime - now, pw);
+ if (mLastNotificationShownTime != null) {
+ for (int i = 0; i < mLastNotificationShownTime.length; i++) {
+ if (mLastNotificationShownTime[i] > 0) {
pw.print(" lastNoti(");
pw.print(mNotificationHelper.notificationTypeToString(i));
pw.print(")=");
- TimeUtils.formatDuration(
- mLastNotificationShownTimeElapsed[i] - nowElapsed, pw);
+ TimeUtils.formatDuration(mLastNotificationShownTime[i] - now, pw);
}
}
}
@@ -456,22 +512,32 @@ public final class AppRestrictionController {
}
@GuardedBy("mSettingsLock")
- @ElapsedRealtimeLong long getLastNotificationTime(
+ @CurrentTimeMillisLong long getLastNotificationTime(
@NotificationHelper.NotificationType int notificationType) {
- if (mLastNotificationShownTimeElapsed == null) {
+ if (mLastNotificationShownTime == null) {
return 0;
}
- return mLastNotificationShownTimeElapsed[notificationType];
+ return mLastNotificationShownTime[notificationType];
+ }
+
+ @GuardedBy("mSettingsLock")
+ void setLastNotificationTime(@NotificationHelper.NotificationType int notificationType,
+ @CurrentTimeMillisLong long timestamp) {
+ setLastNotificationTime(notificationType, timestamp, true);
}
+ @VisibleForTesting
@GuardedBy("mSettingsLock")
void setLastNotificationTime(@NotificationHelper.NotificationType int notificationType,
- @ElapsedRealtimeLong long timestamp) {
- if (mLastNotificationShownTimeElapsed == null) {
- mLastNotificationShownTimeElapsed =
+ @CurrentTimeMillisLong long timestamp, boolean persist) {
+ if (mLastNotificationShownTime == null) {
+ mLastNotificationShownTime =
new long[NotificationHelper.NOTIFICATION_TYPE_LAST];
}
- mLastNotificationShownTimeElapsed[notificationType] = timestamp;
+ mLastNotificationShownTime[notificationType] = timestamp;
+ if (persist && mRestrictionSettingsXmlLoaded.get()) {
+ schedulePersistToXml(UserHandle.getUserId(mUid));
+ }
}
@GuardedBy("mSettingsLock")
@@ -490,6 +556,51 @@ public final class AppRestrictionController {
}
mNotificationId[notificationType] = notificationId;
}
+
+ @VisibleForTesting
+ @GuardedBy("mSettingsLock")
+ void setLevelChangeTime(@CurrentTimeMillisLong long timestamp) {
+ mLevelChangeTime = timestamp;
+ }
+
+ @GuardedBy("mSettingsLock")
+ @Override
+ public Object clone() {
+ final PkgSettings newObj = new PkgSettings(mPackageName, mUid);
+ newObj.mCurrentRestrictionLevel = mCurrentRestrictionLevel;
+ newObj.mLastRestrictionLevel = mLastRestrictionLevel;
+ newObj.mLevelChangeTime = mLevelChangeTime;
+ newObj.mReason = mReason;
+ if (mLastNotificationShownTime != null) {
+ newObj.mLastNotificationShownTime = Arrays.copyOf(
+ mLastNotificationShownTime, mLastNotificationShownTime.length);
+ }
+ if (mNotificationId != null) {
+ newObj.mNotificationId = Arrays.copyOf(mNotificationId, mNotificationId.length);
+ }
+ return newObj;
+ }
+
+ @GuardedBy("mSettingsLock")
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (other == null || !(other instanceof PkgSettings)) {
+ return false;
+ }
+ final PkgSettings otherSettings = (PkgSettings) other;
+ return otherSettings.mUid == mUid
+ && otherSettings.mCurrentRestrictionLevel == mCurrentRestrictionLevel
+ && otherSettings.mLastRestrictionLevel == mLastRestrictionLevel
+ && otherSettings.mLevelChangeTime == mLevelChangeTime
+ && otherSettings.mReason == mReason
+ && TextUtils.equals(otherSettings.mPackageName, mPackageName)
+ && Arrays.equals(otherSettings.mLastNotificationShownTime,
+ mLastNotificationShownTime)
+ && Arrays.equals(otherSettings.mNotificationId, mNotificationId);
+ }
}
/**
@@ -604,21 +715,58 @@ public final class AppRestrictionController {
}
void removePackage(String pkgName, int uid) {
+ removePackage(pkgName, uid, true);
+ }
+
+ void removePackage(String pkgName, int uid, boolean persist) {
synchronized (mSettingsLock) {
+ final int keyIndex = mRestrictionLevels.indexOfKey(uid);
mRestrictionLevels.delete(uid, pkgName);
+ if (keyIndex >= 0 && mRestrictionLevels.numElementsForKeyAt(keyIndex) == 0) {
+ mRestrictionLevels.deleteAt(keyIndex);
+ }
+ }
+ if (persist && mRestrictionSettingsXmlLoaded.get()) {
+ schedulePersistToXml(UserHandle.getUserId(uid));
}
}
void removeUid(int uid) {
+ removeUid(uid, true);
+ }
+
+ void removeUid(int uid, boolean persist) {
synchronized (mSettingsLock) {
mRestrictionLevels.delete(uid);
}
+ if (persist && mRestrictionSettingsXmlLoaded.get()) {
+ schedulePersistToXml(UserHandle.getUserId(uid));
+ }
}
@VisibleForTesting
void reset() {
synchronized (mSettingsLock) {
- mRestrictionLevels.clear();
+ for (int i = mRestrictionLevels.numMaps() - 1; i >= 0; i--) {
+ mRestrictionLevels.deleteAt(i);
+ }
+ }
+ }
+
+ @VisibleForTesting
+ void resetToDefault() {
+ synchronized (mSettingsLock) {
+ mRestrictionLevels.forEach(settings -> {
+ settings.mCurrentRestrictionLevel = RESTRICTION_LEVEL_UNKNOWN;
+ settings.mLastRestrictionLevel = RESTRICTION_LEVEL_UNKNOWN;
+ settings.mLevelChangeTime = 0L;
+ settings.mReason = REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_UNDEFINED;
+ if (settings.mLastNotificationShownTime != null) {
+ for (int i = 0; i < settings.mLastNotificationShownTime.length; i++) {
+ settings.mLastNotificationShownTime[i] = 0L;
+ }
+ }
+ });
}
}
@@ -628,16 +776,272 @@ public final class AppRestrictionController {
mRestrictionLevels.forEach(setting -> settings.add(setting));
}
Collections.sort(settings, Comparator.comparingInt(PkgSettings::getUid));
- final long nowElapsed = SystemClock.elapsedRealtime();
+ final long now = mInjector.currentTimeMillis();
for (int i = 0, size = settings.size(); i < size; i++) {
pw.print(prefix);
pw.print('#');
pw.print(i);
pw.print(' ');
- settings.get(i).dump(pw, nowElapsed);
+ settings.get(i).dump(pw, now);
pw.println();
}
}
+
+ @VisibleForTesting
+ void schedulePersistToXml(@UserIdInt int userId) {
+ mBgHandler.obtainMessage(BgHandler.MSG_PERSIST_RESTRICTION_SETTINGS, userId, 0)
+ .sendToTarget();
+ }
+
+ @VisibleForTesting
+ void scheduleLoadFromXml() {
+ mBgHandler.sendEmptyMessage(BgHandler.MSG_LOAD_RESTRICTION_SETTINGS);
+ }
+
+ @VisibleForTesting
+ File getXmlFileNameForUser(@UserIdInt int userId) {
+ final File dir = new File(mInjector.getDataSystemDeDirectory(
+ userId), APP_RESTRICTION_SETTINGS_DIRNAME);
+ return new File(dir, APP_RESTRICTION_SETTINGS_FILENAME);
+ }
+
+ @VisibleForTesting
+ void loadFromXml(boolean applyLevel) {
+ final int[] allUsers = mInjector.getUserManagerInternal().getUserIds();
+ for (int userId : allUsers) {
+ loadFromXml(userId, applyLevel);
+ }
+ mRestrictionSettingsXmlLoaded.set(true);
+ }
+
+ void loadFromXml(@UserIdInt int userId, boolean applyLevel) {
+ final File file = getXmlFileNameForUser(userId);
+ if (!file.exists()) {
+ return;
+ }
+ final long[] ts = new long[NotificationHelper.NOTIFICATION_TYPE_LAST];
+ try (InputStream in = new FileInputStream(file)) {
+ final TypedXmlPullParser parser = Xml.resolvePullParser(in);
+ final long now = SystemClock.elapsedRealtime();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+ final String tagName = parser.getName();
+ if (!TAG_SETTINGS.equals(tagName)) {
+ Slog.w(TAG, "Unexpected tag name: " + tagName);
+ continue;
+ }
+ loadOneFromXml(parser, now, ts, applyLevel);
+ }
+ if (DEBUG_BG_RESTRICTION_CONTROLLER) {
+ Slog.i(TAG, "Loaded from " + file);
+ }
+ } catch (IOException | XmlPullParserException e) {
+ }
+ }
+
+ private void loadOneFromXml(TypedXmlPullParser parser, long now, long[] ts,
+ boolean applyLevel) {
+ // Reset the buffer.
+ for (int i = 0; i < ts.length; i++) {
+ ts[i] = 0L;
+ }
+ // Walk through the attributes.
+ int uid = 0;
+ String packageName = null;
+ int curLevel = RESTRICTION_LEVEL_UNKNOWN;
+ int reason = REASON_MAIN_DEFAULT;
+ long levelTs = 0L;
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ try {
+ final String attrName = parser.getAttributeName(i);
+ final String attrValue = parser.getAttributeValue(i);
+ switch (attrName) {
+ case ATTR_UID:
+ uid = Integer.parseInt(attrValue);
+ break;
+ case ATTR_PACKAGE:
+ packageName = attrValue;
+ break;
+ case ATTR_CUR_LEVEL:
+ curLevel = Integer.parseInt(attrValue);
+ break;
+ case ATTR_LEVEL_TS:
+ levelTs = Long.parseLong(attrValue);
+ break;
+ case ATTR_REASON:
+ reason = Integer.parseInt(attrValue);
+ break;
+ default:
+ @NotificationHelper.NotificationType int type =
+ NotificationHelper.notificationTimeAttrToType(attrName);
+ ts[type] = Long.parseLong(attrValue);
+ break;
+ }
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ if (uid != 0) {
+ if (DEBUG_BG_RESTRICTION_CONTROLLER) {
+ Slog.i(TAG, "Restoring " + packageName + "/" + UserHandle.formatUid(uid)
+ + " level=" + curLevel + " reason=" + Integer.toHexString(reason)
+ + " ts=" + levelTs + " noti=" + Arrays.toString(ts));
+ }
+ final PkgSettings pkgSettings;
+ synchronized (mSettingsLock) {
+ pkgSettings = getRestrictionSettingsLocked(uid, packageName);
+ if (pkgSettings == null) {
+ return;
+ }
+ for (int i = 0; i < ts.length; i++) {
+ if (pkgSettings.getLastNotificationTime(i) == 0 && ts[i] != 0) {
+ pkgSettings.setLastNotificationTime(i, ts[i], false);
+ }
+ }
+ if (pkgSettings.mCurrentRestrictionLevel >= curLevel) {
+ // The current restriction level is the same or more restrictive,
+ // don't restore.
+ return;
+ }
+ }
+ final int curBucket = mInjector.getAppStandbyInternal().getAppStandbyBucket(
+ packageName, UserHandle.getUserId(uid), now, false);
+ if (applyLevel) {
+ applyRestrictionLevel(packageName, uid, curLevel, TRACKER_TYPE_UNKNOWN,
+ curBucket, true, reason & REASON_MAIN_MASK, reason & REASON_SUB_MASK);
+ } else {
+ pkgSettings.update(curLevel,
+ reason & REASON_MAIN_MASK, reason & REASON_SUB_MASK);
+ }
+ synchronized (mSettingsLock) {
+ // Restore the mLevelChangeTime too.
+ pkgSettings.setLevelChangeTime(levelTs);
+ }
+ }
+ }
+
+ @VisibleForTesting
+ void persistToXml(@UserIdInt int userId) {
+ final File file = getXmlFileNameForUser(userId);
+ final File dir = file.getParentFile();
+ if (!dir.isDirectory() && !dir.mkdirs()) {
+ Slog.w(TAG, "Failed to create folder for " + userId);
+ return;
+ }
+ final AtomicFile atomicFile = new AtomicFile(file);
+ FileOutputStream stream = null;
+ try {
+ stream = atomicFile.startWrite();
+ stream.write(toXmlByteArray(userId));
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to write file " + file, e);
+ if (stream != null) {
+ atomicFile.failWrite(stream);
+ }
+ return;
+ }
+ atomicFile.finishWrite(stream);
+ if (DEBUG_BG_RESTRICTION_CONTROLLER) {
+ Slog.i(TAG, "Successfully written to " + atomicFile);
+ }
+ }
+
+ private byte[] toXmlByteArray(@UserIdInt int userId) {
+ try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+ final TypedXmlSerializer serializer = Xml.resolveSerializer(os);
+
+ serializer.startDocument(/* encoding */ null, /* standalone */ true);
+
+ synchronized (mSettingsLock) {
+ for (int i = mRestrictionLevels.numMaps() - 1; i >= 0; i--) {
+ for (int j = mRestrictionLevels.numElementsForKeyAt(i) - 1; j >= 0; j--) {
+ final PkgSettings settings = mRestrictionLevels.valueAt(i, j);
+ final int uid = settings.getUid();
+ if (UserHandle.getUserId(uid) != userId) {
+ continue;
+ }
+ serializer.startTag(null, TAG_SETTINGS);
+ serializer.attributeInt(null, ATTR_UID, uid);
+ serializer.attribute(null, ATTR_PACKAGE, settings.getPackageName());
+ serializer.attributeInt(null, ATTR_CUR_LEVEL,
+ settings.mCurrentRestrictionLevel);
+ serializer.attributeLong(null, ATTR_LEVEL_TS,
+ settings.mLevelChangeTime);
+ serializer.attributeInt(null, ATTR_REASON, settings.mReason);
+ for (int k = 0; k < NotificationHelper.NOTIFICATION_TYPE_LAST; k++) {
+ serializer.attributeLong(null,
+ NotificationHelper.notificationTypeToTimeAttr(k),
+ settings.getLastNotificationTime(k));
+ }
+ serializer.endTag(null, TAG_SETTINGS);
+ }
+ }
+ }
+
+ serializer.endDocument();
+ serializer.flush();
+
+ return os.toByteArray();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ @VisibleForTesting
+ void removeXml() {
+ final int[] allUsers = mInjector.getUserManagerInternal().getUserIds();
+ for (int userId : allUsers) {
+ getXmlFileNameForUser(userId).delete();
+ }
+ }
+
+ @Override
+ public Object clone() {
+ final RestrictionSettings newObj = new RestrictionSettings();
+ synchronized (mSettingsLock) {
+ for (int i = mRestrictionLevels.numMaps() - 1; i >= 0; i--) {
+ for (int j = mRestrictionLevels.numElementsForKeyAt(i) - 1; j >= 0; j--) {
+ final PkgSettings settings = mRestrictionLevels.valueAt(i, j);
+ newObj.mRestrictionLevels.add(mRestrictionLevels.keyAt(i),
+ mRestrictionLevels.keyAt(i, j), (PkgSettings) settings.clone());
+ }
+ }
+ }
+ return newObj;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (other == null || !(other instanceof RestrictionSettings)) {
+ return false;
+ }
+ final SparseArrayMap<String, PkgSettings> otherSettings = ((RestrictionSettings) other)
+ .mRestrictionLevels;
+ synchronized (mSettingsLock) {
+ if (otherSettings.numMaps() != mRestrictionLevels.numMaps()) {
+ return false;
+ }
+ for (int i = mRestrictionLevels.numMaps() - 1; i >= 0; i--) {
+ final int uid = mRestrictionLevels.keyAt(i);
+ if (otherSettings.numElementsForKey(uid)
+ != mRestrictionLevels.numElementsForKeyAt(i)) {
+ return false;
+ }
+ for (int j = mRestrictionLevels.numElementsForKeyAt(i) - 1; j >= 0; j--) {
+ final PkgSettings settings = mRestrictionLevels.valueAt(i, j);
+ if (!settings.equals(otherSettings.get(uid, settings.getPackageName()))) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
}
final class ConstantsObserver extends ContentObserver implements
@@ -1010,6 +1414,7 @@ public final class AppRestrictionController {
DeviceConfig.removeOnPropertiesChangedListener(mConstantsObserver);
unregisterForUidObservers();
unregisterForSystemBroadcasts();
+ mRestrictionSettings.removeXml();
}
private void initBgRestrictionExemptioFromSysConfig() {
@@ -1034,6 +1439,14 @@ public final class AppRestrictionController {
refreshAppRestrictionLevelForUser(userId, REASON_MAIN_FORCED_BY_USER,
REASON_SUB_FORCED_USER_FLAG_INTERACTION);
}
+ if (!mInjector.isTest()) {
+ // Load the previously saved levels and update the current levels if needed.
+ mRestrictionSettings.scheduleLoadFromXml();
+ // Also save the current levels right away.
+ for (int userId : allUsers) {
+ mRestrictionSettings.schedulePersistToXml(userId);
+ }
+ }
}
private void initSystemModuleNames() {
@@ -1124,15 +1537,15 @@ public final class AppRestrictionController {
Slog.e(TAG, "Unable to find " + info.mPackageName + "/u" + userId);
continue;
}
- final @RestrictionLevel int level = calcAppRestrictionLevel(
+ final Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevel(
userId, uid, info.mPackageName, info.mStandbyBucket, false, false);
if (DEBUG_BG_RESTRICTION_CONTROLLER) {
Slog.i(TAG, "Proposed restriction level of " + info.mPackageName + "/"
+ UserHandle.formatUid(uid) + ": "
- + ActivityManager.restrictionLevelToName(level)
+ + ActivityManager.restrictionLevelToName(levelTypePair.first)
+ " " + info.mStandbyBucket);
}
- applyRestrictionLevel(info.mPackageName, uid, level,
+ applyRestrictionLevel(info.mPackageName, uid, levelTypePair.first, levelTypePair.second,
info.mStandbyBucket, true, reason, subReason);
}
}
@@ -1148,24 +1561,26 @@ public final class AppRestrictionController {
final long now = SystemClock.elapsedRealtime();
for (String pkg: packages) {
final int curBucket = appStandbyInternal.getAppStandbyBucket(pkg, userId, now, false);
- final @RestrictionLevel int level = calcAppRestrictionLevel(userId, uid, pkg,
+ final Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevel(userId, uid, pkg,
curBucket, allowRequestBgRestricted, true);
if (DEBUG_BG_RESTRICTION_CONTROLLER) {
Slog.i(TAG, "Proposed restriction level of " + pkg + "/"
+ UserHandle.formatUid(uid) + ": "
- + ActivityManager.restrictionLevelToName(level));
+ + ActivityManager.restrictionLevelToName(levelTypePair.first));
}
- applyRestrictionLevel(pkg, uid, level, curBucket, true, reason, subReason);
+ applyRestrictionLevel(pkg, uid, levelTypePair.first, levelTypePair.second,
+ curBucket, true, reason, subReason);
}
}
- private @RestrictionLevel int calcAppRestrictionLevel(@UserIdInt int userId, int uid,
+ private Pair<Integer, Integer> calcAppRestrictionLevel(@UserIdInt int userId, int uid,
String packageName, @UsageStatsManager.StandbyBuckets int standbyBucket,
boolean allowRequestBgRestricted, boolean calcTrackers) {
if (mInjector.getAppHibernationInternal().isHibernatingForUser(packageName, userId)) {
- return RESTRICTION_LEVEL_HIBERNATION;
+ return new Pair<>(RESTRICTION_LEVEL_HIBERNATION, TRACKER_TYPE_UNKNOWN);
}
@RestrictionLevel int level;
+ @TrackerType int trackerType = TRACKER_TYPE_UNKNOWN;
switch (standbyBucket) {
case STANDBY_BUCKET_EXEMPTED:
level = RESTRICTION_LEVEL_EXEMPTED;
@@ -1181,19 +1596,23 @@ public final class AppRestrictionController {
default:
if (mInjector.getAppStateTracker()
.isAppBackgroundRestricted(uid, packageName)) {
- return RESTRICTION_LEVEL_BACKGROUND_RESTRICTED;
+ return new Pair<>(RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, trackerType);
}
level = mConstantsObserver.mRestrictedBucketEnabled
&& standbyBucket == STANDBY_BUCKET_RESTRICTED
? RESTRICTION_LEVEL_RESTRICTED_BUCKET
: RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
if (calcTrackers) {
- @RestrictionLevel int l = calcAppRestrictionLevelFromTackers(uid, packageName,
- RESTRICTION_LEVEL_MAX);
+ Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevelFromTackers(
+ uid, packageName, RESTRICTION_LEVEL_MAX);
+ @RestrictionLevel int l = levelTypePair.first;
if (l == RESTRICTION_LEVEL_EXEMPTED) {
- return RESTRICTION_LEVEL_EXEMPTED;
+ return new Pair<>(RESTRICTION_LEVEL_EXEMPTED, levelTypePair.second);
}
level = Math.max(l, level);
+ if (l == level) {
+ trackerType = levelTypePair.second;
+ }
if (level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
// This level can't be entered without user consent
if (allowRequestBgRestricted) {
@@ -1201,27 +1620,32 @@ public final class AppRestrictionController {
uid, 0, packageName).sendToTarget();
}
// Lower the level.
- level = calcAppRestrictionLevelFromTackers(uid, packageName,
+ levelTypePair = calcAppRestrictionLevelFromTackers(uid, packageName,
RESTRICTION_LEVEL_BACKGROUND_RESTRICTED);
+ level = levelTypePair.first;
+ trackerType = levelTypePair.second;
}
}
break;
}
- return level;
+ return new Pair<>(level, trackerType);
}
/**
* Ask each of the trackers for their proposed restriction levels for the given uid/package,
- * and return the most restrictive level.
+ * and return the most restrictive level along with the type of tracker which applied this
+ * restriction level as a {@code Pair<@RestrictionLevel, @TrackerType>}.
*
* <p>Note, it's different from the {@link #getRestrictionLevel} where it returns the least
* restrictive level. We're returning the most restrictive level here because each tracker
* monitors certain dimensions of the app, the abusive behaviors could be detected in one or
* more of these dimensions, but not necessarily all of them. </p>
*/
- private @RestrictionLevel int calcAppRestrictionLevelFromTackers(int uid, String packageName,
+ private Pair<Integer, Integer> calcAppRestrictionLevelFromTackers(int uid, String packageName,
@RestrictionLevel int maxLevel) {
@RestrictionLevel int level = RESTRICTION_LEVEL_UNKNOWN;
+ @RestrictionLevel int prevLevel = level;
+ @TrackerType int trackerType = TRACKER_TYPE_UNKNOWN;
final boolean isRestrictedBucketEnabled = mConstantsObserver.mRestrictedBucketEnabled;
for (int i = mAppStateTrackers.size() - 1; i >= 0; i--) {
@RestrictionLevel int l = mAppStateTrackers.get(i).getPolicy()
@@ -1230,8 +1654,12 @@ public final class AppRestrictionController {
l = RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
}
level = Math.max(level, l);
+ if (level != prevLevel) {
+ trackerType = mAppStateTrackers.get(i).getType();
+ prevLevel = level;
+ }
}
- return level;
+ return new Pair<>(level, trackerType);
}
private static @RestrictionLevel int standbyBucketToRestrictionLevel(
@@ -1444,7 +1872,129 @@ public final class AppRestrictionController {
}
}
- private void applyRestrictionLevel(String pkgName, int uid, @RestrictionLevel int level,
+ private int getRestrictionLevelStatsd(@RestrictionLevel int level) {
+ switch (level) {
+ case RESTRICTION_LEVEL_UNKNOWN:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNKNOWN;
+ case RESTRICTION_LEVEL_UNRESTRICTED:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNRESTRICTED;
+ case RESTRICTION_LEVEL_EXEMPTED:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_EXEMPTED;
+ case RESTRICTION_LEVEL_ADAPTIVE_BUCKET:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_ADAPTIVE_BUCKET;
+ case RESTRICTION_LEVEL_RESTRICTED_BUCKET:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_RESTRICTED_BUCKET;
+ case RESTRICTION_LEVEL_BACKGROUND_RESTRICTED:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_BACKGROUND_RESTRICTED;
+ case RESTRICTION_LEVEL_HIBERNATION:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_HIBERNATION;
+ default:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNKNOWN;
+ }
+ }
+
+ private int getThresholdStatsd(int reason) {
+ switch (reason) {
+ case REASON_MAIN_FORCED_BY_SYSTEM:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_RESTRICTED;
+ case REASON_MAIN_FORCED_BY_USER:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_USER;
+ default:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_UNKNOWN;
+ }
+ }
+
+ private int getTrackerTypeStatsd(@TrackerType int type) {
+ switch (type) {
+ case TRACKER_TYPE_BATTERY:
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BATTERY_TRACKER;
+ case TRACKER_TYPE_BATTERY_EXEMPTION:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BATTERY_EXEMPTION_TRACKER;
+ case TRACKER_TYPE_FGS:
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__FGS_TRACKER;
+ case TRACKER_TYPE_MEDIA_SESSION:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__MEDIA_SESSION_TRACKER;
+ case TRACKER_TYPE_PERMISSION:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__PERMISSION_TRACKER;
+ case TRACKER_TYPE_BROADCAST_EVENTS:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BROADCAST_EVENTS_TRACKER;
+ case TRACKER_TYPE_BIND_SERVICE_EVENTS:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BIND_SERVICE_EVENTS_TRACKER;
+ default:
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__UNKNOWN_TRACKER;
+ }
+ }
+
+ private @ExemptionReason int getExemptionReasonStatsd(int uid, @RestrictionLevel int level) {
+ if (level != RESTRICTION_LEVEL_EXEMPTED) {
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DENIED;
+ }
+
+ @ReasonCode final int reasonCode = getBackgroundRestrictionExemptionReason(uid);
+ return getExemptionReasonForStatsd(reasonCode);
+ }
+
+ private int getOptimizationLevelStatsd(@RestrictionLevel int level) {
+ switch (level) {
+ case RESTRICTION_LEVEL_UNKNOWN:
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__UNKNOWN;
+ case RESTRICTION_LEVEL_UNRESTRICTED:
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__NOT_OPTIMIZED;
+ case RESTRICTION_LEVEL_ADAPTIVE_BUCKET:
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__OPTIMIZED;
+ case RESTRICTION_LEVEL_BACKGROUND_RESTRICTED:
+ return FrameworkStatsLog
+ .APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__BACKGROUND_RESTRICTED;
+ default:
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__UNKNOWN;
+ }
+ }
+
+ @SuppressWarnings("AndroidFrameworkCompatChange")
+ private int getTargetSdkStatsd(String packageName) {
+ final PackageManager pm = mInjector.getPackageManager();
+ if (pm == null) {
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN;
+ }
+ try {
+ final PackageInfo pkg = pm.getPackageInfo(packageName, 0 /* flags */);
+ if (pkg == null || pkg.applicationInfo == null) {
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN;
+ }
+ final int targetSdk = pkg.applicationInfo.targetSdkVersion;
+ if (targetSdk < Build.VERSION_CODES.S) {
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_PRE_S;
+ } else if (targetSdk < Build.VERSION_CODES.TIRAMISU) {
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_S;
+ } else if (targetSdk == Build.VERSION_CODES.TIRAMISU) {
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_T;
+ } else {
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN;
+ }
+ } catch (PackageManager.NameNotFoundException ignored) {
+ }
+ return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN;
+ }
+
+ private void applyRestrictionLevel(String pkgName, int uid,
+ @RestrictionLevel int level, @TrackerType int trackerType,
int curBucket, boolean allowUpdateBucket, int reason, int subReason) {
int curLevel;
int prevReason;
@@ -1524,6 +2074,19 @@ public final class AppRestrictionController {
prevReason & REASON_MAIN_MASK, prevReason & REASON_SUB_MASK,
reason, subReason);
}
+
+ FrameworkStatsLog.write(FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO, uid,
+ getRestrictionLevelStatsd(level),
+ getThresholdStatsd(reason),
+ getTrackerTypeStatsd(trackerType),
+ null, // FgsTrackerInfo
+ null, // BatteryTrackerInfo
+ null, // BroadcastEventsTrackerInfo
+ null, // BindServiceEventsTrackerInfo
+ getExemptionReasonStatsd(uid, level),
+ getOptimizationLevelStatsd(level),
+ getTargetSdkStatsd(pkgName),
+ ActivityManager.isLowRamDeviceStatic());
}
private void handleBackgroundRestrictionChanged(int uid, String pkgName, boolean restricted) {
@@ -1541,7 +2104,7 @@ public final class AppRestrictionController {
// The app could fall into the background restricted with user consent only,
// so set the reason to it.
applyRestrictionLevel(pkgName, uid, RESTRICTION_LEVEL_BACKGROUND_RESTRICTED,
- curBucket, true, REASON_MAIN_FORCED_BY_USER,
+ TRACKER_TYPE_UNKNOWN, curBucket, true, REASON_MAIN_FORCED_BY_USER,
REASON_SUB_FORCED_USER_FLAG_INTERACTION);
mBgHandler.obtainMessage(BgHandler.MSG_CANCEL_REQUEST_BG_RESTRICTED, uid, 0, pkgName)
.sendToTarget();
@@ -1554,11 +2117,11 @@ public final class AppRestrictionController {
? STANDBY_BUCKET_EXEMPTED
: (lastLevel == RESTRICTION_LEVEL_RESTRICTED_BUCKET
? STANDBY_BUCKET_RESTRICTED : STANDBY_BUCKET_RARE);
- final @RestrictionLevel int level = calcAppRestrictionLevel(
+ final Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevel(
UserHandle.getUserId(uid), uid, pkgName, tentativeBucket, false, true);
- applyRestrictionLevel(pkgName, uid, level, curBucket, true,
- REASON_MAIN_USAGE, REASON_SUB_USAGE_USER_INTERACTION);
+ applyRestrictionLevel(pkgName, uid, levelTypePair.first, levelTypePair.second,
+ curBucket, true, REASON_MAIN_USAGE, REASON_SUB_USAGE_USER_INTERACTION);
}
}
@@ -1598,10 +2161,10 @@ public final class AppRestrictionController {
@UserIdInt int userId) {
final int uid = mInjector.getPackageManagerInternal().getPackageUid(
packageName, STOCK_PM_FLAGS, userId);
- final @RestrictionLevel int level = calcAppRestrictionLevel(
+ final Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevel(
userId, uid, packageName, bucket, false, false);
- applyRestrictionLevel(packageName, uid, level, bucket, false,
- REASON_MAIN_DEFAULT, REASON_SUB_DEFAULT_UNDEFINED);
+ applyRestrictionLevel(packageName, uid, levelTypePair.first, levelTypePair.second,
+ bucket, false, REASON_MAIN_DEFAULT, REASON_SUB_DEFAULT_UNDEFINED);
}
void handleRequestBgRestricted(String packageName, int uid) {
@@ -1642,6 +2205,9 @@ public final class AppRestrictionController {
static final int NOTIFICATION_TYPE_LONG_RUNNING_FGS = 1;
static final int NOTIFICATION_TYPE_LAST = 2;
+ static final String ATTR_LAST_BATTERY_NOTIFICATION_TIME = "last_batt_noti_ts";
+ static final String ATTR_LAST_LONG_FGS_NOTIFICATION_TIME = "last_long_fgs_noti_ts";
+
@IntDef(prefix = { "NOTIFICATION_TYPE_"}, value = {
NOTIFICATION_TYPE_ABUSIVE_CURRENT_DRAIN,
NOTIFICATION_TYPE_LONG_RUNNING_FGS,
@@ -1654,6 +2220,25 @@ public final class AppRestrictionController {
"Long-running FGS",
};
+ static final String[] NOTIFICATION_TIME_ATTRS = {
+ ATTR_LAST_BATTERY_NOTIFICATION_TIME,
+ ATTR_LAST_LONG_FGS_NOTIFICATION_TIME,
+ };
+
+ static @NotificationType int notificationTimeAttrToType(@NonNull String attr) {
+ switch (attr) {
+ case ATTR_LAST_BATTERY_NOTIFICATION_TIME:
+ return NOTIFICATION_TYPE_ABUSIVE_CURRENT_DRAIN;
+ case ATTR_LAST_LONG_FGS_NOTIFICATION_TIME:
+ return NOTIFICATION_TYPE_LONG_RUNNING_FGS;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ static @NonNull String notificationTypeToTimeAttr(@NotificationType int type) {
+ return NOTIFICATION_TIME_ATTRS[type];
+ }
+
static final String ACTION_FGS_MANAGER_TRAMPOLINE =
"com.android.server.am.ACTION_FGS_MANAGER_TRAMPOLINE";
@@ -1801,14 +2386,14 @@ public final class AppRestrictionController {
return 0;
}
- final long now = SystemClock.elapsedRealtime();
- final long lastNotificationShownTimeElapsed =
+ final long now = mInjector.currentTimeMillis();
+ final long lastNotificationShownTime =
settings.getLastNotificationTime(notificationType);
- if (lastNotificationShownTimeElapsed != 0 && (lastNotificationShownTimeElapsed
+ if (lastNotificationShownTime != 0 && (lastNotificationShownTime
+ getNotificationMinInterval(notificationType) > now)) {
if (DEBUG_BG_RESTRICTION_CONTROLLER) {
Slog.i(TAG, "Not showing notification as last notification was shown "
- + TimeUtils.formatDuration(now - lastNotificationShownTimeElapsed)
+ + TimeUtils.formatDuration(now - lastNotificationShownTime)
+ " ago");
}
return 0;
@@ -1824,7 +2409,7 @@ public final class AppRestrictionController {
+ "/" + UserHandle.formatUid(uid)
+ ", id=" + notificationId
+ ", now=" + now
- + ", lastShown=" + lastNotificationShownTimeElapsed);
+ + ", lastShown=" + lastNotificationShownTime);
}
return notificationId;
}
@@ -1861,7 +2446,7 @@ public final class AppRestrictionController {
ABUSIVE_BACKGROUND_APPS)
.setAutoCancel(true)
.setGroup(GROUP_KEY)
- .setWhen(System.currentTimeMillis())
+ .setWhen(mInjector.currentTimeMillis())
.setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color))
@@ -2181,6 +2766,8 @@ public final class AppRestrictionController {
static final int MSG_UID_GONE = 7;
static final int MSG_UID_PROC_STATE_CHANGED = 8;
static final int MSG_CANCEL_REQUEST_BG_RESTRICTED = 9;
+ static final int MSG_LOAD_RESTRICTION_SETTINGS = 10;
+ static final int MSG_PERSIST_RESTRICTION_SETTINGS = 11;
private final Injector mInjector;
@@ -2226,6 +2813,12 @@ public final class AppRestrictionController {
c.handleUidInactive(msg.arg1, msg.arg2 == 1);
c.handleUidGone(msg.arg1);
} break;
+ case MSG_LOAD_RESTRICTION_SETTINGS: {
+ c.mRestrictionSettings.loadFromXml(true);
+ } break;
+ case MSG_PERSIST_RESTRICTION_SETTINGS: {
+ c.mRestrictionSettings.persistToXml(msg.arg1);
+ } break;
}
}
}
@@ -2399,6 +2992,18 @@ public final class AppRestrictionController {
void scheduleInitTrackers(Handler handler, Runnable initializers) {
handler.post(initializers);
}
+
+ File getDataSystemDeDirectory(@UserIdInt int userId) {
+ return Environment.getDataSystemDeDirectory(userId);
+ }
+
+ @CurrentTimeMillisLong long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+
+ boolean isTest() {
+ return false;
+ }
}
private void registerForSystemBroadcasts() {
diff --git a/services/core/java/com/android/server/am/BaseAppStateTracker.java b/services/core/java/com/android/server/am/BaseAppStateTracker.java
index cb21a4bf8f22..5afcecaa069e 100644
--- a/services/core/java/com/android/server/am/BaseAppStateTracker.java
+++ b/services/core/java/com/android/server/am/BaseAppStateTracker.java
@@ -40,6 +40,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.app.IAppOpsService;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
+import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.notification.NotificationManagerInternal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
@@ -161,6 +162,13 @@ public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> {
}
/**
+ * Return the type of tracker (as defined by AppRestrictionController.TrackerType)
+ */
+ @TrackerType int getType() {
+ return AppRestrictionController.TRACKER_TYPE_UNKNOWN;
+ }
+
+ /**
* Return the policy holder of this tracker.
*/
T getPolicy() {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 6629a3018f81..bad7782fad77 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -423,9 +423,8 @@ public final class ProcessList {
* Having a global counter ensures that seq numbers are monotonically increasing for a
* particular uid even when the uidRecord is re-created.
*/
- @GuardedBy("mService")
@VisibleForTesting
- long mProcStateSeqCounter = 0;
+ volatile long mProcStateSeqCounter = 0;
/**
* A global counter for generating sequence numbers to uniquely identify pending process starts.
@@ -4860,6 +4859,10 @@ public final class ProcessList {
}
}
+ long getProcStateSeqCounter() {
+ return mProcStateSeqCounter;
+ }
+
/**
* Create a server socket in system_server, zygote will connect to it
* in order to send unsolicited messages to system_server.
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 639f56cb12dd..5a55b8b33cad 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -1112,7 +1112,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
foregroundNoti = localForegroundNoti; // save it for amending next time
signalForegroundServiceNotification(packageName, appInfo.uid,
- localForegroundId);
+ localForegroundId, false /* canceling */);
} catch (RuntimeException e) {
Slog.w(TAG, "Error showing notification for service", e);
@@ -1147,17 +1147,18 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
} catch (RuntimeException e) {
Slog.w(TAG, "Error canceling notification for service", e);
}
- signalForegroundServiceNotification(packageName, appInfo.uid, -localForegroundId);
+ signalForegroundServiceNotification(packageName, appInfo.uid, localForegroundId,
+ true /* canceling */);
}
});
}
private void signalForegroundServiceNotification(String packageName, int uid,
- int foregroundId) {
+ int foregroundId, boolean canceling) {
synchronized (ams) {
for (int i = ams.mForegroundServiceStateListeners.size() - 1; i >= 0; i--) {
ams.mForegroundServiceStateListeners.get(i).onForegroundServiceNotificationUpdated(
- packageName, appInfo.uid, foregroundId);
+ packageName, appInfo.uid, foregroundId, canceling);
}
}
}
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 4fa1ba1c8158..1c1d72685cf4 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -572,11 +572,13 @@ public final class GameManagerService extends IGameManagerService.Stub {
public static final String DEFAULT_SCALING = "1.0";
public static final String DEFAULT_FPS = "";
public static final String ANGLE_KEY = "useAngle";
+ public static final String LOADING_BOOST_KEY = "loadingBoost";
private final @GameMode int mGameMode;
private String mScaling;
private String mFps;
private final boolean mUseAngle;
+ private final int mLoadingBoostDuration;
GameModeConfiguration(KeyValueListParser parser) {
mGameMode = parser.getInt(MODE_KEY, GameManager.GAME_MODE_UNSUPPORTED);
@@ -595,6 +597,9 @@ public final class GameManagerService extends IGameManagerService.Stub {
// - The Phenotype config has enabled it.
mUseAngle = mAllowAngle && !willGamePerformOptimizations(mGameMode)
&& parser.getBoolean(ANGLE_KEY, false);
+
+ mLoadingBoostDuration = willGamePerformOptimizations(mGameMode) ? -1
+ : parser.getInt(LOADING_BOOST_KEY, -1);
}
public int getGameMode() {
@@ -613,6 +618,10 @@ public final class GameManagerService extends IGameManagerService.Stub {
return mUseAngle;
}
+ public int getLoadingBoostDuration() {
+ return mLoadingBoostDuration;
+ }
+
public void setScaling(String scaling) {
mScaling = scaling;
}
@@ -633,7 +642,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
*/
public String toString() {
return "[Game Mode:" + mGameMode + ",Scaling:" + mScaling + ",Use Angle:"
- + mUseAngle + ",Fps:" + mFps + "]";
+ + mUseAngle + ",Fps:" + mFps + ",Loading Boost Duration:"
+ + mLoadingBoostDuration + "]";
}
/**
@@ -968,6 +978,63 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
/**
+ * If loading boost is applicable for the package for the currently enabled game mode, return
+ * the boost duration. If no configuration is available for the selected package or mode, the
+ * default is returned.
+ */
+ @VisibleForTesting
+ public int getLoadingBoostDuration(String packageName, int userId)
+ throws SecurityException {
+ final int gameMode = getGameMode(packageName, userId);
+ if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
+ return -1;
+ }
+
+ synchronized (mDeviceConfigLock) {
+ final GamePackageConfiguration config = mConfigs.get(packageName);
+ if (config == null) {
+ return -1;
+ }
+ GamePackageConfiguration.GameModeConfiguration gameModeConfiguration =
+ config.getGameModeConfiguration(gameMode);
+ if (gameModeConfiguration == null) {
+ return -1;
+ }
+ return gameModeConfiguration.getLoadingBoostDuration();
+ }
+ }
+
+ /**
+ * If loading boost is enabled, invoke it.
+ */
+ @Override
+ @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
+ @GameMode public void notifyGraphicsEnvironmentSetup(String packageName, int userId)
+ throws SecurityException {
+ userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, true, "notifyGraphicsEnvironmentSetup",
+ "com.android.server.app.GameManagerService");
+
+ // Restrict to games only.
+ if (!isPackageGame(packageName, userId)) {
+ return;
+ }
+
+ if (!isValidPackageName(packageName, userId)) {
+ return;
+ }
+
+ final int gameMode = getGameMode(packageName, userId);
+ if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
+ return;
+ }
+ final int loadingBoostDuration = getLoadingBoostDuration(packageName, userId);
+ if (loadingBoostDuration != -1) {
+ mPowerManagerInternal.setPowerBoost(Mode.GAME_LOADING, loadingBoostDuration);
+ }
+ }
+
+ /**
* Sets the game service provider to a given package, meant for testing.
*
* <p>This setting persists until the next call or until the next reboot.
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 361629b0a629..752e17e59a6e 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2367,7 +2367,8 @@ public class AppOpsService extends IAppOpsService.Stub {
ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
boolean isSelfRequest = (filter & FILTER_BY_UID) != 0 && uid == Binder.getCallingUid();
if (!isSelfRequest) {
- boolean isCallerInstrumented = ami.isUidCurrentlyInstrumented(Binder.getCallingUid());
+ boolean isCallerInstrumented =
+ ami.getInstrumentationSourceUid(Binder.getCallingUid()) != Process.INVALID_UID;
boolean isCallerSystem = Binder.getCallingPid() == Process.myPid();
boolean isCallerPermissionController;
try {
@@ -6894,7 +6895,8 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public @Nullable RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage() {
ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
- boolean isCallerInstrumented = ami.isUidCurrentlyInstrumented(Binder.getCallingUid());
+ boolean isCallerInstrumented =
+ ami.getInstrumentationSourceUid(Binder.getCallingUid()) != Process.INVALID_UID;
boolean isCallerSystem = Binder.getCallingPid() == Process.myPid();
if (!isCallerSystem && !isCallerInstrumented) {
return null;
diff --git a/services/core/java/com/android/server/audio/AudioEventLogger.java b/services/core/java/com/android/server/audio/AudioEventLogger.java
index af0e978726e3..259990ce0687 100644
--- a/services/core/java/com/android/server/audio/AudioEventLogger.java
+++ b/services/core/java/com/android/server/audio/AudioEventLogger.java
@@ -16,9 +16,12 @@
package com.android.server.audio;
+import android.annotation.IntDef;
import android.util.Log;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
@@ -63,6 +66,16 @@ public class AudioEventLogger {
return printLog(ALOGI, tag);
}
+ /** @hide */
+ @IntDef(flag = false, value = {
+ ALOGI,
+ ALOGE,
+ ALOGW,
+ ALOGV }
+ )
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LogType {}
+
public static final int ALOGI = 0;
public static final int ALOGE = 1;
public static final int ALOGW = 2;
@@ -74,7 +87,7 @@ public class AudioEventLogger {
* @param tag
* @return
*/
- public Event printLog(int type, String tag) {
+ public Event printLog(@LogType int type, String tag) {
switch (type) {
case ALOGI:
Log.i(tag, eventToString());
@@ -135,6 +148,27 @@ public class AudioEventLogger {
mEvents.add(evt);
}
+ /**
+ * Add a string-based event to the log, and print it to logcat as info.
+ * @param msg the message for the logs
+ * @param tag the logcat tag to use
+ */
+ public synchronized void loglogi(String msg, String tag) {
+ final Event event = new StringEvent(msg);
+ log(event.printLog(tag));
+ }
+
+ /**
+ * Same as {@link #loglogi(String, String)} but specifying the logcat type
+ * @param msg the message for the logs
+ * @param logType the type of logcat entry
+ * @param tag the logcat tag to use
+ */
+ public synchronized void loglog(String msg, @Event.LogType int logType, String tag) {
+ final Event event = new StringEvent(msg);
+ log(event.printLog(logType, tag));
+ }
+
public synchronized void dump(PrintWriter pw) {
pw.println("Audio event log: " + mTitle);
for (Event evt : mEvents) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 517ff82d9fd2..465e5e9d8453 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -340,7 +340,8 @@ public class AudioService extends IAudioService.Stub
private static final int MSG_DISPATCH_AUDIO_MODE = 40;
private static final int MSG_ROUTING_UPDATED = 41;
private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
- private static final int MSG_PERSIST_SPATIAL_AUDIO_ENABLED = 43;
+ // commented out for now, will be reused for other SA persisting
+ //private static final int MSG_PERSIST_SPATIAL_AUDIO_ENABLED = 43;
private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44;
private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45;
private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46;
@@ -1543,9 +1544,7 @@ public class AudioService extends IAudioService.Stub
}
}
- if (mHasSpatializerEffect) {
- mSpatializerHelper.reset(/* featureEnabled */ isSpatialAudioEnabled());
- }
+ mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
onIndicateSystemReady();
// indicate the end of reconfiguration phase to audio HAL
@@ -8114,9 +8113,7 @@ public class AudioService extends IAudioService.Stub
case MSG_INIT_SPATIALIZER:
mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
- if (mHasSpatializerEffect) {
- mSpatializerHelper.setFeatureEnabled(isSpatialAudioEnabled());
- }
+ mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
mAudioEventWakeLock.release();
break;
@@ -8257,10 +8254,6 @@ public class AudioService extends IAudioService.Stub
onRoutingUpdatedFromAudioThread();
break;
- case MSG_PERSIST_SPATIAL_AUDIO_ENABLED:
- onPersistSpatialAudioEnabled(msg.arg1 == 1);
- break;
-
case MSG_ADD_ASSISTANT_SERVICE_UID:
onAddAssistantServiceUids(new int[]{msg.arg1});
break;
@@ -8864,31 +8857,6 @@ public class AudioService extends IAudioService.Stub
*/
private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true;
- /**
- * persist in user settings whether the feature is enabled.
- * Can change when {@link Spatializer#setEnabled(boolean)} is called and successfully
- * changes the state of the feature
- * @param featureEnabled
- */
- void persistSpatialAudioEnabled(boolean featureEnabled) {
- sendMsg(mAudioHandler,
- MSG_PERSIST_SPATIAL_AUDIO_ENABLED,
- SENDMSG_REPLACE, featureEnabled ? 1 : 0, 0, null,
- /*delay ms*/ 100);
- }
-
- void onPersistSpatialAudioEnabled(boolean enabled) {
- mSettings.putSecureIntForUser(mContentResolver,
- Settings.Secure.SPATIAL_AUDIO_ENABLED, enabled ? 1 : 0,
- UserHandle.USER_CURRENT);
- }
-
- boolean isSpatialAudioEnabled() {
- return mSettings.getSecureIntForUser(mContentResolver,
- Settings.Secure.SPATIAL_AUDIO_ENABLED, SPATIAL_AUDIO_ENABLED_DEFAULT ? 1 : 0,
- UserHandle.USER_CURRENT) == 1;
- }
-
private void enforceModifyDefaultAudioEffectsPermission() {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
@@ -9748,6 +9716,7 @@ public class AudioService extends IAudioService.Stub
static final int LOG_NB_EVENTS_FORCE_USE = 20;
static final int LOG_NB_EVENTS_VOLUME = 40;
static final int LOG_NB_EVENTS_DYN_POLICY = 10;
+ static final int LOG_NB_EVENTS_SPATIAL = 30;
static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE,
"audio services lifecycle");
@@ -9768,6 +9737,9 @@ public class AudioService extends IAudioService.Stub
static final AudioEventLogger sVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME,
"volume changes (logged when command received by AudioService)");
+ static final AudioEventLogger sSpatialLogger = new AudioEventLogger(LOG_NB_EVENTS_SPATIAL,
+ "spatial audio");
+
final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY,
"dynamic policy events (logged when command received by AudioService)");
@@ -9906,10 +9878,10 @@ public class AudioService extends IAudioService.Stub
pw.println("\n");
pw.println("\nSpatial audio:");
- pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect);
- pw.println("isSpatializerEnabled:" + isSpatializerEnabled());
- pw.println("isSpatialAudioEnabled:" + isSpatialAudioEnabled());
+ pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)");
+ pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)");
mSpatializerHelper.dump(pw);
+ sSpatialLogger.dump(pw);
mAudioSystem.dump(pw);
}
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 40a63504fb6b..d22a562651dc 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -177,20 +177,20 @@ public class SpatializerHelper {
}
synchronized void init(boolean effectExpected) {
- Log.i(TAG, "Initializing");
+ loglogi("init effectExpected=" + effectExpected);
if (!effectExpected) {
- Log.i(TAG, "Setting state to STATE_NOT_SUPPORTED due to effect not expected");
+ loglogi("init(): setting state to STATE_NOT_SUPPORTED due to effect not expected");
mState = STATE_NOT_SUPPORTED;
return;
}
if (mState != STATE_UNINITIALIZED) {
- throw new IllegalStateException(("init() called in state:" + mState));
+ throw new IllegalStateException(logloge("init() called in state " + mState));
}
// is there a spatializer?
mSpatCallback = new SpatializerCallback();
final ISpatializer spat = AudioSystem.getSpatializer(mSpatCallback);
if (spat == null) {
- Log.i(TAG, "init(): No Spatializer found");
+ loglogi("init(): No Spatializer found");
mState = STATE_NOT_SUPPORTED;
return;
}
@@ -201,14 +201,14 @@ public class SpatializerHelper {
|| levels.length == 0
|| (levels.length == 1
&& levels[0] == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE)) {
- Log.e(TAG, "Spatializer is useless");
+ logloge("init(): found Spatializer is useless");
mState = STATE_NOT_SUPPORTED;
return;
}
for (byte level : levels) {
- logd("found support for level: " + level);
+ loglogi("init(): found support for level: " + level);
if (level == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL) {
- logd("Setting capable level to LEVEL_MULTICHANNEL");
+ loglogi("init(): setting capable level to LEVEL_MULTICHANNEL");
mCapableSpatLevel = level;
break;
}
@@ -223,7 +223,7 @@ public class SpatializerHelper {
mTransauralSupported = true;
break;
default:
- Log.e(TAG, "Spatializer reports unknown supported mode:" + mode);
+ logloge("init(): Spatializer reports unknown supported mode:" + mode);
break;
}
}
@@ -277,7 +277,7 @@ public class SpatializerHelper {
* @param featureEnabled
*/
synchronized void reset(boolean featureEnabled) {
- Log.i(TAG, "Resetting");
+ loglogi("Resetting featureEnabled=" + featureEnabled);
releaseSpat();
mState = STATE_UNINITIALIZED;
mSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
@@ -318,23 +318,24 @@ public class SpatializerHelper {
if (enabledAvailable.second) {
// available for Spatial audio, check w/ effect
able = canBeSpatializedOnDevice(DEFAULT_ATTRIBUTES, DEFAULT_FORMAT, ROUTING_DEVICES);
- Log.i(TAG, "onRoutingUpdated: can spatialize media 5.1:" + able
+ loglogi("onRoutingUpdated: can spatialize media 5.1:" + able
+ " on device:" + ROUTING_DEVICES[0]);
setDispatchAvailableState(able);
} else {
- Log.i(TAG, "onRoutingUpdated: device:" + ROUTING_DEVICES[0]
+ loglogi("onRoutingUpdated: device:" + ROUTING_DEVICES[0]
+ " not available for Spatial Audio");
setDispatchAvailableState(false);
}
if (able && enabledAvailable.first) {
- Log.i(TAG, "Enabling Spatial Audio since enabled for media device:"
+ loglogi("Enabling Spatial Audio since enabled for media device:"
+ ROUTING_DEVICES[0]);
} else {
- Log.i(TAG, "Disabling Spatial Audio since disabled for media device:"
+ loglogi("Disabling Spatial Audio since disabled for media device:"
+ ROUTING_DEVICES[0]);
}
- setDispatchFeatureEnabledState(able && enabledAvailable.first);
+ setDispatchFeatureEnabledState(able && enabledAvailable.first,
+ "onRoutingUpdated");
if (mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED
&& mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_DISABLED) {
@@ -347,7 +348,7 @@ public class SpatializerHelper {
private final class SpatializerCallback extends INativeSpatializerCallback.Stub {
public void onLevelChanged(byte level) {
- logd("SpatializerCallback.onLevelChanged level:" + level);
+ loglogi("SpatializerCallback.onLevelChanged level:" + level);
synchronized (SpatializerHelper.this) {
mSpatLevel = spatializationLevelToSpatializerInt(level);
}
@@ -358,7 +359,7 @@ public class SpatializerHelper {
}
public void onOutputChanged(int output) {
- logd("SpatializerCallback.onOutputChanged output:" + output);
+ loglogi("SpatializerCallback.onOutputChanged output:" + output);
int oldOutput;
synchronized (SpatializerHelper.this) {
oldOutput = mSpatOutput;
@@ -374,20 +375,21 @@ public class SpatializerHelper {
// spatializer head tracking callback from native
private final class SpatializerHeadTrackingCallback
extends ISpatializerHeadTrackingCallback.Stub {
- public void onHeadTrackingModeChanged(byte mode) {
- logd("SpatializerHeadTrackingCallback.onHeadTrackingModeChanged mode:" + mode);
+ public void onHeadTrackingModeChanged(byte mode) {
int oldMode, newMode;
synchronized (this) {
oldMode = mActualHeadTrackingMode;
mActualHeadTrackingMode = headTrackingModeTypeToSpatializerInt(mode);
newMode = mActualHeadTrackingMode;
}
+ loglogi("SpatializerHeadTrackingCallback.onHeadTrackingModeChanged mode:"
+ + Spatializer.headtrackingModeToString(newMode));
if (oldMode != newMode) {
dispatchActualHeadTrackingMode(newMode);
}
}
- public void onHeadToSoundStagePoseUpdated(float[] headToStage) {
+ public void onHeadToSoundStagePoseUpdated(float[] headToStage) {
if (headToStage == null) {
Log.e(TAG, "SpatializerHeadTrackingCallback.onHeadToStagePoseUpdated"
+ "null transform");
@@ -404,7 +406,8 @@ public class SpatializerHelper {
for (float val : headToStage) {
t.append("[").append(String.format(Locale.ENGLISH, "%.3f", val)).append("]");
}
- logd("SpatializerHeadTrackingCallback.onHeadToStagePoseUpdated headToStage:" + t);
+ loglogi("SpatializerHeadTrackingCallback.onHeadToStagePoseUpdated headToStage:"
+ + t);
}
dispatchPoseUpdate(headToStage);
}
@@ -444,10 +447,9 @@ public class SpatializerHelper {
}
synchronized void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
- // TODO add log
+ loglogi("addCompatibleAudioDevice: dev=" + ada);
final int deviceType = ada.getType();
final boolean wireless = isWireless(deviceType);
- boolean updateRouting = false;
boolean isInList = false;
for (SADeviceState deviceState : mSADevices) {
@@ -455,8 +457,6 @@ public class SpatializerHelper {
&& (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
|| !wireless) {
isInList = true;
- // state change?
- updateRouting = !deviceState.mEnabled;
deviceState.mEnabled = true;
break;
}
@@ -466,32 +466,24 @@ public class SpatializerHelper {
wireless ? ada.getAddress() : null);
dev.mEnabled = true;
mSADevices.add(dev);
- updateRouting = true;
- }
- if (updateRouting) {
- onRoutingUpdated();
}
+ onRoutingUpdated();
}
synchronized void removeCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
- // TODO add log
+ loglogi("removeCompatibleAudioDevice: dev=" + ada);
final int deviceType = ada.getType();
final boolean wireless = isWireless(deviceType);
- boolean updateRouting = false;
for (SADeviceState deviceState : mSADevices) {
if (deviceType == deviceState.mDeviceType
&& (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
|| !wireless) {
- // state change?
- updateRouting = deviceState.mEnabled;
deviceState.mEnabled = false;
break;
}
}
- if (updateRouting) {
- onRoutingUpdated();
- }
+ onRoutingUpdated();
}
/**
@@ -629,6 +621,7 @@ public class SpatializerHelper {
}
synchronized void setFeatureEnabled(boolean enabled) {
+ loglogi("setFeatureEnabled(" + enabled + ") was featureEnabled:" + mFeatureEnabled);
if (mFeatureEnabled == enabled) {
return;
}
@@ -652,7 +645,7 @@ public class SpatializerHelper {
switch (mState) {
case STATE_UNINITIALIZED:
if (enabled) {
- throw(new IllegalStateException("Can't enable when uninitialized"));
+ throw (new IllegalStateException("Can't enable when uninitialized"));
}
return;
case STATE_NOT_SUPPORTED:
@@ -679,7 +672,7 @@ public class SpatializerHelper {
return;
}
}
- setDispatchFeatureEnabledState(enabled);
+ setDispatchFeatureEnabledState(enabled, "setSpatializerEnabledInt");
}
synchronized int getCapableImmersiveAudioLevel() {
@@ -703,7 +696,8 @@ public class SpatializerHelper {
* Update the feature state, no-op if no change
* @param featureEnabled
*/
- private synchronized void setDispatchFeatureEnabledState(boolean featureEnabled) {
+ private synchronized void setDispatchFeatureEnabledState(boolean featureEnabled, String source)
+ {
if (featureEnabled) {
switch (mState) {
case STATE_DISABLED_UNAVAILABLE:
@@ -715,9 +709,12 @@ public class SpatializerHelper {
case STATE_ENABLED_AVAILABLE:
case STATE_ENABLED_UNAVAILABLE:
// already enabled: no-op
+ loglogi("setDispatchFeatureEnabledState(" + featureEnabled
+ + ") no dispatch: mState:"
+ + spatStateString(mState) + " src:" + source);
return;
default:
- throw(new IllegalStateException("Invalid mState:" + mState
+ throw (new IllegalStateException("Invalid mState:" + mState
+ " for enabled true"));
}
} else {
@@ -731,12 +728,17 @@ public class SpatializerHelper {
case STATE_DISABLED_AVAILABLE:
case STATE_DISABLED_UNAVAILABLE:
// already disabled: no-op
+ loglogi("setDispatchFeatureEnabledState(" + featureEnabled
+ + ") no dispatch: mState:" + spatStateString(mState)
+ + " src:" + source);
return;
default:
throw (new IllegalStateException("Invalid mState:" + mState
+ " for enabled false"));
}
}
+ loglogi("setDispatchFeatureEnabledState(" + featureEnabled
+ + ") mState:" + spatStateString(mState));
final int nbCallbacks = mStateCallbacks.beginBroadcast();
for (int i = 0; i < nbCallbacks; i++) {
try {
@@ -747,14 +749,13 @@ public class SpatializerHelper {
}
}
mStateCallbacks.finishBroadcast();
- mAudioService.persistSpatialAudioEnabled(featureEnabled);
}
private synchronized void setDispatchAvailableState(boolean available) {
switch (mState) {
case STATE_UNINITIALIZED:
case STATE_NOT_SUPPORTED:
- throw(new IllegalStateException(
+ throw (new IllegalStateException(
"Should not update available state in state:" + mState));
case STATE_DISABLED_UNAVAILABLE:
if (available) {
@@ -762,6 +763,8 @@ public class SpatializerHelper {
break;
} else {
// already in unavailable state
+ loglogi("setDispatchAvailableState(" + available
+ + ") no dispatch: mState:" + spatStateString(mState));
return;
}
case STATE_ENABLED_UNAVAILABLE:
@@ -770,11 +773,15 @@ public class SpatializerHelper {
break;
} else {
// already in unavailable state
+ loglogi("setDispatchAvailableState(" + available
+ + ") no dispatch: mState:" + spatStateString(mState));
return;
}
case STATE_DISABLED_AVAILABLE:
if (available) {
// already in available state
+ loglogi("setDispatchAvailableState(" + available
+ + ") no dispatch: mState:" + spatStateString(mState));
return;
} else {
mState = STATE_DISABLED_UNAVAILABLE;
@@ -783,12 +790,15 @@ public class SpatializerHelper {
case STATE_ENABLED_AVAILABLE:
if (available) {
// already in available state
+ loglogi("setDispatchAvailableState(" + available
+ + ") no dispatch: mState:" + spatStateString(mState));
return;
} else {
mState = STATE_ENABLED_UNAVAILABLE;
break;
}
}
+ loglogi("setDispatchAvailableState(" + available + ") mState:" + spatStateString(mState));
final int nbCallbacks = mStateCallbacks.beginBroadcast();
for (int i = 0; i < nbCallbacks; i++) {
try {
@@ -813,7 +823,7 @@ public class SpatializerHelper {
mSpatHeadTrackingCallback = new SpatializerHeadTrackingCallback();
mSpat = AudioSystem.getSpatializer(mSpatCallback);
try {
- mSpat.setLevel((byte) Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL);
+ mSpat.setLevel((byte) Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL);
mIsHeadTrackingSupported = mSpat.isHeadTrackingSupported();
//TODO: register heatracking callback only when sensors are registered
if (mIsHeadTrackingSupported) {
@@ -851,8 +861,6 @@ public class SpatializerHelper {
// virtualization capabilities
synchronized boolean canBeSpatialized(
@NonNull AudioAttributes attributes, @NonNull AudioFormat format) {
- logd("canBeSpatialized usage:" + attributes.getUsage()
- + " format:" + format.toLogFriendlyString());
switch (mState) {
case STATE_UNINITIALIZED:
case STATE_NOT_SUPPORTED:
@@ -879,7 +887,8 @@ public class SpatializerHelper {
mASA.getDevicesForAttributes(
attributes, false /* forVolume */).toArray(devices);
final boolean able = canBeSpatializedOnDevice(attributes, format, devices);
- logd("canBeSpatialized returning " + able);
+ logd("canBeSpatialized usage:" + attributes.getUsage()
+ + " format:" + format.toLogFriendlyString() + " returning " + able);
return able;
}
@@ -1316,11 +1325,11 @@ public class SpatializerHelper {
final boolean init = mFeatureEnabled && (mSpatLevel != SpatializationLevel.NONE);
final String action = init ? "initializing" : "releasing";
if (mSpat == null) {
- Log.e(TAG, "not " + action + " sensors, null spatializer");
+ logloge("not " + action + " sensors, null spatializer");
return;
}
if (!mIsHeadTrackingSupported) {
- Log.e(TAG, "not " + action + " sensors, spatializer doesn't support headtracking");
+ logloge("not " + action + " sensors, spatializer doesn't support headtracking");
return;
}
int headHandle = -1;
@@ -1345,7 +1354,7 @@ public class SpatializerHelper {
// does this happen before routing is updated?
// avoid by supporting adding device here AND in onRoutingUpdated()
headHandle = getHeadSensorHandleUpdateTracker();
- Log.i(TAG, "head tracker sensor handle initialized to " + headHandle);
+ loglogi("head tracker sensor handle initialized to " + headHandle);
screenHandle = getScreenSensorHandle();
Log.i(TAG, "found screen sensor handle initialized to " + screenHandle);
} else {
@@ -1388,7 +1397,7 @@ public class SpatializerHelper {
case SpatializerHeadTrackingMode.RELATIVE_SCREEN:
return Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE;
default:
- throw(new IllegalArgumentException("Unexpected head tracking mode:" + mode));
+ throw (new IllegalArgumentException("Unexpected head tracking mode:" + mode));
}
}
@@ -1403,7 +1412,7 @@ public class SpatializerHelper {
case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE:
return SpatializerHeadTrackingMode.RELATIVE_SCREEN;
default:
- throw(new IllegalArgumentException("Unexpected head tracking mode:" + sdkMode));
+ throw (new IllegalArgumentException("Unexpected head tracking mode:" + sdkMode));
}
}
@@ -1416,7 +1425,7 @@ public class SpatializerHelper {
case SpatializationLevel.SPATIALIZER_MCHAN_BED_PLUS_OBJECTS:
return Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MCHAN_BED_PLUS_OBJECTS;
default:
- throw(new IllegalArgumentException("Unexpected spatializer level:" + level));
+ throw (new IllegalArgumentException("Unexpected spatializer level:" + level));
}
}
@@ -1429,18 +1438,19 @@ public class SpatializerHelper {
+ Spatializer.headtrackingModeToString(mActualHeadTrackingMode));
pw.println("\tmDesiredHeadTrackingMode:"
+ Spatializer.headtrackingModeToString(mDesiredHeadTrackingMode));
- String modesString = "";
+ pw.println("\tsupports binaural:" + mBinauralSupported + " / transaural:"
+ + mTransauralSupported);
+ StringBuilder modesString = new StringBuilder();
int[] modes = getSupportedHeadTrackingModes();
for (int mode : modes) {
- modesString += Spatializer.headtrackingModeToString(mode) + " ";
+ modesString.append(Spatializer.headtrackingModeToString(mode)).append(" ");
}
- pw.println("\tsupports binaural:" + mBinauralSupported + " / transaural"
- + mTransauralSupported);
pw.println("\tsupported head tracking modes:" + modesString);
+ pw.println("\theadtracker available:" + mHeadTrackerAvailable);
pw.println("\tmSpatOutput:" + mSpatOutput);
- pw.println("\tdevices:\n");
+ pw.println("\tdevices:");
for (SADeviceState device : mSADevices) {
- pw.println("\t\t" + device + "\n");
+ pw.println("\t\t" + device);
}
}
@@ -1463,6 +1473,25 @@ public class SpatializerHelper {
}
}
+ private static String spatStateString(int state) {
+ switch (state) {
+ case STATE_UNINITIALIZED:
+ return "STATE_UNINITIALIZED";
+ case STATE_NOT_SUPPORTED:
+ return "STATE_NOT_SUPPORTED";
+ case STATE_DISABLED_UNAVAILABLE:
+ return "STATE_DISABLED_UNAVAILABLE";
+ case STATE_ENABLED_UNAVAILABLE:
+ return "STATE_ENABLED_UNAVAILABLE";
+ case STATE_ENABLED_AVAILABLE:
+ return "STATE_ENABLED_AVAILABLE";
+ case STATE_DISABLED_AVAILABLE:
+ return "STATE_DISABLED_AVAILABLE";
+ default:
+ return "invalid state";
+ }
+ }
+
private static boolean isWireless(int deviceType) {
for (int type : WIRELESS_TYPES) {
if (type == deviceType) {
@@ -1473,7 +1502,7 @@ public class SpatializerHelper {
}
private static boolean isWirelessSpeaker(int deviceType) {
- for (int type: WIRELESS_SPEAKER_TYPES) {
+ for (int type : WIRELESS_SPEAKER_TYPES) {
if (type == deviceType) {
return true;
}
@@ -1515,4 +1544,14 @@ public class SpatializerHelper {
}
return screenHandle;
}
+
+
+ private static void loglogi(String msg) {
+ AudioService.sSpatialLogger.loglogi(msg, TAG);
+ }
+
+ private static String logloge(String msg) {
+ AudioService.sSpatialLogger.loglog(msg, AudioEventLogger.Event.ALOGE, TAG);
+ return msg;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index bf69284df2f6..cc49f07dd0e5 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -462,7 +462,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
mState = STATE_SHOWING_DEVICE_CREDENTIAL;
mStatusBarService.onBiometricError(modality, error, vendorCode);
} else if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
- mStatusBarService.hideAuthenticationDialog();
+ mStatusBarService.hideAuthenticationDialog(mRequestId);
// TODO: If multiple authenticators are simultaneously running, this will
// need to be modified. Send the error to the client here, instead of doing
// a round trip to SystemUI.
@@ -480,7 +480,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
// the client and clean up. The only error we should get here is
// ERROR_CANCELED due to another client kicking us out.
mClientReceiver.onError(modality, error, vendorCode);
- mStatusBarService.hideAuthenticationDialog();
+ mStatusBarService.hideAuthenticationDialog(mRequestId);
return true;
}
@@ -489,7 +489,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
break;
case STATE_CLIENT_DIED_CANCELLING:
- mStatusBarService.hideAuthenticationDialog();
+ mStatusBarService.hideAuthenticationDialog(mRequestId);
return true;
default:
@@ -665,7 +665,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
cancelAllSensors();
return false;
default:
- mStatusBarService.hideAuthenticationDialog();
+ mStatusBarService.hideAuthenticationDialog(mRequestId);
return true;
}
} catch (RemoteException e) {
@@ -832,7 +832,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
BiometricConstants.BIOMETRIC_ERROR_CANCELED,
0 /* vendorCode */
);
- mStatusBarService.hideAuthenticationDialog();
+ mStatusBarService.hideAuthenticationDialog(mRequestId);
return true;
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
index 2a8d9f1967eb..ad24cf0591ca 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
@@ -53,14 +53,26 @@ public class BiometricLogger {
private boolean mShouldLogMetrics = true;
private class ALSProbe implements Probe {
+ private boolean mDestroyed = false;
+
+ @Override
+ public synchronized void enable() {
+ if (!mDestroyed) {
+ setLightSensorLoggingEnabled(getAmbientLightSensor(mSensorManager));
+ }
+ }
+
@Override
- public void enable() {
- setLightSensorLoggingEnabled(getAmbientLightSensor(mSensorManager));
+ public synchronized void disable() {
+ if (!mDestroyed) {
+ setLightSensorLoggingEnabled(null);
+ }
}
@Override
- public void disable() {
- setLightSensorLoggingEnabled(null);
+ public synchronized void destroy() {
+ disable();
+ mDestroyed = true;
}
}
diff --git a/services/core/java/com/android/server/biometrics/log/CallbackWithProbe.java b/services/core/java/com/android/server/biometrics/log/CallbackWithProbe.java
index f7b736885f71..93ff2a8cff97 100644
--- a/services/core/java/com/android/server/biometrics/log/CallbackWithProbe.java
+++ b/services/core/java/com/android/server/biometrics/log/CallbackWithProbe.java
@@ -46,7 +46,7 @@ public class CallbackWithProbe<T extends Probe> implements ClientMonitorCallback
@Override
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {
- mProbe.disable();
+ mProbe.destroy();
}
@NonNull
diff --git a/services/core/java/com/android/server/biometrics/log/Probe.java b/services/core/java/com/android/server/biometrics/log/Probe.java
index 9e6fc6b8b8b2..d1056a42b257 100644
--- a/services/core/java/com/android/server/biometrics/log/Probe.java
+++ b/services/core/java/com/android/server/biometrics/log/Probe.java
@@ -27,4 +27,6 @@ public interface Probe {
void enable();
/** Stop sampling data. */
void disable();
+ /** Same as {@link #disable()} and ignores all future calls to this probe. */
+ void destroy();
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/LockoutCache.java b/services/core/java/com/android/server/biometrics/sensors/LockoutCache.java
index 0aba29557b20..95c49032c029 100644
--- a/services/core/java/com/android/server/biometrics/sensors/LockoutCache.java
+++ b/services/core/java/com/android/server/biometrics/sensors/LockoutCache.java
@@ -16,12 +16,14 @@
package com.android.server.biometrics.sensors;
+import android.util.Slog;
import android.util.SparseIntArray;
/**
* For a single sensor, caches lockout states for all users.
*/
public class LockoutCache implements LockoutTracker {
+ private static final String TAG = "LockoutCache";
// Map of userId to LockoutMode
private final SparseIntArray mUserLockoutStates;
@@ -31,6 +33,7 @@ public class LockoutCache implements LockoutTracker {
}
public void setLockoutModeForUser(int userId, @LockoutMode int mode) {
+ Slog.d(TAG, "Lockout for user: " + userId + " is " + mode);
synchronized (this) {
mUserLockoutStates.put(userId, mode);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/LockoutTracker.java b/services/core/java/com/android/server/biometrics/sensors/LockoutTracker.java
index fa386d073035..4a59c9df9bef 100644
--- a/services/core/java/com/android/server/biometrics/sensors/LockoutTracker.java
+++ b/services/core/java/com/android/server/biometrics/sensors/LockoutTracker.java
@@ -17,6 +17,7 @@
package com.android.server.biometrics.sensors;
import android.annotation.IntDef;
+import android.hardware.biometrics.BiometricConstants;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -25,9 +26,9 @@ import java.lang.annotation.RetentionPolicy;
* Interface for retrieval of current user's lockout state.
*/
public interface LockoutTracker {
- int LOCKOUT_NONE = 0;
- int LOCKOUT_TIMED = 1;
- int LOCKOUT_PERMANENT = 2;
+ int LOCKOUT_NONE = BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
+ int LOCKOUT_TIMED = BiometricConstants.BIOMETRIC_LOCKOUT_TIMED;
+ int LOCKOUT_PERMANENT = BiometricConstants.BIOMETRIC_LOCKOUT_PERMANENT;
@Retention(RetentionPolicy.SOURCE)
@IntDef({LOCKOUT_NONE, LOCKOUT_TIMED, LOCKOUT_PERMANENT})
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 b69c7600e75a..800d4b8acf61 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
@@ -18,6 +18,9 @@ package com.android.server.biometrics.sensors.face.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.SynchronousUserSwitchObserver;
+import android.app.UserSwitchObserver;
import android.content.Context;
import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricsProtoEnums;
@@ -91,6 +94,14 @@ public class Sensor {
@NonNull private final Supplier<AidlSession> mLazySession;
@Nullable private AidlSession mCurrentSession;
+ private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
+ @Override
+ public void onUserSwitching(int newUserId) {
+ mProvider.scheduleInternalCleanup(
+ mSensorProperties.sensorId, newUserId, null /* callback */);
+ }
+ };
+
@VisibleForTesting
public static class HalSessionCallback extends ISessionCallback.Stub {
/**
@@ -537,6 +548,12 @@ public class Sensor {
mLockoutCache = new LockoutCache();
mAuthenticatorIds = new HashMap<>();
mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
+
+ try {
+ ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, mTag);
+ } catch (RemoteException e) {
+ Slog.e(mTag, "Unable to register user switch observer");
+ }
}
@NonNull Supplier<AidlSession> getLazySession() {
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 63e345e40ad7..024d611732c1 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
@@ -18,6 +18,9 @@ package com.android.server.biometrics.sensors.fingerprint.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.SynchronousUserSwitchObserver;
+import android.app.UserSwitchObserver;
import android.content.Context;
import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricsProtoEnums;
@@ -92,6 +95,14 @@ public class Sensor {
@Nullable private AidlSession mCurrentSession;
@NonNull private final Supplier<AidlSession> mLazySession;
+ private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
+ @Override
+ public void onUserSwitching(int newUserId) {
+ mProvider.scheduleInternalCleanup(
+ mSensorProperties.sensorId, newUserId, null /* callback */);
+ }
+ };
+
@VisibleForTesting
public static class HalSessionCallback extends ISessionCallback.Stub {
@@ -491,6 +502,12 @@ public class Sensor {
});
mAuthenticatorIds = new HashMap<>();
mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
+
+ try {
+ ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, mTag);
+ } catch (RemoteException e) {
+ Slog.e(mTag, "Unable to register user switch observer");
+ }
}
@NonNull Supplier<AidlSession> getLazySession() {
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 162eb0e188b9..54e83ec5303a 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -535,11 +535,11 @@ class AutomaticBrightnessController {
pw.println(" Idle mode active=" + mCurrentBrightnessMapper.isForIdleMode());
pw.println();
- pw.println(" mActiveMapper=");
- mInteractiveModeBrightnessMapper.dump(pw);
+ pw.println(" mInteractiveMapper=");
+ mInteractiveModeBrightnessMapper.dump(pw, mHbmController.getNormalBrightnessMax());
if (mIdleModeBrightnessMapper != null) {
pw.println(" mIdleMapper=");
- mIdleModeBrightnessMapper.dump(pw);
+ mIdleModeBrightnessMapper.dump(pw, mHbmController.getNormalBrightnessMax());
}
pw.println();
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index c46ae851b752..38de9a73a511 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -358,7 +358,10 @@ public abstract class BrightnessMappingStrategy {
*/
public abstract long getShortTermModelTimeout();
- public abstract void dump(PrintWriter pw);
+ /**
+ * Prints dump output for display dumpsys.
+ */
+ public abstract void dump(PrintWriter pw, float hbmTransition);
/**
* We can designate a mapping strategy to be used for idle screen brightness mode.
@@ -714,7 +717,7 @@ public abstract class BrightnessMappingStrategy {
}
@Override
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, float hbmTransition) {
pw.println("SimpleMappingStrategy");
pw.println(" mSpline=" + mSpline);
pw.println(" mMaxGamma=" + mMaxGamma);
@@ -947,7 +950,7 @@ public abstract class BrightnessMappingStrategy {
}
@Override
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, float hbmTransition) {
pw.println("PhysicalMappingStrategy");
pw.println(" mConfig=" + mConfig);
pw.println(" mBrightnessSpline=" + mBrightnessSpline);
@@ -959,6 +962,8 @@ public abstract class BrightnessMappingStrategy {
pw.println(" mUserBrightness=" + mUserBrightness);
pw.println(" mDefaultConfig=" + mDefaultConfig);
pw.println(" mBrightnessRangeAdjustmentApplied=" + mBrightnessRangeAdjustmentApplied);
+
+ dumpConfigDiff(pw, hbmTransition);
}
@Override
@@ -966,6 +971,117 @@ public abstract class BrightnessMappingStrategy {
return mIsForIdleMode;
}
+ /**
+ * Prints out the default curve and how it differs from the long-term curve
+ * and the current curve (in case the current curve includes short-term adjustments).
+ *
+ * @param pw The print-writer to write to.
+ */
+ private void dumpConfigDiff(PrintWriter pw, float hbmTransition) {
+ pw.println(" Difference between current config and default: ");
+
+ Pair<float[], float[]> currentCurve = mConfig.getCurve();
+ Spline currSpline = Spline.createSpline(currentCurve.first, currentCurve.second);
+
+ Pair<float[], float[]> defaultCurve = mDefaultConfig.getCurve();
+ Spline defaultSpline = Spline.createSpline(defaultCurve.first, defaultCurve.second);
+
+ // Add the short-term curve lux point if present
+ float[] luxes = currentCurve.first;
+ if (mUserLux >= 0) {
+ luxes = Arrays.copyOf(currentCurve.first, currentCurve.first.length + 1);
+ luxes[luxes.length - 1] = mUserLux;
+ Arrays.sort(luxes);
+ }
+
+ StringBuffer sbLux = null;
+ StringBuffer sbNits = null;
+ StringBuffer sbLong = null;
+ StringBuffer sbShort = null;
+ StringBuffer sbBrightness = null;
+ StringBuffer sbPercent = null;
+ StringBuffer sbPercentHbm = null;
+ boolean needsHeaders = true;
+ String separator = "";
+ for (int i = 0; i < luxes.length; i++) {
+ float lux = luxes[i];
+ if (needsHeaders) {
+ sbLux = new StringBuffer(" lux: ");
+ sbNits = new StringBuffer(" default: ");
+ sbLong = new StringBuffer(" long-term: ");
+ sbShort = new StringBuffer(" current: ");
+ sbBrightness = new StringBuffer(" current(bl): ");
+ sbPercent = new StringBuffer(" current(%): ");
+ sbPercentHbm = new StringBuffer(" current(%hbm): ");
+ needsHeaders = false;
+ }
+
+ float defaultNits = defaultSpline.interpolate(lux);
+ float longTermNits = currSpline.interpolate(lux);
+ float shortTermNits = mBrightnessSpline.interpolate(lux);
+ float brightness = mNitsToBrightnessSpline.interpolate(shortTermNits);
+
+ String luxPrefix = (lux == mUserLux ? "^" : "");
+ String strLux = luxPrefix + toStrFloatForDump(lux);
+ String strNits = toStrFloatForDump(defaultNits);
+ String strLong = toStrFloatForDump(longTermNits);
+ String strShort = toStrFloatForDump(shortTermNits);
+ String strBrightness = toStrFloatForDump(brightness);
+ String strPercent = String.valueOf(
+ Math.round(100.0f * BrightnessUtils.convertLinearToGamma(
+ (brightness / hbmTransition))));
+ String strPercentHbm = String.valueOf(
+ Math.round(100.0f * BrightnessUtils.convertLinearToGamma(brightness)));
+
+ int maxLen = Math.max(strLux.length(),
+ Math.max(strNits.length(),
+ Math.max(strBrightness.length(),
+ Math.max(strPercent.length(),
+ Math.max(strPercentHbm.length(),
+ Math.max(strLong.length(), strShort.length()))))));
+ String format = separator + "%" + maxLen + "s";
+ separator = ", ";
+
+ sbLux.append(String.format(format, strLux));
+ sbNits.append(String.format(format, strNits));
+ sbLong.append(String.format(format, strLong));
+ sbShort.append(String.format(format, strShort));
+ sbBrightness.append(String.format(format, strBrightness));
+ sbPercent.append(String.format(format, strPercent));
+ sbPercentHbm.append(String.format(format, strPercentHbm));
+
+ // At 80 chars, start another row
+ if (sbLux.length() > 80 || (i == luxes.length - 1)) {
+ pw.println(sbLux);
+ pw.println(sbNits);
+ pw.println(sbLong);
+ pw.println(sbShort);
+ pw.println(sbBrightness);
+ pw.println(sbPercent);
+ if (hbmTransition < PowerManager.BRIGHTNESS_MAX) {
+ pw.println(sbPercentHbm);
+ }
+ pw.println("");
+ needsHeaders = true;
+ separator = "";
+ }
+ }
+ }
+
+ private String toStrFloatForDump(float value) {
+ if (value == 0.0f) {
+ return "0";
+ } else if (value < 0.1f) {
+ return String.format("%.3f", value);
+ } else if (value < 1) {
+ return String.format("%.2f", value);
+ } else if (value < 10) {
+ return String.format("%.1f", value);
+ } else {
+ return String.format("%d", Math.round(value));
+ }
+ }
+
private void computeNitsBrightnessSplines(float[] nits) {
mNitsToBrightnessSpline = Spline.createSpline(nits, mBrightness);
mBrightnessToNitsSpline = Spline.createSpline(mBrightness, nits);
diff --git a/services/core/java/com/android/server/display/DensityMap.java b/services/core/java/com/android/server/display/DensityMapping.java
index 4aafd148a6dd..deca9878f280 100644
--- a/services/core/java/com/android/server/display/DensityMap.java
+++ b/services/core/java/com/android/server/display/DensityMapping.java
@@ -23,31 +23,32 @@ import java.util.Comparator;
* Class which can compute the logical density for a display resolution. It holds a collection
* of pre-configured densities, which are used for look-up and interpolation.
*/
-public class DensityMap {
+public class DensityMapping {
// Instead of resolutions we store the squared diagonal size. Diagonals make the map
// keys invariant to rotations and are useful for interpolation because they're scalars.
// Squared diagonals have the same properties as diagonals (the square function is monotonic)
// but also allow us to use integer types and avoid floating point arithmetics.
- private final Entry[] mSortedDensityMapEntries;
+ private final Entry[] mSortedDensityMappingEntries;
/**
- * Creates a density map. The newly created object takes ownership of the passed array.
+ * Creates a density mapping. The newly created object takes ownership of the passed array.
*/
- static DensityMap createByOwning(Entry[] densityMapEntries) {
- return new DensityMap(densityMapEntries);
+ static DensityMapping createByOwning(Entry[] densityMappingEntries) {
+ return new DensityMapping(densityMappingEntries);
}
- private DensityMap(Entry[] densityMapEntries) {
- Arrays.sort(densityMapEntries, Comparator.comparingInt(entry -> entry.squaredDiagonal));
- mSortedDensityMapEntries = densityMapEntries;
- verifyDensityMap(mSortedDensityMapEntries);
+ private DensityMapping(Entry[] densityMappingEntries) {
+ Arrays.sort(densityMappingEntries, Comparator.comparingInt(
+ entry -> entry.squaredDiagonal));
+ mSortedDensityMappingEntries = densityMappingEntries;
+ verifyDensityMapping(mSortedDensityMappingEntries);
}
/**
* Returns the logical density for the given resolution.
*
- * If the resolution matches one of the entries in the map, the corresponding density is
+ * If the resolution matches one of the entries in the mapping, the corresponding density is
* returned. Otherwise the return value is interpolated using the closest entries in the map.
*/
public int getDensityForResolution(int width, int height) {
@@ -61,7 +62,7 @@ public class DensityMap {
Entry left = Entry.ZEROES;
Entry right = null;
- for (Entry entry : mSortedDensityMapEntries) {
+ for (Entry entry : mSortedDensityMappingEntries) {
if (entry.squaredDiagonal <= squaredDiagonal) {
left = entry;
} else {
@@ -90,7 +91,7 @@ public class DensityMap {
/ (rightDiagonal - leftDiagonal) + left.density);
}
- private static void verifyDensityMap(Entry[] sortedEntries) {
+ private static void verifyDensityMapping(Entry[] sortedEntries) {
for (int i = 1; i < sortedEntries.length; i++) {
Entry prev = sortedEntries[i - 1];
Entry curr = sortedEntries[i];
@@ -100,10 +101,10 @@ public class DensityMap {
// resolution (AxB and AxB) or rotated resolution (AxB and BxA), but it can also
// happen in the very rare cases when two different resolutions happen to have
// the same diagonal (e.g. 100x700 and 500x500).
- throw new IllegalStateException("Found two entries in the density map with"
+ throw new IllegalStateException("Found two entries in the density mapping with"
+ " the same diagonal: " + prev + ", " + curr);
} else if (prev.density > curr.density) {
- throw new IllegalStateException("Found two entries in the density map with"
+ throw new IllegalStateException("Found two entries in the density mapping with"
+ " increasing diagonal but decreasing density: " + prev + ", " + curr);
}
}
@@ -111,8 +112,8 @@ public class DensityMap {
@Override
public String toString() {
- return "DensityMap{"
- + "mDensityMapEntries=" + Arrays.toString(mSortedDensityMapEntries)
+ return "DensityMapping{"
+ + "mDensityMappingEntries=" + Arrays.toString(mSortedDensityMappingEntries)
+ '}';
}
@@ -129,7 +130,7 @@ public class DensityMap {
@Override
public String toString() {
- return "DensityMapEntry{"
+ return "DensityMappingEntry{"
+ "squaredDiagonal=" + squaredDiagonal
+ ", density=" + density + '}';
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index d12c6219b67f..ed05aa67506a 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -272,7 +272,7 @@ public class DisplayDeviceConfig {
private List<String> mQuirks;
private boolean mIsHighBrightnessModeEnabled = false;
private HighBrightnessModeData mHbmData;
- private DensityMap mDensityMap;
+ private DensityMapping mDensityMapping;
private String mLoadedFrom = null;
private BrightnessThrottlingData mBrightnessThrottlingData;
@@ -592,8 +592,8 @@ public class DisplayDeviceConfig {
return mRefreshRateLimitations;
}
- public DensityMap getDensityMap() {
- return mDensityMap;
+ public DensityMapping getDensityMapping() {
+ return mDensityMapping;
}
/**
@@ -637,7 +637,7 @@ public class DisplayDeviceConfig {
+ ", mAmbientLightSensor=" + mAmbientLightSensor
+ ", mProximitySensor=" + mProximitySensor
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
- + ", mDensityMap= " + mDensityMap
+ + ", mDensityMapping= " + mDensityMapping
+ "}";
}
@@ -681,7 +681,7 @@ public class DisplayDeviceConfig {
try (InputStream in = new BufferedInputStream(new FileInputStream(configFile))) {
final DisplayConfiguration config = XmlParser.read(in);
if (config != null) {
- loadDensityMap(config);
+ loadDensityMapping(config);
loadBrightnessDefaultFromDdcXml(config);
loadBrightnessConstraintsFromConfigXml();
loadBrightnessMap(config);
@@ -735,28 +735,28 @@ public class DisplayDeviceConfig {
return;
}
- if (mDensityMap == null) {
- loadDensityMap(defaultConfig);
+ if (mDensityMapping == null) {
+ loadDensityMapping(defaultConfig);
}
}
- private void loadDensityMap(DisplayConfiguration config) {
- if (config.getDensityMap() == null) {
+ private void loadDensityMapping(DisplayConfiguration config) {
+ if (config.getDensityMapping() == null) {
return;
}
- final List<Density> entriesFromXml = config.getDensityMap().getDensity();
+ final List<Density> entriesFromXml = config.getDensityMapping().getDensity();
- final DensityMap.Entry[] entries =
- new DensityMap.Entry[entriesFromXml.size()];
+ final DensityMapping.Entry[] entries =
+ new DensityMapping.Entry[entriesFromXml.size()];
for (int i = 0; i < entriesFromXml.size(); i++) {
final Density density = entriesFromXml.get(i);
- entries[i] = new DensityMap.Entry(
+ entries[i] = new DensityMapping.Entry(
density.getWidth().intValue(),
density.getHeight().intValue(),
density.getDensity().intValue());
}
- mDensityMap = DensityMap.createByOwning(entries);
+ mDensityMapping = DensityMapping.createByOwning(entries);
}
private void loadBrightnessDefaultFromDdcXml(DisplayConfiguration config) {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 932717a4a39d..5a105f551ab2 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2084,6 +2084,7 @@ public final class DisplayManagerService extends SystemService {
}
private SurfaceControl.ScreenshotHardwareBuffer systemScreenshotInternal(int displayId) {
+ final SurfaceControl.DisplayCaptureArgs captureArgs;
synchronized (mSyncRoot) {
final IBinder token = getDisplayToken(displayId);
if (token == null) {
@@ -2095,15 +2096,14 @@ public final class DisplayManagerService extends SystemService {
}
final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
- final SurfaceControl.DisplayCaptureArgs captureArgs =
- new SurfaceControl.DisplayCaptureArgs.Builder(token)
- .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight())
- .setUseIdentityTransform(true)
- .setCaptureSecureLayers(true)
- .setAllowProtected(true)
- .build();
- return SurfaceControl.captureDisplay(captureArgs);
- }
+ captureArgs = new SurfaceControl.DisplayCaptureArgs.Builder(token)
+ .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight())
+ .setUseIdentityTransform(true)
+ .setCaptureSecureLayers(true)
+ .setAllowProtected(true)
+ .build();
+ }
+ return SurfaceControl.captureDisplay(captureArgs);
}
private SurfaceControl.ScreenshotHardwareBuffer userScreenshotInternal(int displayId) {
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index efd2f6f1bfe1..ac72b1725432 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -2098,7 +2098,6 @@ public class DisplayModeDirector {
private class UdfpsObserver extends IUdfpsHbmListener.Stub {
private final SparseBooleanArray mLocalHbmEnabled = new SparseBooleanArray();
- private final SparseBooleanArray mGlobalHbmEnabled = new SparseBooleanArray();
public void observe() {
StatusBarManagerInternal statusBar =
@@ -2109,39 +2108,27 @@ public class DisplayModeDirector {
}
@Override
- public void onHbmEnabled(int hbmType, int displayId) {
+ public void onHbmEnabled(int displayId) {
synchronized (mLock) {
- updateHbmStateLocked(hbmType, displayId, true /*enabled*/);
+ updateHbmStateLocked(displayId, true /*enabled*/);
}
}
@Override
- public void onHbmDisabled(int hbmType, int displayId) {
+ public void onHbmDisabled(int displayId) {
synchronized (mLock) {
- updateHbmStateLocked(hbmType, displayId, false /*enabled*/);
+ updateHbmStateLocked(displayId, false /*enabled*/);
}
}
- private void updateHbmStateLocked(int hbmType, int displayId, boolean enabled) {
- switch (hbmType) {
- case UdfpsObserver.LOCAL_HBM:
- mLocalHbmEnabled.put(displayId, enabled);
- break;
- case UdfpsObserver.GLOBAL_HBM:
- mGlobalHbmEnabled.put(displayId, enabled);
- break;
- default:
- Slog.w(TAG, "Unknown HBM type reported. Ignoring.");
- return;
- }
+ private void updateHbmStateLocked(int displayId, boolean enabled) {
+ mLocalHbmEnabled.put(displayId, enabled);
updateVoteLocked(displayId);
}
private void updateVoteLocked(int displayId) {
final Vote vote;
- if (mGlobalHbmEnabled.get(displayId)) {
- vote = Vote.forRefreshRates(60f, 60f);
- } else if (mLocalHbmEnabled.get(displayId)) {
+ if (mLocalHbmEnabled.get(displayId)) {
Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
float maxRefreshRate = 0f;
for (Display.Mode mode : modes) {
@@ -2165,13 +2152,6 @@ public class DisplayModeDirector {
final String enabled = mLocalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
pw.println(" Display " + displayId + ": " + enabled);
}
- pw.println(" mGlobalHbmEnabled: ");
- for (int i = 0; i < mGlobalHbmEnabled.size(); i++) {
- final int displayId = mGlobalHbmEnabled.keyAt(i);
- final String enabled = mGlobalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
- pw.println(" Display " + displayId + ": " + enabled);
- }
-
}
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 633cb24f64e9..a155095c0725 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -469,12 +469,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
private int getLogicalDensity() {
- DensityMap densityMap = getDisplayDeviceConfig().getDensityMap();
- if (densityMap == null) {
+ DensityMapping densityMapping = getDisplayDeviceConfig().getDensityMapping();
+ if (densityMapping == null) {
return (int) (mStaticDisplayInfo.density * 160 + 0.5);
}
- return densityMap.getDensityForResolution(mInfo.width, mInfo.height);
+ return densityMapping.getDensityForResolution(mInfo.width, mInfo.height);
}
private void loadDisplayDeviceConfig() {
diff --git a/services/core/java/com/android/server/hdmi/AbsoluteVolumeAudioStatusAction.java b/services/core/java/com/android/server/hdmi/AbsoluteVolumeAudioStatusAction.java
new file mode 100644
index 000000000000..d7563e085e61
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/AbsoluteVolumeAudioStatusAction.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+/**
+ * Action to query and track the audio status of the System Audio device when enabling or using
+ * Absolute Volume Control. Must be removed when AVC is disabled. Performs two main functions:
+ * 1. When enabling AVC: queries the starting audio status of the System Audio device and
+ * enables the feature upon receiving a response.
+ * 2. While AVC is enabled: monitors <Report Audio Status> messages from the System Audio device and
+ * notifies AudioService if the audio status changes.
+ */
+final class AbsoluteVolumeAudioStatusAction extends HdmiCecFeatureAction {
+ private static final String TAG = "AbsoluteVolumeAudioStatusAction";
+
+ private int mInitialAudioStatusRetriesLeft = 2;
+
+ private static final int STATE_WAIT_FOR_INITIAL_AUDIO_STATUS = 1;
+ private static final int STATE_MONITOR_AUDIO_STATUS = 2;
+
+ private final int mTargetAddress;
+
+ private AudioStatus mLastAudioStatus;
+
+ AbsoluteVolumeAudioStatusAction(HdmiCecLocalDevice source, int targetAddress) {
+ super(source);
+ mTargetAddress = targetAddress;
+ }
+
+ @Override
+ boolean start() {
+ mState = STATE_WAIT_FOR_INITIAL_AUDIO_STATUS;
+ sendGiveAudioStatus();
+ return true;
+ }
+
+ void updateVolume(int volumeIndex) {
+ mLastAudioStatus = new AudioStatus(volumeIndex, mLastAudioStatus.getMute());
+ }
+
+ private void sendGiveAudioStatus() {
+ addTimer(mState, HdmiConfig.TIMEOUT_MS);
+ sendCommand(HdmiCecMessageBuilder.buildGiveAudioStatus(getSourceAddress(), mTargetAddress));
+ }
+
+ @Override
+ boolean processCommand(HdmiCecMessage cmd) {
+ switch (cmd.getOpcode()) {
+ case Constants.MESSAGE_REPORT_AUDIO_STATUS:
+ return handleReportAudioStatus(cmd);
+ }
+
+ return false;
+ }
+
+ private boolean handleReportAudioStatus(HdmiCecMessage cmd) {
+ if (mTargetAddress != cmd.getSource() || cmd.getParams().length == 0) {
+ return false;
+ }
+
+ boolean mute = HdmiUtils.isAudioStatusMute(cmd);
+ int volume = HdmiUtils.getAudioStatusVolume(cmd);
+ AudioStatus audioStatus = new AudioStatus(volume, mute);
+ if (mState == STATE_WAIT_FOR_INITIAL_AUDIO_STATUS) {
+ localDevice().getService().enableAbsoluteVolumeControl(audioStatus);
+ mState = STATE_MONITOR_AUDIO_STATUS;
+ } else if (mState == STATE_MONITOR_AUDIO_STATUS) {
+ if (audioStatus.getVolume() != mLastAudioStatus.getVolume()) {
+ localDevice().getService().notifyAvcVolumeChange(audioStatus.getVolume());
+ }
+ if (audioStatus.getMute() != mLastAudioStatus.getMute()) {
+ localDevice().getService().notifyAvcMuteChange(audioStatus.getMute());
+ }
+ }
+ mLastAudioStatus = audioStatus;
+
+ return true;
+ }
+
+ @Override
+ void handleTimerEvent(int state) {
+ if (mState != state) {
+ return;
+ } else if (mInitialAudioStatusRetriesLeft > 0) {
+ mInitialAudioStatusRetriesLeft--;
+ sendGiveAudioStatus();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
new file mode 100644
index 000000000000..438c1ea01e29
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceVolumeManager;
+import android.media.VolumeInfo;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Wrapper for {@link AudioDeviceVolumeManager}. Creates an instance of the class and directly
+ * passes method calls to that instance.
+ */
+public class AudioDeviceVolumeManagerWrapper
+ implements AudioDeviceVolumeManagerWrapperInterface {
+
+ private static final String TAG = "AudioDeviceVolumeManagerWrapper";
+
+ private final AudioDeviceVolumeManager mAudioDeviceVolumeManager;
+
+ public AudioDeviceVolumeManagerWrapper(Context context) {
+ mAudioDeviceVolumeManager = new AudioDeviceVolumeManager(context);
+ }
+
+ @Override
+ public void addOnDeviceVolumeBehaviorChangedListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull AudioDeviceVolumeManager.OnDeviceVolumeBehaviorChangedListener listener)
+ throws SecurityException {
+ mAudioDeviceVolumeManager.addOnDeviceVolumeBehaviorChangedListener(executor, listener);
+ }
+
+ @Override
+ public void removeOnDeviceVolumeBehaviorChangedListener(
+ @NonNull AudioDeviceVolumeManager.OnDeviceVolumeBehaviorChangedListener listener) {
+ mAudioDeviceVolumeManager.removeOnDeviceVolumeBehaviorChangedListener(listener);
+ }
+
+ @Override
+ public void setDeviceAbsoluteVolumeBehavior(
+ @NonNull AudioDeviceAttributes device,
+ @NonNull VolumeInfo volume,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener,
+ boolean handlesVolumeAdjustment) {
+ mAudioDeviceVolumeManager.setDeviceAbsoluteVolumeBehavior(device, volume, executor,
+ vclistener, handlesVolumeAdjustment);
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapperInterface.java b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapperInterface.java
new file mode 100644
index 000000000000..1a1d4c19358b
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapperInterface.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import static android.media.AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener;
+import static android.media.AudioDeviceVolumeManager.OnDeviceVolumeBehaviorChangedListener;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceVolumeManager;
+import android.media.VolumeInfo;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Interface with the methods from {@link AudioDeviceVolumeManager} used by the HDMI framework.
+ * Allows the class to be faked for tests.
+ */
+public interface AudioDeviceVolumeManagerWrapperInterface {
+
+ /**
+ * Wrapper for {@link AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener(
+ * Executor, OnDeviceVolumeBehaviorChangedListener)}
+ */
+ void addOnDeviceVolumeBehaviorChangedListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull AudioDeviceVolumeManager.OnDeviceVolumeBehaviorChangedListener listener);
+
+ /**
+ * Wrapper for {@link AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener(
+ * OnDeviceVolumeBehaviorChangedListener)}
+ */
+ void removeOnDeviceVolumeBehaviorChangedListener(
+ @NonNull AudioDeviceVolumeManager.OnDeviceVolumeBehaviorChangedListener listener);
+
+ /**
+ * Wrapper for {@link AudioDeviceVolumeManager#setDeviceAbsoluteVolumeBehavior(
+ * AudioDeviceAttributes, VolumeInfo, Executor, OnAudioDeviceVolumeChangedListener, boolean)}
+ */
+ void setDeviceAbsoluteVolumeBehavior(
+ @NonNull AudioDeviceAttributes device,
+ @NonNull VolumeInfo volume,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener,
+ boolean handlesVolumeAdjustment);
+}
diff --git a/services/core/java/com/android/server/hdmi/AudioStatus.java b/services/core/java/com/android/server/hdmi/AudioStatus.java
new file mode 100644
index 000000000000..a884ffb93a6d
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/AudioStatus.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.annotation.Nullable;
+
+import java.util.Objects;
+
+/**
+ * Immutable representation of the information in the [Audio Status] operand:
+ * volume status (0 <= N <= 100) and mute status (muted or unmuted).
+ */
+public class AudioStatus {
+ public static final int MAX_VOLUME = 100;
+ public static final int MIN_VOLUME = 0;
+
+ int mVolume;
+ boolean mMute;
+
+ public AudioStatus(int volume, boolean mute) {
+ mVolume = volume;
+ mMute = mute;
+ }
+
+ public int getVolume() {
+ return mVolume;
+ }
+
+ public boolean getMute() {
+ return mMute;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object obj) {
+ if (!(obj instanceof AudioStatus)) {
+ return false;
+ }
+
+ AudioStatus other = (AudioStatus) obj;
+ return mVolume == other.mVolume
+ && mMute == other.mMute;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mVolume, mMute);
+ }
+
+ @Override
+ public String toString() {
+ return "AudioStatus mVolume:" + mVolume + " mMute:" + mMute;
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 751f2db99528..157057d0e4b7 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -118,6 +118,7 @@ final class Constants {
MESSAGE_SYSTEM_AUDIO_MODE_REQUEST,
MESSAGE_GIVE_AUDIO_STATUS,
MESSAGE_SET_SYSTEM_AUDIO_MODE,
+ MESSAGE_SET_AUDIO_VOLUME_LEVEL,
MESSAGE_REPORT_AUDIO_STATUS,
MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS,
MESSAGE_SYSTEM_AUDIO_MODE_STATUS,
@@ -197,9 +198,9 @@ final class Constants {
static final int MESSAGE_SYSTEM_AUDIO_MODE_REQUEST = 0x70;
static final int MESSAGE_GIVE_AUDIO_STATUS = 0x71;
static final int MESSAGE_SET_SYSTEM_AUDIO_MODE = 0x72;
+ static final int MESSAGE_SET_AUDIO_VOLUME_LEVEL = 0x73;
static final int MESSAGE_REPORT_AUDIO_STATUS = 0x7A;
static final int MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D;
- static final int MESSAGE_SET_AUDIO_VOLUME_LEVEL = 0x73;
static final int MESSAGE_SYSTEM_AUDIO_MODE_STATUS = 0x7E;
static final int MESSAGE_ROUTING_CHANGE = 0x80;
static final int MESSAGE_ROUTING_INFORMATION = 0x81;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 26a161323e4f..fb2d2ee08cbd 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -303,6 +303,13 @@ abstract class HdmiCecLocalDevice {
if (dispatchMessageToAction(message)) {
return Constants.HANDLED;
}
+
+ // If a message type has its own class, all valid messages of that type
+ // will be represented by an instance of that class.
+ if (message instanceof SetAudioVolumeLevelMessage) {
+ return handleSetAudioVolumeLevel((SetAudioVolumeLevelMessage) message);
+ }
+
switch (message.getOpcode()) {
case Constants.MESSAGE_ACTIVE_SOURCE:
return handleActiveSource(message);
@@ -637,6 +644,11 @@ abstract class HdmiCecLocalDevice {
return Constants.NOT_HANDLED;
}
+ @Constants.HandleMessageResult
+ protected int handleSetAudioVolumeLevel(SetAudioVolumeLevelMessage message) {
+ return Constants.NOT_HANDLED;
+ }
+
@Constants.RcProfile
protected abstract int getRcProfile();
@@ -1002,6 +1014,57 @@ abstract class HdmiCecLocalDevice {
action.start();
}
+ void addAvcAudioStatusAction(int targetAddress) {
+ if (!hasAction(AbsoluteVolumeAudioStatusAction.class)) {
+ addAndStartAction(new AbsoluteVolumeAudioStatusAction(this, targetAddress));
+ }
+ }
+
+ void removeAvcAudioStatusAction() {
+ removeAction(AbsoluteVolumeAudioStatusAction.class);
+ }
+
+ void updateAvcVolume(int volumeIndex) {
+ for (AbsoluteVolumeAudioStatusAction action :
+ getActions(AbsoluteVolumeAudioStatusAction.class)) {
+ action.updateVolume(volumeIndex);
+ }
+ }
+
+ /**
+ * Determines whether {@code targetAddress} supports <Set Audio Volume Level>. Does two things
+ * in parallel: send <Give Features> (to get <Report Features> in response),
+ * and send <Set Audio Volume Level> (to see if it gets a <Feature Abort> in response).
+ */
+ @ServiceThreadOnly
+ void queryAvcSupport(int targetAddress) {
+ assertRunOnServiceThread();
+
+ // Send <Give Features> if using CEC 2.0 or above.
+ if (mService.getCecVersion() >= HdmiControlManager.HDMI_CEC_VERSION_2_0) {
+ synchronized (mLock) {
+ mService.sendCecCommand(HdmiCecMessageBuilder.buildGiveFeatures(
+ getDeviceInfo().getLogicalAddress(), targetAddress));
+ }
+ }
+
+ // If we don't already have a {@link SetAudioVolumeLevelDiscoveryAction} for the target
+ // device, start one.
+ List<SetAudioVolumeLevelDiscoveryAction> savlDiscoveryActions =
+ getActions(SetAudioVolumeLevelDiscoveryAction.class);
+ if (savlDiscoveryActions.stream().noneMatch(a -> a.getTargetAddress() == targetAddress)) {
+ addAndStartAction(new SetAudioVolumeLevelDiscoveryAction(this, targetAddress,
+ new IHdmiControlCallback.Stub() {
+ @Override
+ public void onComplete(int result) {
+ if (result == HdmiControlManager.RESULT_SUCCESS) {
+ getService().checkAndUpdateAbsoluteVolumeControlState();
+ }
+ }
+ }));
+ }
+ }
+
@ServiceThreadOnly
void startQueuedActions() {
assertRunOnServiceThread();
@@ -1205,6 +1268,9 @@ abstract class HdmiCecLocalDevice {
*/
protected void disableDevice(
boolean initiatedByCec, final PendingActionClearedCallback originalCallback) {
+ removeAction(AbsoluteVolumeAudioStatusAction.class);
+ removeAction(SetAudioVolumeLevelDiscoveryAction.class);
+
mPendingActionClearedCallback =
new PendingActionClearedCallback() {
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
index 90b4f76fec10..c0c02027a7a1 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -307,6 +307,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
protected void disableDevice(boolean initiatedByCec, PendingActionClearedCallback callback) {
removeAction(OneTouchPlayAction.class);
removeAction(DevicePowerStatusAction.class);
+ removeAction(AbsoluteVolumeAudioStatusAction.class);
super.disableDevice(initiatedByCec, callback);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 9212fb604721..1ea1457439ec 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1166,6 +1166,19 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
return Constants.HANDLED;
}
+ @Override
+ @Constants.HandleMessageResult
+ protected int handleSetAudioVolumeLevel(SetAudioVolumeLevelMessage message) {
+ // <Set Audio Volume Level> should only be sent to the System Audio device, so we don't
+ // handle it when System Audio Mode is enabled.
+ if (mService.isSystemAudioActivated()) {
+ return Constants.ABORT_NOT_IN_CORRECT_MODE;
+ } else {
+ mService.setStreamMusicVolume(message.getAudioVolumeLevel(), 0);
+ return Constants.HANDLED;
+ }
+ }
+
void announceOneTouchRecordResult(int recorderAddress, int result) {
mService.invokeOneTouchRecordResult(recorderAddress, result);
}
@@ -1202,6 +1215,13 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
return mService.getHdmiCecNetwork().getSafeCecDeviceInfo(Constants.ADDR_AUDIO_SYSTEM);
}
+ /**
+ * Returns the audio output device used for System Audio Mode.
+ */
+ AudioDeviceAttributes getSystemAudioOutputDevice() {
+ return HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_ARC;
+ }
+
@ServiceThreadOnly
void handleRemoveActiveRoutingPath(int path) {
@@ -1296,6 +1316,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
removeAction(OneTouchRecordAction.class);
removeAction(TimerRecordingAction.class);
removeAction(NewDeviceAction.class);
+ removeAction(AbsoluteVolumeAudioStatusAction.class);
disableSystemAudioIfExist();
disableArcIfExist();
@@ -1318,7 +1339,6 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
removeAction(SystemAudioActionFromAvr.class);
removeAction(SystemAudioActionFromTv.class);
removeAction(SystemAudioAutoInitiationAction.class);
- removeAction(SystemAudioStatusAction.class);
removeAction(VolumeControlAction.class);
if (!mService.isControlEnabled()) {
@@ -1589,6 +1609,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
return DeviceFeatures.NO_FEATURES_SUPPORTED.toBuilder()
.setRecordTvScreenSupport(FEATURE_SUPPORTED)
.setArcTxSupport(hasArcPort ? FEATURE_SUPPORTED : FEATURE_NOT_SUPPORTED)
+ .setSetAudioVolumeLevelSupport(FEATURE_SUPPORTED)
.build();
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessage.java b/services/core/java/com/android/server/hdmi/HdmiCecMessage.java
index 290cae50f2cb..2b84225e7c55 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessage.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessage.java
@@ -262,6 +262,8 @@ public class HdmiCecMessage {
return "Give Audio Status";
case Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE:
return "Set System Audio Mode";
+ case Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL:
+ return "Set Audio Volume Level";
case Constants.MESSAGE_REPORT_AUDIO_STATUS:
return "Report Audio Status";
case Constants.MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS:
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
index 8b6d16a171f5..caaf80073de1 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
@@ -259,6 +259,7 @@ public class HdmiCecNetwork {
// The addition of a local device should not notify listeners
return;
}
+ mHdmiControlService.checkAndUpdateAbsoluteVolumeControlState();
if (info.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) {
// Don't notify listeners of devices that haven't reported their physical address yet
return;
@@ -383,7 +384,7 @@ public class HdmiCecNetwork {
final void removeCecDevice(HdmiCecLocalDevice localDevice, int address) {
assertRunOnServiceThread();
HdmiDeviceInfo info = removeDeviceInfo(HdmiDeviceInfo.idForCecDevice(address));
-
+ mHdmiControlService.checkAndUpdateAbsoluteVolumeControlState();
localDevice.mCecMessageCache.flushMessagesFrom(address);
if (info.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) {
// Don't notify listeners of devices that haven't reported their physical address yet
@@ -586,6 +587,8 @@ public class HdmiCecNetwork {
.build();
updateCecDevice(newDeviceInfo);
+
+ mHdmiControlService.checkAndUpdateAbsoluteVolumeControlState();
}
@ServiceThreadOnly
@@ -617,6 +620,8 @@ public class HdmiCecNetwork {
)
.build();
updateCecDevice(newDeviceInfo);
+
+ mHdmiControlService.checkAndUpdateAbsoluteVolumeControlState();
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 12380abd0d38..9824b4e6c43a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -30,6 +30,7 @@ import static com.android.server.hdmi.Constants.OPTION_MHL_SERVICE_CONTROL;
import static com.android.server.power.ShutdownThread.SHUTDOWN_ACTION_PROPERTY;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -38,6 +39,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.hardware.display.DisplayManager;
+import android.hardware.hdmi.DeviceFeatures;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiHotplugEvent;
@@ -56,7 +58,12 @@ import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
import android.hardware.hdmi.IHdmiVendorCommandListener;
import android.hardware.tv.cec.V1_0.OptionKey;
import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioDeviceVolumeManager;
import android.media.AudioManager;
+import android.media.VolumeInfo;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.media.tv.TvInputManager;
@@ -83,6 +90,7 @@ import android.util.ArrayMap;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
+import android.view.KeyEvent;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -101,6 +109,7 @@ import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -202,6 +211,27 @@ public class HdmiControlService extends SystemService {
public @interface WakeReason {
}
+ @VisibleForTesting
+ static final AudioDeviceAttributes AUDIO_OUTPUT_DEVICE_HDMI = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_HDMI, "");
+ @VisibleForTesting
+ static final AudioDeviceAttributes AUDIO_OUTPUT_DEVICE_HDMI_ARC =
+ new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
+ AudioDeviceInfo.TYPE_HDMI_ARC, "");
+ static final AudioDeviceAttributes AUDIO_OUTPUT_DEVICE_HDMI_EARC =
+ new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
+ AudioDeviceInfo.TYPE_HDMI_EARC, "");
+
+ // Audio output devices used for Absolute Volume Control
+ private static final List<AudioDeviceAttributes> AVC_AUDIO_OUTPUT_DEVICES =
+ Collections.unmodifiableList(Arrays.asList(AUDIO_OUTPUT_DEVICE_HDMI,
+ AUDIO_OUTPUT_DEVICE_HDMI_ARC, AUDIO_OUTPUT_DEVICE_HDMI_EARC));
+
+ // AudioAttributes for STREAM_MUSIC
+ @VisibleForTesting
+ static final AudioAttributes STREAM_MUSIC_ATTRIBUTES =
+ new AudioAttributes.Builder().setLegacyStreamType(AudioManager.STREAM_MUSIC).build();
+
private final Executor mServiceThreadExecutor = new Executor() {
@Override
public void execute(Runnable r) {
@@ -209,6 +239,10 @@ public class HdmiControlService extends SystemService {
}
};
+ Executor getServiceThreadExecutor() {
+ return mServiceThreadExecutor;
+ }
+
// Logical address of the active source.
@GuardedBy("mLock")
protected final ActiveSource mActiveSource = new ActiveSource();
@@ -222,6 +256,13 @@ public class HdmiControlService extends SystemService {
@HdmiControlManager.VolumeControl
private int mHdmiCecVolumeControl;
+ // Caches the volume behaviors of all audio output devices in AVC_AUDIO_OUTPUT_DEVICES.
+ @GuardedBy("mLock")
+ private Map<AudioDeviceAttributes, Integer> mAudioDeviceVolumeBehaviors = new HashMap<>();
+
+ // Maximum volume of AudioManager.STREAM_MUSIC. Set upon gaining access to system services.
+ private int mStreamMusicMaxVolume;
+
// Make sure HdmiCecConfig is instantiated and the XMLs are read.
private HdmiCecConfig mHdmiCecConfig;
@@ -411,6 +452,12 @@ public class HdmiControlService extends SystemService {
private PowerManagerInternalWrapper mPowerManagerInternal;
@Nullable
+ private AudioManager mAudioManager;
+
+ @Nullable
+ private AudioDeviceVolumeManagerWrapperInterface mAudioDeviceVolumeManager;
+
+ @Nullable
private Looper mIoLooper;
@Nullable
@@ -439,11 +486,21 @@ public class HdmiControlService extends SystemService {
private final SelectRequestBuffer mSelectRequestBuffer = new SelectRequestBuffer();
- @VisibleForTesting HdmiControlService(Context context, List<Integer> deviceTypes) {
+ /**
+ * Constructor for testing.
+ *
+ * It's critical to use a fake AudioDeviceVolumeManager because a normally instantiated
+ * AudioDeviceVolumeManager can access the "real" AudioService on the DUT.
+ *
+ * @see FakeAudioDeviceVolumeManagerWrapper
+ */
+ @VisibleForTesting HdmiControlService(Context context, List<Integer> deviceTypes,
+ AudioDeviceVolumeManagerWrapperInterface audioDeviceVolumeManager) {
super(context);
mLocalDevices = deviceTypes;
mSettingsObserver = new SettingsObserver(mHandler);
mHdmiCecConfig = new HdmiCecConfig(context);
+ mAudioDeviceVolumeManager = audioDeviceVolumeManager;
}
public HdmiControlService(Context context) {
@@ -744,6 +801,14 @@ public class HdmiControlService extends SystemService {
Context.TV_INPUT_SERVICE);
mPowerManager = new PowerManagerWrapper(getContext());
mPowerManagerInternal = new PowerManagerInternalWrapper();
+ mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+ mStreamMusicMaxVolume = getAudioManager().getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ if (mAudioDeviceVolumeManager == null) {
+ mAudioDeviceVolumeManager =
+ new AudioDeviceVolumeManagerWrapper(getContext());
+ }
+ getAudioDeviceVolumeManager().addOnDeviceVolumeBehaviorChangedListener(
+ mServiceThreadExecutor, this::onDeviceVolumeBehaviorChanged);
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
runOnServiceThread(this::bootCompleted);
}
@@ -2419,6 +2484,7 @@ public class HdmiControlService extends SystemService {
pw.println("mPowerStatus: " + mPowerStatusController.getPowerStatus());
pw.println("mIsCecAvailable: " + mIsCecAvailable);
pw.println("mCecVersion: " + mCecVersion);
+ pw.println("mIsAbsoluteVolumeControlEnabled: " + isAbsoluteVolumeControlEnabled());
// System settings
pw.println("System_settings:");
@@ -2578,6 +2644,7 @@ public class HdmiControlService extends SystemService {
@HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
mHdmiCecVolumeControl = hdmiCecVolumeControl;
announceHdmiCecVolumeControlFeatureChange(hdmiCecVolumeControl);
+ runOnServiceThread(this::checkAndUpdateAbsoluteVolumeControlState);
}
// Get the source address to send out commands to devices connected to the current device
@@ -3086,15 +3153,17 @@ public class HdmiControlService extends SystemService {
private void announceHdmiCecVolumeControlFeatureChange(
@HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
assertRunOnServiceThread();
- mHdmiCecVolumeControlFeatureListenerRecords.broadcast(listener -> {
- try {
- listener.onHdmiCecVolumeControlFeature(hdmiCecVolumeControl);
- } catch (RemoteException e) {
- Slog.e(TAG,
- "Failed to report HdmiControlVolumeControlStatusChange: "
- + hdmiCecVolumeControl);
- }
- });
+ synchronized (mLock) {
+ mHdmiCecVolumeControlFeatureListenerRecords.broadcast(listener -> {
+ try {
+ listener.onHdmiCecVolumeControlFeature(hdmiCecVolumeControl);
+ } catch (RemoteException e) {
+ Slog.e(TAG,
+ "Failed to report HdmiControlVolumeControlStatusChange: "
+ + hdmiCecVolumeControl);
+ }
+ });
+ }
}
public HdmiCecLocalDeviceTv tv() {
@@ -3131,8 +3200,20 @@ public class HdmiControlService extends SystemService {
HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
}
+ /**
+ * Returns null before the boot phase {@link SystemService#PHASE_SYSTEM_SERVICES_READY}.
+ */
+ @Nullable
AudioManager getAudioManager() {
- return (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+ return mAudioManager;
+ }
+
+ /**
+ * Returns null before the boot phase {@link SystemService#PHASE_SYSTEM_SERVICES_READY}.
+ */
+ @Nullable
+ private AudioDeviceVolumeManagerWrapperInterface getAudioDeviceVolumeManager() {
+ return mAudioDeviceVolumeManager;
}
boolean isControlEnabled() {
@@ -3486,6 +3567,7 @@ public class HdmiControlService extends SystemService {
synchronized (mLock) {
mSystemAudioActivated = on;
}
+ runOnServiceThread(this::checkAndUpdateAbsoluteVolumeControlState);
}
@ServiceThreadOnly
@@ -3599,6 +3681,8 @@ public class HdmiControlService extends SystemService {
device.addActiveSourceHistoryItem(new ActiveSource(logicalAddress, physicalAddress),
deviceIsActiveSource, caller);
}
+
+ runOnServiceThread(this::checkAndUpdateAbsoluteVolumeControlState);
}
// This method should only be called when the device can be the active source
@@ -3791,4 +3875,332 @@ public class HdmiControlService extends SystemService {
Slog.e(TAG, "Failed to report setting change", e);
}
}
+
+ /**
+ * Listener for changes to the volume behavior of an audio output device. Caches the
+ * volume behavior of devices used for Absolute Volume Control.
+ */
+ @VisibleForTesting
+ @ServiceThreadOnly
+ void onDeviceVolumeBehaviorChanged(AudioDeviceAttributes device, int volumeBehavior) {
+ assertRunOnServiceThread();
+ if (AVC_AUDIO_OUTPUT_DEVICES.contains(device)) {
+ synchronized (mLock) {
+ mAudioDeviceVolumeBehaviors.put(device, volumeBehavior);
+ }
+ checkAndUpdateAbsoluteVolumeControlState();
+ }
+ }
+
+ /**
+ * Wrapper for {@link AudioManager#getDeviceVolumeBehavior} that takes advantage of cached
+ * results for the volume behaviors of HDMI audio devices.
+ */
+ @AudioManager.DeviceVolumeBehavior
+ private int getDeviceVolumeBehavior(AudioDeviceAttributes device) {
+ if (AVC_AUDIO_OUTPUT_DEVICES.contains(device)) {
+ synchronized (mLock) {
+ if (mAudioDeviceVolumeBehaviors.containsKey(device)) {
+ return mAudioDeviceVolumeBehaviors.get(device);
+ }
+ }
+ }
+ return getAudioManager().getDeviceVolumeBehavior(device);
+ }
+
+ /**
+ * Returns whether Absolute Volume Control is enabled or not. This is determined by the
+ * volume behavior of the relevant HDMI audio output device(s) for this device's type.
+ */
+ public boolean isAbsoluteVolumeControlEnabled() {
+ if (!isTvDevice() && !isPlaybackDevice()) {
+ return false;
+ }
+ AudioDeviceAttributes avcAudioOutputDevice = getAvcAudioOutputDevice();
+ if (avcAudioOutputDevice == null) {
+ return false;
+ }
+ return getDeviceVolumeBehavior(avcAudioOutputDevice)
+ == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
+ }
+
+ private AudioDeviceAttributes getAvcAudioOutputDevice() {
+ if (isTvDevice()) {
+ return tv().getSystemAudioOutputDevice();
+ } else if (isPlaybackDevice()) {
+ return AUDIO_OUTPUT_DEVICE_HDMI;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Checks the conditions for Absolute Volume Control (AVC), and enables or disables the feature
+ * if necessary. AVC is enabled precisely when a specific audio output device
+ * (HDMI for playback devices, and HDMI_ARC or HDMI_EARC for TVs) is using absolute volume
+ * behavior.
+ *
+ * AVC must be enabled on a Playback device or TV precisely when it is playing
+ * audio on an external device (the System Audio device) that supports the feature.
+ * This reduces to these conditions:
+ *
+ * 1. If the System Audio Device is an Audio System: System Audio Mode is active
+ * 2. Our HDMI audio output device is using full volume behavior
+ * 3. CEC volume is enabled
+ * 4. The System Audio device supports AVC (i.e. it supports <Set Audio Volume Level>)
+ *
+ * If not all of these conditions are met, this method disables AVC if necessary.
+ *
+ * If all of these conditions are met, this method starts an action to query the System Audio
+ * device's audio status, which enables AVC upon obtaining the audio status.
+ */
+ @ServiceThreadOnly
+ void checkAndUpdateAbsoluteVolumeControlState() {
+ assertRunOnServiceThread();
+
+ // Can't enable or disable AVC before we have access to system services
+ if (getAudioManager() == null) {
+ return;
+ }
+
+ HdmiCecLocalDevice localCecDevice;
+ if (isTvDevice() && tv() != null) {
+ localCecDevice = tv();
+ // Condition 1: TVs need System Audio Mode to be active
+ // (Doesn't apply to Playback Devices, where if SAM isn't active, we assume the
+ // TV is the System Audio Device instead.)
+ if (!isSystemAudioActivated()) {
+ disableAbsoluteVolumeControl();
+ return;
+ }
+ } else if (isPlaybackDevice() && playback() != null) {
+ localCecDevice = playback();
+ } else {
+ // Either this device type doesn't support AVC, or it hasn't fully initialized yet
+ return;
+ }
+
+ HdmiDeviceInfo systemAudioDeviceInfo = getHdmiCecNetwork().getSafeCecDeviceInfo(
+ localCecDevice.findAudioReceiverAddress());
+ @AudioManager.DeviceVolumeBehavior int currentVolumeBehavior =
+ getDeviceVolumeBehavior(getAvcAudioOutputDevice());
+
+ // Condition 2: Already using full or absolute volume behavior
+ boolean alreadyUsingFullOrAbsoluteVolume =
+ currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL
+ || currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
+ // Condition 3: CEC volume is enabled
+ boolean cecVolumeEnabled =
+ getHdmiCecVolumeControl() == HdmiControlManager.VOLUME_CONTROL_ENABLED;
+
+ if (!cecVolumeEnabled || !alreadyUsingFullOrAbsoluteVolume) {
+ disableAbsoluteVolumeControl();
+ return;
+ }
+
+ // Check for safety: if the System Audio device is a candidate for AVC, we should already
+ // have received messages from it to trigger the other conditions.
+ if (systemAudioDeviceInfo == null) {
+ disableAbsoluteVolumeControl();
+ return;
+ }
+ // Condition 4: The System Audio device supports AVC (i.e. <Set Audio Volume Level>).
+ switch (systemAudioDeviceInfo.getDeviceFeatures().getSetAudioVolumeLevelSupport()) {
+ case DeviceFeatures.FEATURE_SUPPORTED:
+ if (!isAbsoluteVolumeControlEnabled()) {
+ // Start an action that will call {@link #enableAbsoluteVolumeControl}
+ // once the System Audio device sends <Report Audio Status>
+ localCecDevice.addAvcAudioStatusAction(
+ systemAudioDeviceInfo.getLogicalAddress());
+ }
+ return;
+ case DeviceFeatures.FEATURE_NOT_SUPPORTED:
+ disableAbsoluteVolumeControl();
+ return;
+ case DeviceFeatures.FEATURE_SUPPORT_UNKNOWN:
+ disableAbsoluteVolumeControl();
+ localCecDevice.queryAvcSupport(systemAudioDeviceInfo.getLogicalAddress());
+ return;
+ default:
+ return;
+ }
+ }
+
+ private void disableAbsoluteVolumeControl() {
+ if (isPlaybackDevice()) {
+ playback().removeAvcAudioStatusAction();
+ } else if (isTvDevice()) {
+ tv().removeAvcAudioStatusAction();
+ }
+ AudioDeviceAttributes device = getAvcAudioOutputDevice();
+ if (getDeviceVolumeBehavior(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+ getAudioManager().setDeviceVolumeBehavior(device,
+ AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ }
+ }
+
+ /**
+ * Enables Absolute Volume Control. Should only be called when all the conditions for
+ * AVC are met (see {@link #checkAndUpdateAbsoluteVolumeControlState}).
+ * @param audioStatus The initial audio status to set the audio output device to
+ */
+ void enableAbsoluteVolumeControl(AudioStatus audioStatus) {
+ HdmiCecLocalDevice localDevice = isPlaybackDevice() ? playback() : tv();
+ HdmiDeviceInfo systemAudioDevice = getHdmiCecNetwork().getDeviceInfo(
+ localDevice.findAudioReceiverAddress());
+ VolumeInfo volumeInfo = new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+ .setMuted(audioStatus.getMute())
+ .setVolumeIndex(audioStatus.getVolume())
+ .setMaxVolumeIndex(AudioStatus.MAX_VOLUME)
+ .setMinVolumeIndex(AudioStatus.MIN_VOLUME)
+ .build();
+ mAbsoluteVolumeChangedListener = new AbsoluteVolumeChangedListener(
+ localDevice, systemAudioDevice);
+
+ // AudioService sets the volume of the stream and device based on the input VolumeInfo
+ // when enabling absolute volume behavior, but not the mute state
+ notifyAvcMuteChange(audioStatus.getMute());
+ getAudioDeviceVolumeManager().setDeviceAbsoluteVolumeBehavior(
+ getAvcAudioOutputDevice(), volumeInfo, mServiceThreadExecutor,
+ mAbsoluteVolumeChangedListener, true);
+ }
+
+ private AbsoluteVolumeChangedListener mAbsoluteVolumeChangedListener;
+
+ @VisibleForTesting
+ AbsoluteVolumeChangedListener getAbsoluteVolumeChangedListener() {
+ return mAbsoluteVolumeChangedListener;
+ }
+
+ /**
+ * Listeners for changes reported by AudioService to the state of an audio output device using
+ * absolute volume behavior.
+ */
+ @VisibleForTesting
+ class AbsoluteVolumeChangedListener implements
+ AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener {
+ private HdmiCecLocalDevice mLocalDevice;
+ private HdmiDeviceInfo mSystemAudioDevice;
+
+ private AbsoluteVolumeChangedListener(HdmiCecLocalDevice localDevice,
+ HdmiDeviceInfo systemAudioDevice) {
+ mLocalDevice = localDevice;
+ mSystemAudioDevice = systemAudioDevice;
+ }
+
+ /**
+ * Called when AudioService sets the volume level of an absolute volume audio output device
+ * to a numeric value.
+ */
+ @Override
+ public void onAudioDeviceVolumeChanged(
+ @NonNull AudioDeviceAttributes audioDevice,
+ @NonNull VolumeInfo volumeInfo) {
+ int localDeviceAddress;
+ synchronized (mLocalDevice.mLock) {
+ localDeviceAddress = mLocalDevice.getDeviceInfo().getLogicalAddress();
+ }
+ sendCecCommand(SetAudioVolumeLevelMessage.build(
+ localDeviceAddress,
+ mSystemAudioDevice.getLogicalAddress(),
+ volumeInfo.getVolumeIndex()),
+ // If sending the message fails, ask the System Audio device for its
+ // audio status so that we can update AudioService
+ (int errorCode) -> {
+ if (errorCode == SendMessageResult.SUCCESS) {
+ // Update the volume tracked in our AbsoluteVolumeAudioStatusAction
+ // so it correctly processes incoming <Report Audio Status> messages
+ HdmiCecLocalDevice avcDevice = isTvDevice() ? tv() : playback();
+ avcDevice.updateAvcVolume(volumeInfo.getVolumeIndex());
+ } else {
+ sendCecCommand(HdmiCecMessageBuilder.buildGiveAudioStatus(
+ localDeviceAddress,
+ mSystemAudioDevice.getLogicalAddress()
+ ));
+ }
+ });
+ }
+
+ /**
+ * Called when AudioService adjusts the volume or mute state of an absolute volume
+ * audio output device
+ */
+ @Override
+ public void onAudioDeviceVolumeAdjusted(
+ @NonNull AudioDeviceAttributes audioDevice,
+ @NonNull VolumeInfo volumeInfo,
+ @AudioManager.VolumeAdjustment int direction,
+ @AudioDeviceVolumeManager.VolumeAdjustmentMode int mode
+ ) {
+ int keyCode;
+ switch (direction) {
+ case AudioManager.ADJUST_RAISE:
+ keyCode = KeyEvent.KEYCODE_VOLUME_UP;
+ break;
+ case AudioManager.ADJUST_LOWER:
+ keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
+ break;
+ case AudioManager.ADJUST_TOGGLE_MUTE:
+ case AudioManager.ADJUST_MUTE:
+ case AudioManager.ADJUST_UNMUTE:
+ // Many CEC devices only support toggle mute. Therefore, we send the
+ // same keycode for all three mute options.
+ keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
+ break;
+ default:
+ return;
+ }
+ switch (mode) {
+ case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL:
+ mLocalDevice.sendVolumeKeyEvent(keyCode, true);
+ mLocalDevice.sendVolumeKeyEvent(keyCode, false);
+ break;
+ case AudioDeviceVolumeManager.ADJUST_MODE_START:
+ mLocalDevice.sendVolumeKeyEvent(keyCode, true);
+ break;
+ case AudioDeviceVolumeManager.ADJUST_MODE_END:
+ mLocalDevice.sendVolumeKeyEvent(keyCode, false);
+ break;
+ default:
+ return;
+ }
+ }
+ }
+
+ /**
+ * Notifies AudioService of a change in the volume of the System Audio device. Has no effect if
+ * AVC is disabled, or the audio output device for AVC is not playing for STREAM_MUSIC
+ */
+ void notifyAvcVolumeChange(int volume) {
+ if (!isAbsoluteVolumeControlEnabled()) return;
+ List<AudioDeviceAttributes> streamMusicDevices =
+ getAudioManager().getDevicesForAttributes(STREAM_MUSIC_ATTRIBUTES);
+ if (streamMusicDevices.contains(getAvcAudioOutputDevice())) {
+ setStreamMusicVolume(volume, AudioManager.FLAG_ABSOLUTE_VOLUME);
+ }
+ }
+
+ /**
+ * Notifies AudioService of a change in the mute status of the System Audio device. Has no
+ * effect if AVC is disabled, or the audio output device for AVC is not playing for STREAM_MUSIC
+ */
+ void notifyAvcMuteChange(boolean mute) {
+ if (!isAbsoluteVolumeControlEnabled()) return;
+ List<AudioDeviceAttributes> streamMusicDevices =
+ getAudioManager().getDevicesForAttributes(STREAM_MUSIC_ATTRIBUTES);
+ if (streamMusicDevices.contains(getAvcAudioOutputDevice())) {
+ int direction = mute ? AudioManager.ADJUST_MUTE : AudioManager.ADJUST_UNMUTE;
+ getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC, direction,
+ AudioManager.FLAG_ABSOLUTE_VOLUME);
+ }
+ }
+
+ /**
+ * Sets the volume index of {@link AudioManager#STREAM_MUSIC}. Rescales the input volume index
+ * from HDMI-CEC volume range to STREAM_MUSIC's.
+ */
+ void setStreamMusicVolume(int volume, int flags) {
+ getAudioManager().setStreamVolume(AudioManager.STREAM_MUSIC,
+ volume * mStreamMusicMaxVolume / AudioStatus.MAX_VOLUME, flags);
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/SendKeyAction.java b/services/core/java/com/android/server/hdmi/SendKeyAction.java
index adcef667545f..7daeaf19c657 100644
--- a/services/core/java/com/android/server/hdmi/SendKeyAction.java
+++ b/services/core/java/com/android/server/hdmi/SendKeyAction.java
@@ -172,8 +172,19 @@ final class SendKeyAction extends HdmiCecFeatureAction {
}
private void sendKeyUp() {
- sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(getSourceAddress(),
- mTargetAddress));
+ // When using Absolute Volume Control, query audio status after a volume key is released.
+ // This allows us to notify AudioService of the resulting volume or mute status changes.
+ if (HdmiCecKeycode.isVolumeKeycode(mLastKeycode)
+ && localDevice().getService().isAbsoluteVolumeControlEnabled()) {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(getSourceAddress(),
+ mTargetAddress),
+ __ -> sendCommand(HdmiCecMessageBuilder.buildGiveAudioStatus(
+ getSourceAddress(),
+ localDevice().findAudioReceiverAddress())));
+ } else {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(getSourceAddress(),
+ mTargetAddress));
+ }
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java b/services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java
index 96fd003c72b4..eb3b33d8ca22 100644
--- a/services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java
+++ b/services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java
@@ -122,4 +122,11 @@ public class SetAudioVolumeLevelDiscoveryAction extends HdmiCecFeatureAction {
return true;
}
}
+
+ /**
+ * Returns the logical address of this action's target device.
+ */
+ public int getTargetAddress() {
+ return mTargetAddress;
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
index 978c25d0a8c6..e7a3db75c9d0 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
@@ -153,7 +153,7 @@ abstract class SystemAudioAction extends HdmiCecFeatureAction {
boolean receivedStatus = HdmiUtils.parseCommandParamSystemAudioStatus(cmd);
if (receivedStatus == mTargetAudioStatus) {
setSystemAudioMode(receivedStatus);
- startAudioStatusAction();
+ finish();
return true;
} else {
HdmiLogger.debug("Unexpected system audio mode request:" + receivedStatus);
@@ -168,11 +168,6 @@ abstract class SystemAudioAction extends HdmiCecFeatureAction {
}
}
- protected void startAudioStatusAction() {
- addAndStartAction(new SystemAudioStatusAction(tv(), mAvrLogicalAddress, mCallbacks));
- finish();
- }
-
protected void removeSystemAudioActionInProgress() {
removeActionExcept(SystemAudioActionFromTv.class, this);
removeActionExcept(SystemAudioActionFromAvr.class, this);
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java
index 6ddff91a70f7..99148c4ea114 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java
@@ -16,8 +16,8 @@
package com.android.server.hdmi;
-import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.IHdmiControlCallback;
/**
@@ -65,7 +65,7 @@ final class SystemAudioActionFromAvr extends SystemAudioAction {
if (mTargetAudioStatus) {
setSystemAudioMode(true);
- startAudioStatusAction();
+ finish();
} else {
setSystemAudioMode(false);
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
deleted file mode 100644
index b4af540b96f5..000000000000
--- a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.IHdmiControlCallback;
-import android.hardware.tv.cec.V1_0.SendMessageResult;
-
-import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
-
-import java.util.List;
-
-/**
- * Action to update audio status (volume or mute) of audio amplifier
- */
-final class SystemAudioStatusAction extends HdmiCecFeatureAction {
- private static final String TAG = "SystemAudioStatusAction";
-
- // State that waits for <ReportAudioStatus>.
- private static final int STATE_WAIT_FOR_REPORT_AUDIO_STATUS = 1;
-
- private final int mAvrAddress;
-
- SystemAudioStatusAction(
- HdmiCecLocalDevice source, int avrAddress, List<IHdmiControlCallback> callbacks) {
- super(source, callbacks);
- mAvrAddress = avrAddress;
- }
-
- SystemAudioStatusAction(HdmiCecLocalDevice source, int avrAddress,
- IHdmiControlCallback callback) {
- super(source, callback);
- mAvrAddress = avrAddress;
- }
-
- @Override
- boolean start() {
- mState = STATE_WAIT_FOR_REPORT_AUDIO_STATUS;
- addTimer(mState, HdmiConfig.TIMEOUT_MS);
- sendGiveAudioStatus();
- return true;
- }
-
- private void sendGiveAudioStatus() {
- sendCommand(HdmiCecMessageBuilder.buildGiveAudioStatus(getSourceAddress(), mAvrAddress),
- new SendMessageCallback() {
- @Override
- public void onSendCompleted(int error) {
- if (error != SendMessageResult.SUCCESS) {
- handleSendGiveAudioStatusFailure();
- }
- }
- });
- }
-
- private void handleSendGiveAudioStatusFailure() {
-
- // Still return SUCCESS to callback.
- finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
- }
-
- @Override
- boolean processCommand(HdmiCecMessage cmd) {
- if (mState != STATE_WAIT_FOR_REPORT_AUDIO_STATUS || mAvrAddress != cmd.getSource()) {
- return false;
- }
-
- switch (cmd.getOpcode()) {
- case Constants.MESSAGE_REPORT_AUDIO_STATUS:
- handleReportAudioStatus(cmd);
- return true;
- }
-
- return false;
- }
-
- private void handleReportAudioStatus(HdmiCecMessage cmd) {
- byte[] params = cmd.getParams();
- boolean mute = HdmiUtils.isAudioStatusMute(cmd);
- int volume = HdmiUtils.getAudioStatusVolume(cmd);
- tv().setAudioStatus(mute, volume);
-
- if (!(tv().isSystemAudioActivated() ^ mute)) {
- // Toggle AVR's mute status to match with the system audio status.
- sendUserControlPressedAndReleased(mAvrAddress, HdmiCecKeycode.CEC_KEYCODE_MUTE);
- }
- finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
- }
-
- @Override
- void handleTimerEvent(int state) {
- if (mState != state) {
- return;
- }
-
- handleSendGiveAudioStatusFailure();
- }
-}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 140a28f111e6..385aa698543d 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -20,6 +20,7 @@ import static android.view.KeyEvent.KEYCODE_UNKNOWN;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManagerInternal;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -325,8 +326,7 @@ public class InputManagerService extends IInputManager.Stub
private static native void nativeSetMaximumObscuringOpacityForTouch(long ptr, float opacity);
private static native void nativeSetBlockUntrustedTouchesMode(long ptr, int mode);
private static native int nativeInjectInputEvent(long ptr, InputEvent event,
- int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
- int policyFlags);
+ boolean injectIntoUid, int uid, int syncMode, int timeoutMillis, int policyFlags);
private static native VerifiedInputEvent nativeVerifyInputEvent(long ptr, InputEvent event);
private static native void nativeToggleCapsLock(long ptr, int deviceId);
private static native void nativeDisplayRemoved(long ptr, int displayId);
@@ -897,11 +897,15 @@ public class InputManagerService extends IInputManager.Stub
}
@Override // Binder call
- public boolean injectInputEvent(InputEvent event, int mode) {
- return injectInputEventInternal(event, mode);
- }
-
- private boolean injectInputEventInternal(InputEvent event, int mode) {
+ public boolean injectInputEvent(InputEvent event, int mode, int targetUid) {
+ if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS,
+ "injectInputEvent()", true /*checkInstrumentationSource*/)) {
+ throw new SecurityException(
+ "Injecting input events requires the caller (or the source of the "
+ + "instrumentation, if any) to have the INJECT_EVENTS permission.");
+ }
+ // We are not checking if targetUid matches the callingUid, since having the permission
+ // already means you can inject into any window.
Objects.requireNonNull(event, "event must not be null");
if (mode != InputEventInjectionSync.NONE
&& mode != InputEventInjectionSync.WAIT_FOR_FINISHED
@@ -910,22 +914,41 @@ public class InputManagerService extends IInputManager.Stub
}
final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
+ final boolean injectIntoUid = targetUid != Process.INVALID_UID;
final int result;
try {
- result = nativeInjectInputEvent(mPtr, event, pid, uid, mode,
- INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
+ result = nativeInjectInputEvent(mPtr, event, injectIntoUid,
+ targetUid, mode, INJECTION_TIMEOUT_MILLIS,
+ WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
} finally {
Binder.restoreCallingIdentity(ident);
}
switch (result) {
- case InputEventInjectionResult.PERMISSION_DENIED:
- Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
- throw new SecurityException(
- "Injecting to another application requires INJECT_EVENTS permission");
case InputEventInjectionResult.SUCCEEDED:
return true;
+ case InputEventInjectionResult.TARGET_MISMATCH:
+ if (!injectIntoUid) {
+ throw new IllegalStateException("Injection should not result in TARGET_MISMATCH"
+ + " when it is not targeted into to a specific uid.");
+ }
+ // Attempt to inject into a window owned by the instrumentation source of the caller
+ // because it is possible that tests adopt the identity of the shell when launching
+ // activities that they would like to inject into.
+ final ActivityManagerInternal ami =
+ LocalServices.getService(ActivityManagerInternal.class);
+ Objects.requireNonNull(ami, "ActivityManagerInternal should not be null.");
+ final int instrUid = ami.getInstrumentationSourceUid(Binder.getCallingUid());
+ if (instrUid != Process.INVALID_UID && targetUid != instrUid) {
+ Slog.w(TAG, "Targeted input event was not directed at a window owned by uid "
+ + targetUid + ". Attempting to inject into window owned by "
+ + "instrumentation source uid " + instrUid + ".");
+ return injectInputEvent(event, mode, instrUid);
+ }
+ throw new IllegalArgumentException(
+ "Targeted input event injection from pid " + pid
+ + " was not directed at a window owned by uid "
+ + targetUid + ".");
case InputEventInjectionResult.TIMED_OUT:
Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
return false;
@@ -2761,8 +2784,12 @@ public class InputManagerService extends IInputManager.Stub
}
}
}
-
private boolean checkCallingPermission(String permission, String func) {
+ return checkCallingPermission(permission, func, false /*checkInstrumentationSource*/);
+ }
+
+ private boolean checkCallingPermission(String permission, String func,
+ boolean checkInstrumentationSource) {
// Quick check: if the calling permission is me, it's all okay.
if (Binder.getCallingPid() == Process.myPid()) {
return true;
@@ -2771,6 +2798,18 @@ public class InputManagerService extends IInputManager.Stub
if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
return true;
}
+
+ if (checkInstrumentationSource) {
+ final ActivityManagerInternal ami =
+ LocalServices.getService(ActivityManagerInternal.class);
+ Objects.requireNonNull(ami, "ActivityManagerInternal should not be null.");
+ final int instrumentationUid = ami.getInstrumentationSourceUid(Binder.getCallingUid());
+ if (instrumentationUid != Process.INVALID_UID && mContext.checkPermission(permission,
+ -1 /*pid*/, instrumentationUid) == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ }
+
String msg = "Permission Denial: " + func + " from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid()
@@ -3016,13 +3055,6 @@ public class InputManagerService extends IInputManager.Stub
// Native callback.
@SuppressWarnings("unused")
- private boolean checkInjectEventsPermission(int injectorPid, int injectorUid) {
- return mContext.checkPermission(android.Manifest.permission.INJECT_EVENTS,
- injectorPid, injectorUid) == PackageManager.PERMISSION_GRANTED;
- }
-
- // Native callback.
- @SuppressWarnings("unused")
private void onPointerDownOutsideFocus(IBinder touchedToken) {
mWindowManagerCallbacks.onPointerDownOutsideFocus(touchedToken);
}
@@ -3463,12 +3495,17 @@ public class InputManagerService extends IInputManager.Stub
@Override
public void sendInputEvent(InputEvent event, int policyFlags) {
+ if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS,
+ "sendInputEvent()")) {
+ throw new SecurityException(
+ "The INJECT_EVENTS permission is required for injecting input events.");
+ }
Objects.requireNonNull(event, "event must not be null");
synchronized (mInputFilterLock) {
if (!mDisconnected) {
- nativeInjectInputEvent(mPtr, event, 0, 0,
- InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0,
+ nativeInjectInputEvent(mPtr, event, false /* injectIntoUid */, -1 /* uid */,
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0 /* timeout */,
policyFlags | WindowManagerPolicy.FLAG_FILTERED);
}
}
@@ -3664,11 +3701,6 @@ public class InputManagerService extends IInputManager.Stub
}
@Override
- public boolean injectInputEvent(InputEvent event, int mode) {
- return injectInputEventInternal(event, mode);
- }
-
- @Override
public void setInteractive(boolean interactive) {
nativeSetInteractive(mPtr, interactive);
}
diff --git a/services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java b/services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java
index db81393a9ad6..37a486923b12 100644
--- a/services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java
+++ b/services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java
@@ -30,8 +30,6 @@ import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.os.Binder;
import android.os.HandlerThread;
import android.os.LocaleList;
import android.os.RemoteException;
@@ -78,7 +76,7 @@ class LocaleManagerBackupHelper {
private static final Duration STAGE_DATA_RETENTION_PERIOD = Duration.ofDays(3);
private final LocaleManagerService mLocaleManagerService;
- private final PackageManagerInternal mPackageManagerInternal;
+ private final PackageManager mPackageManager;
private final Clock mClock;
private final Context mContext;
private final Object mStagedDataLock = new Object();
@@ -90,18 +88,18 @@ class LocaleManagerBackupHelper {
private final BroadcastReceiver mUserMonitor;
LocaleManagerBackupHelper(LocaleManagerService localeManagerService,
- PackageManagerInternal pmInternal, HandlerThread broadcastHandlerThread) {
- this(localeManagerService.mContext, localeManagerService, pmInternal, Clock.systemUTC(),
+ PackageManager packageManager, HandlerThread broadcastHandlerThread) {
+ this(localeManagerService.mContext, localeManagerService, packageManager, Clock.systemUTC(),
new SparseArray<>(), broadcastHandlerThread);
}
@VisibleForTesting LocaleManagerBackupHelper(Context context,
LocaleManagerService localeManagerService,
- PackageManagerInternal pmInternal, Clock clock, SparseArray<StagedData> stagedData,
+ PackageManager packageManager, Clock clock, SparseArray<StagedData> stagedData,
HandlerThread broadcastHandlerThread) {
mContext = context;
mLocaleManagerService = localeManagerService;
- mPackageManagerInternal = pmInternal;
+ mPackageManager = packageManager;
mClock = clock;
mStagedData = stagedData;
@@ -130,8 +128,8 @@ class LocaleManagerBackupHelper {
}
HashMap<String, String> pkgStates = new HashMap<>();
- for (ApplicationInfo appInfo : mPackageManagerInternal.getInstalledApplications(/*flags*/0,
- userId, Binder.getCallingUid())) {
+ for (ApplicationInfo appInfo : mPackageManager.getInstalledApplicationsAsUser(
+ PackageManager.ApplicationInfoFlags.of(0), userId)) {
try {
LocaleList appLocales = mLocaleManagerService.getApplicationLocales(
appInfo.packageName,
diff --git a/services/core/java/com/android/server/locales/LocaleManagerService.java b/services/core/java/com/android/server/locales/LocaleManagerService.java
index 924db6a49eeb..9ef14cc38993 100644
--- a/services/core/java/com/android/server/locales/LocaleManagerService.java
+++ b/services/core/java/com/android/server/locales/LocaleManagerService.java
@@ -28,7 +28,7 @@ import android.app.ILocaleManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
+import android.content.pm.PackageManager.PackageInfoFlags;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.HandlerThread;
@@ -60,7 +60,7 @@ public class LocaleManagerService extends SystemService {
private final LocaleManagerService.LocaleManagerBinderService mBinderService;
private ActivityTaskManagerInternal mActivityTaskManagerInternal;
private ActivityManagerInternal mActivityManagerInternal;
- private PackageManagerInternal mPackageManagerInternal;
+ private PackageManager mPackageManager;
private LocaleManagerBackupHelper mBackupHelper;
@@ -74,7 +74,7 @@ public class LocaleManagerService extends SystemService {
mBinderService = new LocaleManagerBinderService();
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
- mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
+ mPackageManager = mContext.getPackageManager();
HandlerThread broadcastHandlerThread = new HandlerThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND);
@@ -90,7 +90,7 @@ public class LocaleManagerService extends SystemService {
});
mBackupHelper = new LocaleManagerBackupHelper(this,
- mPackageManagerInternal, broadcastHandlerThread);
+ mPackageManager, broadcastHandlerThread);
mPackageMonitor = new LocaleManagerServicePackageMonitor(mBackupHelper,
systemAppUpdateTracker);
@@ -102,7 +102,7 @@ public class LocaleManagerService extends SystemService {
@VisibleForTesting
LocaleManagerService(Context context, ActivityTaskManagerInternal activityTaskManagerInternal,
ActivityManagerInternal activityManagerInternal,
- PackageManagerInternal packageManagerInternal,
+ PackageManager packageManager,
LocaleManagerBackupHelper localeManagerBackupHelper,
PackageMonitor packageMonitor) {
super(context);
@@ -110,7 +110,7 @@ public class LocaleManagerService extends SystemService {
mBinderService = new LocaleManagerBinderService();
mActivityTaskManagerInternal = activityTaskManagerInternal;
mActivityManagerInternal = activityManagerInternal;
- mPackageManagerInternal = packageManagerInternal;
+ mPackageManager = packageManager;
mBackupHelper = localeManagerBackupHelper;
mPackageMonitor = packageMonitor;
}
@@ -419,8 +419,12 @@ public class LocaleManagerService extends SystemService {
}
private int getPackageUid(String appPackageName, int userId) {
- return mPackageManagerInternal
- .getPackageUid(appPackageName, /* flags */ 0, userId);
+ try {
+ return mPackageManager
+ .getPackageUidAsUser(appPackageName, PackageInfoFlags.of(0), userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ return Process.INVALID_UID;
+ }
}
@Nullable
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index fac510651878..31d5136c80a5 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -94,7 +94,6 @@ import android.util.IndentingPrintWriter;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
@@ -279,6 +278,9 @@ public class LocationManagerService extends ILocationManager.Stub implements
this::onLocationUserSettingsChanged);
mInjector.getSettingsHelper().addOnLocationEnabledChangedListener(
this::onLocationModeChanged);
+ mInjector.getSettingsHelper().addAdasAllowlistChangedListener(
+ () -> refreshAppOpsRestrictions(UserHandle.USER_ALL)
+ );
mInjector.getSettingsHelper().addIgnoreSettingsAllowlistChangedListener(
() -> refreshAppOpsRestrictions(UserHandle.USER_ALL));
mInjector.getUserInfoHelper().addListener((userId, change) -> {
@@ -823,12 +825,6 @@ public class LocationManagerService extends ILocationManager.Stub implements
throw new IllegalArgumentException(
"adas gnss bypass requests are only allowed on the \"gps\" provider");
}
- if (!ArrayUtils.contains(mContext.getResources().getStringArray(
- com.android.internal.R.array.config_locationDriverAssistancePackageNames),
- identity.getPackageName())) {
- throw new SecurityException(
- "only verified adas packages may use adas gnss bypass requests");
- }
if (!isLocationProvider) {
LocationPermissions.enforceCallingOrSelfBypassPermission(mContext);
}
@@ -923,12 +919,6 @@ public class LocationManagerService extends ILocationManager.Stub implements
throw new IllegalArgumentException(
"adas gnss bypass requests are only allowed on the \"gps\" provider");
}
- if (!ArrayUtils.contains(mContext.getResources().getStringArray(
- com.android.internal.R.array.config_locationDriverAssistancePackageNames),
- identity.getPackageName())) {
- throw new SecurityException(
- "only verified adas packages may use adas gnss bypass requests");
- }
if (!isLocationProvider) {
LocationPermissions.enforceCallingOrSelfBypassPermission(mContext);
}
@@ -1542,6 +1532,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
}
}
builder.add(mInjector.getSettingsHelper().getIgnoreSettingsAllowlist());
+ builder.add(mInjector.getSettingsHelper().getAdasAllowlist());
allowedPackages = builder.build();
}
diff --git a/services/core/java/com/android/server/location/injector/SettingsHelper.java b/services/core/java/com/android/server/location/injector/SettingsHelper.java
index 148afa75ca75..490bfe1ab82f 100644
--- a/services/core/java/com/android/server/location/injector/SettingsHelper.java
+++ b/services/core/java/com/android/server/location/injector/SettingsHelper.java
@@ -146,6 +146,20 @@ public abstract class SettingsHelper {
public abstract void removeOnGnssMeasurementsFullTrackingEnabledChangedListener(
GlobalSettingChangedListener listener);
+ /** Retrieve adas allowlist. */
+ public abstract PackageTagsList getAdasAllowlist();
+
+ /**
+ * Add a listener for changes to the ADAS settings package allowlist. Callbacks occur on an
+ * unspecified thread.
+ */
+ public abstract void addAdasAllowlistChangedListener(GlobalSettingChangedListener listener);
+
+ /**
+ * Remove a listener for changes to the ADAS package allowlist.
+ */
+ public abstract void removeAdasAllowlistChangedListener(GlobalSettingChangedListener listener);
+
/**
* Retrieve the ignore location settings package+tags allowlist setting.
*/
diff --git a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
index 3e8da7d7478a..777683ef59cf 100644
--- a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
@@ -16,6 +16,7 @@
package com.android.server.location.injector;
+import static android.location.LocationDeviceConfig.ADAS_SETTINGS_ALLOWLIST;
import static android.location.LocationDeviceConfig.IGNORE_SETTINGS_ALLOWLIST;
import static android.provider.Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING;
import static android.provider.Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS;
@@ -80,6 +81,7 @@ public class SystemSettingsHelper extends SettingsHelper {
private final StringListCachedSecureSetting mLocationPackageBlacklist;
private final StringListCachedSecureSetting mLocationPackageWhitelist;
private final StringSetCachedGlobalSetting mBackgroundThrottlePackageWhitelist;
+ private final PackageTagsListSetting mAdasPackageAllowlist;
private final PackageTagsListSetting mIgnoreSettingsPackageAllowlist;
public SystemSettingsHelper(Context context) {
@@ -98,6 +100,9 @@ public class SystemSettingsHelper extends SettingsHelper {
LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
() -> SystemConfig.getInstance().getAllowUnthrottledLocation(),
FgThread.getHandler());
+ mAdasPackageAllowlist = new PackageTagsListSetting(
+ ADAS_SETTINGS_ALLOWLIST,
+ () -> SystemConfig.getInstance().getAllowAdasLocationSettings());
mIgnoreSettingsPackageAllowlist = new PackageTagsListSetting(
IGNORE_SETTINGS_ALLOWLIST,
() -> SystemConfig.getInstance().getAllowIgnoreLocationSettings());
@@ -233,6 +238,21 @@ public class SystemSettingsHelper extends SettingsHelper {
}
@Override
+ public PackageTagsList getAdasAllowlist() {
+ return mAdasPackageAllowlist.getValue();
+ }
+
+ @Override
+ public void addAdasAllowlistChangedListener(GlobalSettingChangedListener listener) {
+ mAdasPackageAllowlist.addListener(listener);
+ }
+
+ @Override
+ public void removeAdasAllowlistChangedListener(GlobalSettingChangedListener listener) {
+ mAdasPackageAllowlist.removeListener(listener);
+ }
+
+ @Override
public PackageTagsList getIgnoreSettingsAllowlist() {
return mIgnoreSettingsPackageAllowlist.getValue();
}
@@ -359,11 +379,19 @@ public class SystemSettingsHelper extends SettingsHelper {
PackageTagsList ignoreSettingsAllowlist = mIgnoreSettingsPackageAllowlist.getValue();
if (!ignoreSettingsAllowlist.isEmpty()) {
- ipw.println("Bypass Allow Packages:");
+ ipw.println("Emergency Bypass Allow Packages:");
ipw.increaseIndent();
ignoreSettingsAllowlist.dump(ipw);
ipw.decreaseIndent();
}
+
+ PackageTagsList adasPackageAllowlist = mAdasPackageAllowlist.getValue();
+ if (!adasPackageAllowlist.isEmpty()) {
+ ipw.println("ADAS Bypass Allow Packages:");
+ ipw.increaseIndent();
+ adasPackageAllowlist.dump(ipw);
+ ipw.decreaseIndent();
+ }
}
private abstract static class ObservingSetting extends ContentObserver {
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 721ef1ed358f..1235352b0590 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -699,6 +699,9 @@ public class LocationProviderManager extends
} else if (!mLocationSettings.getUserSettings(
getIdentity().getUserId()).isAdasGnssLocationEnabled()) {
adasGnssBypass = false;
+ } else if (!mSettingsHelper.getAdasAllowlist().contains(
+ getIdentity().getPackageName(), getIdentity().getAttributionTag())) {
+ adasGnssBypass = false;
}
builder.setAdasGnssBypass(adasGnssBypass);
@@ -1406,6 +1409,8 @@ public class LocationProviderManager extends
this::onAppForegroundChanged;
private final GlobalSettingChangedListener mBackgroundThrottleIntervalChangedListener =
this::onBackgroundThrottleIntervalChanged;
+ private final GlobalSettingChangedListener mAdasPackageAllowlistChangedListener =
+ this::onAdasAllowlistChanged;
private final GlobalSettingChangedListener mIgnoreSettingsPackageWhitelistChangedListener =
this::onIgnoreSettingsWhitelistChanged;
private final LocationPowerSaveModeChangedListener mLocationPowerSaveModeChangedListener =
@@ -1710,6 +1715,9 @@ public class LocationProviderManager extends
} else if (!mLocationSettings.getUserSettings(
identity.getUserId()).isAdasGnssLocationEnabled()) {
adasGnssBypass = false;
+ } else if (!mSettingsHelper.getAdasAllowlist().contains(
+ identity.getPackageName(), identity.getAttributionTag())) {
+ adasGnssBypass = false;
}
builder.setAdasGnssBypass(adasGnssBypass);
@@ -1979,6 +1987,8 @@ public class LocationProviderManager extends
mBackgroundThrottlePackageWhitelistChangedListener);
mSettingsHelper.addOnLocationPackageBlacklistChangedListener(
mLocationPackageBlacklistChangedListener);
+ mSettingsHelper.addAdasAllowlistChangedListener(
+ mAdasPackageAllowlistChangedListener);
mSettingsHelper.addIgnoreSettingsAllowlistChangedListener(
mIgnoreSettingsPackageWhitelistChangedListener);
mLocationPermissionsHelper.addListener(mLocationPermissionsListener);
@@ -2000,6 +2010,7 @@ public class LocationProviderManager extends
mBackgroundThrottlePackageWhitelistChangedListener);
mSettingsHelper.removeOnLocationPackageBlacklistChangedListener(
mLocationPackageBlacklistChangedListener);
+ mSettingsHelper.removeAdasAllowlistChangedListener(mAdasPackageAllowlistChangedListener);
mSettingsHelper.removeIgnoreSettingsAllowlistChangedListener(
mIgnoreSettingsPackageWhitelistChangedListener);
mLocationPermissionsHelper.removeListener(mLocationPermissionsListener);
@@ -2422,6 +2433,12 @@ public class LocationProviderManager extends
}
}
+ private void onAdasAllowlistChanged() {
+ synchronized (mLock) {
+ updateRegistrations(Registration::onProviderLocationRequestChanged);
+ }
+ }
+
private void onIgnoreSettingsWhitelistChanged() {
synchronized (mLock) {
updateRegistrations(Registration::onProviderLocationRequestChanged);
diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java
index 7b63fa24088b..015bf3c5e390 100644
--- a/services/core/java/com/android/server/logcat/LogcatManagerService.java
+++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java
@@ -23,7 +23,6 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.os.Binder;
import android.os.ILogd;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -76,6 +75,7 @@ public final class LogcatManagerService extends SystemService {
@Override
public void approve(int uid, int gid, int pid, int fd) {
try {
+ Slog.d(TAG, "Allow logd access for uid: " + uid);
getLogdService().approve(uid, gid, pid, fd);
} catch (RemoteException e) {
Slog.e(TAG, "Fails to call remote functions", e);
@@ -85,6 +85,7 @@ public final class LogcatManagerService extends SystemService {
@Override
public void decline(int uid, int gid, int pid, int fd) {
try {
+ Slog.d(TAG, "Decline logd access for uid: " + uid);
getLogdService().decline(uid, gid, pid, fd);
} catch (RemoteException e) {
Slog.e(TAG, "Fails to call remote functions", e);
@@ -182,7 +183,8 @@ public final class LogcatManagerService extends SystemService {
ActivityManagerInternal ami = LocalServices.getService(
ActivityManagerInternal.class);
- boolean isCallerInstrumented = ami.isUidCurrentlyInstrumented(mUid);
+ boolean isCallerInstrumented =
+ ami.getInstrumentationSourceUid(mUid) != android.os.Process.INVALID_UID;
// The instrumented apks only run for testing, so we don't check user permission.
if (isCallerInstrumented) {
@@ -194,8 +196,9 @@ public final class LogcatManagerService extends SystemService {
return;
}
- final int procState = mActivityManager.getUidImportance(Binder.getCallingUid());
- // If the process is foreground, send a notification for user consent
+ final int procState = LocalServices.getService(ActivityManagerInternal.class)
+ .getUidProcessState(mUid);
+ // If the process is foreground, show a dialog for user consent
if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
showDialog(mUid, mGid, mPid, mFd);
} else {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 74b11daf6c74..e5a6e6529ebc 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1007,7 +1007,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int changes = ActivityManager.UID_OBSERVER_PROCSTATE
| ActivityManager.UID_OBSERVER_GONE
| ActivityManager.UID_OBSERVER_CAPABILITY;
- mActivityManager.registerUidObserver(mUidObserver, changes,
+ mActivityManagerInternal.registerNetworkPolicyUidObserver(mUidObserver, changes,
NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
mNetworkManager.registerObserver(mAlertObserver);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 9af5b667fc44..f42e734b96ec 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2558,14 +2558,8 @@ public class NotificationManagerService extends SystemService {
@Override
public void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
boolean needsOngoingFlag) {
- NotificationRecord r = createAutoGroupSummary(
+ NotificationManagerService.this.addAutoGroupSummary(
userId, pkg, triggeringKey, needsOngoingFlag);
- if (r != null) {
- final boolean isAppForeground =
- mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
- mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
- SystemClock.elapsedRealtime()));
- }
}
@Override
@@ -5758,17 +5752,30 @@ public class NotificationManagerService extends SystemService {
r.addAdjustment(adjustment);
}
+ @VisibleForTesting
+ void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
+ boolean needsOngoingFlag) {
+ NotificationRecord r = createAutoGroupSummary(
+ userId, pkg, triggeringKey, needsOngoingFlag);
+ if (r != null) {
+ final boolean isAppForeground =
+ mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
+ mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
+ SystemClock.elapsedRealtime()));
+ }
+ }
+
// Clears the 'fake' auto-group summary.
+ @VisibleForTesting
@GuardedBy("mNotificationLock")
- private void clearAutogroupSummaryLocked(int userId, String pkg) {
+ void clearAutogroupSummaryLocked(int userId, String pkg) {
ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
if (summaries != null && summaries.containsKey(pkg)) {
- // Clear summary.
final NotificationRecord removed = findNotificationByKeyLocked(summaries.remove(pkg));
if (removed != null) {
- boolean wasPosted = removeFromNotificationListsLocked(removed);
- cancelNotificationLocked(removed, false, REASON_UNAUTOBUNDLED, wasPosted, null,
- SystemClock.elapsedRealtime());
+ final StatusBarNotification sbn = removed.getSbn();
+ cancelNotification(MY_UID, MY_PID, pkg, sbn.getTag(), sbn.getId(), 0, 0, false,
+ userId, REASON_UNAUTOBUNDLED, null);
}
}
}
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index 5013570fa6b8..66f71a37e0a3 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -386,6 +386,7 @@ final class AppDataHelper {
final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
+ final Computer snapshot = mPm.snapshotComputer();
// First look for stale data that doesn't belong, and check if things
// have changed since we did our last restorecon
if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
@@ -400,7 +401,7 @@ final class AppDataHelper {
for (File file : files) {
final String packageName = file.getName();
try {
- assertPackageStorageValid(volumeUuid, packageName, userId);
+ assertPackageStorageValid(snapshot, volumeUuid, packageName, userId);
} catch (PackageManagerException e) {
logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
try {
@@ -417,7 +418,7 @@ final class AppDataHelper {
for (File file : files) {
final String packageName = file.getName();
try {
- assertPackageStorageValid(volumeUuid, packageName, userId);
+ assertPackageStorageValid(snapshot, volumeUuid, packageName, userId);
} catch (PackageManagerException e) {
logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
try {
@@ -434,12 +435,9 @@ final class AppDataHelper {
// installed for this volume and user
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "prepareAppDataAndMigrate");
Installer.Batch batch = new Installer.Batch();
- final List<PackageSetting> packages;
- synchronized (mPm.mLock) {
- packages = mPm.mSettings.getVolumePackagesLPr(volumeUuid);
- }
+ List<? extends PackageStateInternal> packages = snapshot.getVolumePackages(volumeUuid);
int preparedCount = 0;
- for (PackageSetting ps : packages) {
+ for (PackageStateInternal ps : packages) {
final String packageName = ps.getPackageName();
if (ps.getPkg() == null) {
Slog.w(TAG, "Odd, missing scanned package " + packageName);
@@ -453,7 +451,7 @@ final class AppDataHelper {
continue;
}
- if (ps.getInstalled(userId)) {
+ if (ps.getUserStateOrDefault(userId).isInstalled()) {
prepareAppDataAndMigrate(batch, ps.getPkg(), userId, flags, migrateAppData);
preparedCount++;
}
@@ -469,35 +467,25 @@ final class AppDataHelper {
* Asserts that storage path is valid by checking that {@code packageName} is present,
* installed for the given {@code userId} and can have app data.
*/
- private void assertPackageStorageValid(String volumeUuid, String packageName, int userId)
- throws PackageManagerException {
- synchronized (mPm.mLock) {
- // Normalize package name to handle renamed packages
- packageName = normalizePackageNameLPr(packageName);
-
- final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
- if (ps == null) {
- throw new PackageManagerException("Package " + packageName + " is unknown");
- } else if (!TextUtils.equals(volumeUuid, ps.getVolumeUuid())) {
- throw new PackageManagerException(
- "Package " + packageName + " found on unknown volume " + volumeUuid
- + "; expected volume " + ps.getVolumeUuid());
- } else if (!ps.getInstalled(userId)) {
- throw new PackageManagerException(
- "Package " + packageName + " not installed for user " + userId);
- } else if (ps.getPkg() != null && !shouldHaveAppStorage(ps.getPkg())) {
- throw new PackageManagerException(
- "Package " + packageName + " shouldn't have storage");
- }
+ private void assertPackageStorageValid(@NonNull Computer snapshot, String volumeUuid,
+ String packageName, int userId) throws PackageManagerException {
+ final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+ if (packageState == null) {
+ throw new PackageManagerException("Package " + packageName + " is unknown");
+ } else if (!TextUtils.equals(volumeUuid, packageState.getVolumeUuid())) {
+ throw new PackageManagerException(
+ "Package " + packageName + " found on unknown volume " + volumeUuid
+ + "; expected volume " + packageState.getVolumeUuid());
+ } else if (!packageState.getUserStateOrDefault(userId).isInstalled()) {
+ throw new PackageManagerException(
+ "Package " + packageName + " not installed for user " + userId);
+ } else if (packageState.getPkg() != null
+ && !shouldHaveAppStorage(packageState.getPkg())) {
+ throw new PackageManagerException(
+ "Package " + packageName + " shouldn't have storage");
}
}
- @GuardedBy("mPm.mLock")
- private String normalizePackageNameLPr(String packageName) {
- String normalizedPackageName = mPm.mSettings.getRenamedPackageLPr(packageName);
- return normalizedPackageName != null ? normalizedPackageName : packageName;
- }
-
/**
* Prepare storage for system user really early during boot,
* since core system apps like SettingsProvider and SystemUI
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 17dc403cf2c5..29ee28175f57 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -44,6 +44,7 @@ import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import android.util.SparseSetArray;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -63,18 +64,14 @@ import com.android.server.pm.pkg.component.ParsedMainComponent;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;
+import com.android.server.utils.Snapshots;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableImpl;
-import com.android.server.utils.Watched;
-import com.android.server.utils.WatchedArrayList;
import com.android.server.utils.WatchedArrayMap;
-import com.android.server.utils.WatchedArraySet;
import com.android.server.utils.WatchedSparseBooleanMatrix;
-import com.android.server.utils.WatchedSparseSetArray;
import com.android.server.utils.Watcher;
import java.io.PrintWriter;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -87,7 +84,7 @@ import java.util.concurrent.Executor;
* manifests.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable {
+public class AppsFilter implements Watchable, Snappable {
private static final String TAG = "AppsFilter";
@@ -102,48 +99,32 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
* application B is implicitly allowed to query for application A; regardless of any manifest
* entries.
*/
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mImplicitlyQueryable;
- private final SnapshotCache<WatchedSparseSetArray<Integer>> mImplicitQueryableSnapshot;
+ private final SparseSetArray<Integer> mImplicitlyQueryable = new SparseSetArray<>();
/**
* This contains a list of app UIDs that are implicitly queryable because another app explicitly
* interacted with it, but could keep across package updates. For example, if application A
* grants persistable uri permission to application B; regardless of any manifest entries.
*/
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mRetainedImplicitlyQueryable;
- private final SnapshotCache<WatchedSparseSetArray<Integer>>
- mRetainedImplicitlyQueryableSnapshot;
+ private final SparseSetArray<Integer> mRetainedImplicitlyQueryable = new SparseSetArray<>();
/**
* A mapping from the set of App IDs that query other App IDs via package name to the
* list of packages that they can see.
*/
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mQueriesViaPackage;
- private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaPackageSnapshot;
+ private final SparseSetArray<Integer> mQueriesViaPackage = new SparseSetArray<>();
/**
* A mapping from the set of App IDs that query others via component match to the list
* of packages that the they resolve to.
*/
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mQueriesViaComponent;
- private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaComponentSnapshot;
+ private final SparseSetArray<Integer> mQueriesViaComponent = new SparseSetArray<>();
/**
* A mapping from the set of App IDs that query other App IDs via library name to the
* list of packages that they can see.
*/
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mQueryableViaUsesLibrary;
- private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;
+ private final SparseSetArray<Integer> mQueryableViaUsesLibrary = new SparseSetArray<>();
/**
* Executor for running reasonably short background tasks such as building the initial
@@ -163,10 +144,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
* A set of App IDs that are always queryable by any package, regardless of their manifest
* content.
*/
- @Watched
- @GuardedBy("mLock")
- private final WatchedArraySet<Integer> mForceQueryable;
- private final SnapshotCache<WatchedArraySet<Integer>> mForceQueryableSnapshot;
+ private final ArraySet<Integer> mForceQueryable = new ArraySet<>();
/**
* The set of package names provided by the device that should be force queryable regardless of
@@ -176,16 +154,14 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
/** True if all system apps should be made queryable by default. */
private final boolean mSystemAppsQueryable;
+
private final FeatureConfig mFeatureConfig;
private final OverlayReferenceMapper mOverlayReferenceMapper;
private final StateProvider mStateProvider;
private final PackageManagerInternal mPmInternal;
- private SigningDetails mSystemSigningDetails;
- @GuardedBy("mLock")
- @Watched
- private final WatchedArrayList<String> mProtectedBroadcasts;
- private final SnapshotCache<WatchedArrayList<String>> mProtectedBroadcastsSnapshot;
+ private SigningDetails mSystemSigningDetails;
+ private Set<String> mProtectedBroadcasts = new ArraySet<>();
private final Object mCacheLock = new Object();
@@ -194,29 +170,24 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
* filtered to the second. It's essentially a cache of the
* {@link #shouldFilterApplicationInternal(int, Object, PackageStateInternal, int)} call.
* NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on
- * initial scam and is empty until {@link #onSystemReady()} is called.
+ * initial scam and is empty until {@link #mSystemReady} is true.
*/
@GuardedBy("mCacheLock")
@NonNull
private final WatchedSparseBooleanMatrix mShouldFilterCache;
- private final SnapshotCache<WatchedSparseBooleanMatrix> mShouldFilterCacheSnapshot;
- /**
- * Guards the accesses for the list/set fields except for {@link #mShouldFilterCache}
- */
- private final Object mLock = new Object();
+ private volatile boolean mSystemReady = false;
/**
* A cached snapshot.
*/
- private final SnapshotCache<AppsFilterImpl> mSnapshot;
+ private final SnapshotCache<AppsFilter> mSnapshot;
- private SnapshotCache<AppsFilterImpl> makeCache() {
- return new SnapshotCache<AppsFilterImpl>(this, this) {
+ private SnapshotCache<AppsFilter> makeCache() {
+ return new SnapshotCache<AppsFilter>(this, this) {
@Override
- public AppsFilterImpl createSnapshot() {
- AppsFilterImpl s = new AppsFilterImpl(mSource);
- s.mWatchable.seal();
+ public AppsFilter createSnapshot() {
+ AppsFilter s = new AppsFilter(mSource);
return s;
}
};
@@ -226,15 +197,6 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
* Watchable machinery
*/
private final WatchableImpl mWatchable = new WatchableImpl();
- /**
- * The observer that watches for changes from array members
- */
- private final Watcher mObserver = new Watcher() {
- @Override
- public void onChange(@Nullable Watchable what) {
- AppsFilterImpl.this.dispatchChange(what);
- }
- };
/**
* Ensures an observer is in the list, exactly once. The observer cannot be null. The
@@ -289,7 +251,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
@VisibleForTesting(visibility = PRIVATE)
- AppsFilterImpl(StateProvider stateProvider,
+ AppsFilter(StateProvider stateProvider,
FeatureConfig featureConfig,
String[] forceQueryableList,
boolean systemAppsQueryable,
@@ -304,87 +266,38 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
mStateProvider = stateProvider;
mPmInternal = pmInternal;
mBackgroundExecutor = backgroundExecutor;
- mImplicitlyQueryable = new WatchedSparseSetArray<>();
- mImplicitQueryableSnapshot = new SnapshotCache.Auto<>(
- mImplicitlyQueryable, mImplicitlyQueryable, "AppsFilter.mImplicitlyQueryable");
- mRetainedImplicitlyQueryable = new WatchedSparseSetArray<>();
- mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Auto<>(
- mRetainedImplicitlyQueryable, mRetainedImplicitlyQueryable,
- "AppsFilter.mRetainedImplicitlyQueryable");
- mQueriesViaPackage = new WatchedSparseSetArray<>();
- mQueriesViaPackageSnapshot = new SnapshotCache.Auto<>(
- mQueriesViaPackage, mQueriesViaPackage, "AppsFilter.mQueriesViaPackage");
- mQueriesViaComponent = new WatchedSparseSetArray<>();
- mQueriesViaComponentSnapshot = new SnapshotCache.Auto<>(
- mQueriesViaComponent, mQueriesViaComponent, "AppsFilter.mQueriesViaComponent");
- mQueryableViaUsesLibrary = new WatchedSparseSetArray<>();
- mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Auto<>(
- mQueryableViaUsesLibrary, mQueryableViaUsesLibrary,
- "AppsFilter.mQueryableViaUsesLibrary");
- mForceQueryable = new WatchedArraySet<>();
- mForceQueryableSnapshot = new SnapshotCache.Auto<>(
- mForceQueryable, mForceQueryable, "AppsFilter.mForceQueryable");
- mProtectedBroadcasts = new WatchedArrayList<>();
- mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>(
- mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
mShouldFilterCache = new WatchedSparseBooleanMatrix();
- mShouldFilterCacheSnapshot = new SnapshotCache.Auto<>(
- mShouldFilterCache, mShouldFilterCache, "AppsFilter.mShouldFilterCache");
-
- registerObservers();
- Watchable.verifyWatchedAttributes(this, mObserver);
mSnapshot = makeCache();
}
/**
* The copy constructor is used by PackageManagerService to construct a snapshot.
+ * Attributes are not deep-copied since these are supposed to be immutable.
+ * TODO: deep-copy the attributes, if necessary.
*/
- private AppsFilterImpl(AppsFilterImpl orig) {
- synchronized (orig.mLock) {
- mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot();
- mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>();
- mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot();
- mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Sealed<>();
- mQueriesViaPackage = orig.mQueriesViaPackageSnapshot.snapshot();
- mQueriesViaPackageSnapshot = new SnapshotCache.Sealed<>();
- mQueriesViaComponent = orig.mQueriesViaComponentSnapshot.snapshot();
- mQueriesViaComponentSnapshot = new SnapshotCache.Sealed<>();
- mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot();
- mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>();
- mForceQueryable = orig.mForceQueryableSnapshot.snapshot();
- mForceQueryableSnapshot = new SnapshotCache.Sealed<>();
- mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot();
- mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>();
- }
+ private AppsFilter(AppsFilter orig) {
+ Snapshots.copy(mImplicitlyQueryable, orig.mImplicitlyQueryable);
+ Snapshots.copy(mRetainedImplicitlyQueryable, orig.mRetainedImplicitlyQueryable);
+ Snapshots.copy(mQueriesViaPackage, orig.mQueriesViaPackage);
+ Snapshots.copy(mQueriesViaComponent, orig.mQueriesViaComponent);
+ Snapshots.copy(mQueryableViaUsesLibrary, orig.mQueryableViaUsesLibrary);
mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute;
- mForceQueryableByDevicePackageNames =
- Arrays.copyOf(orig.mForceQueryableByDevicePackageNames,
- orig.mForceQueryableByDevicePackageNames.length);
+ mForceQueryable.addAll(orig.mForceQueryable);
+ mForceQueryableByDevicePackageNames = orig.mForceQueryableByDevicePackageNames;
mSystemAppsQueryable = orig.mSystemAppsQueryable;
mFeatureConfig = orig.mFeatureConfig;
mOverlayReferenceMapper = orig.mOverlayReferenceMapper;
mStateProvider = orig.mStateProvider;
mSystemSigningDetails = orig.mSystemSigningDetails;
+ mProtectedBroadcasts = orig.mProtectedBroadcasts;
synchronized (orig.mCacheLock) {
- mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot();
- mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>();
+ mShouldFilterCache = orig.mShouldFilterCache.snapshot();
}
mBackgroundExecutor = null;
mPmInternal = null;
mSnapshot = new SnapshotCache.Sealed<>();
- }
-
- @SuppressWarnings("GuardedBy")
- private void registerObservers() {
- mImplicitlyQueryable.registerObserver(mObserver);
- mRetainedImplicitlyQueryable.registerObserver(mObserver);
- mQueriesViaPackage.registerObserver(mObserver);
- mQueriesViaComponent.registerObserver(mObserver);
- mQueryableViaUsesLibrary.registerObserver(mObserver);
- mForceQueryable.registerObserver(mObserver);
- mProtectedBroadcasts.registerObserver(mObserver);
- mShouldFilterCache.registerObserver(mObserver);
+ mSystemReady = true;
}
/**
@@ -392,7 +305,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
* the function ensures that this function returns a valid snapshot even if a race
* condition causes the cached snapshot to be cleared asynchronously to this method.
*/
- public AppsFilterSnapshot snapshot() {
+ public AppsFilter snapshot() {
return mSnapshot.snapshot();
}
@@ -453,7 +366,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
@Nullable
private SparseBooleanArray mLoggingEnabled = null;
- private AppsFilterImpl mAppsFilter;
+ private AppsFilter mAppsFilter;
private FeatureConfigImpl(
PackageManagerInternal pmInternal, PackageManagerServiceInjector injector) {
@@ -461,7 +374,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
mInjector = injector;
}
- public void setAppsFilter(AppsFilterImpl filter) {
+ public void setAppsFilter(AppsFilter filter) {
mAppsFilter = filter;
}
@@ -565,9 +478,8 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
@Override
public void updatePackageState(PackageStateInternal setting, boolean removed) {
- final boolean enableLogging = setting.getPkg() != null
- && !removed && (setting.getPkg().isTestOnly()
- || setting.getPkg().isDebuggable());
+ final boolean enableLogging = setting.getPkg() != null &&
+ !removed && (setting.getPkg().isTestOnly() || setting.getPkg().isDebuggable());
enableLogging(setting.getAppId(), enableLogging);
if (removed) {
mDisabledPackages.remove(setting.getPackageName());
@@ -578,7 +490,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
/** Builder method for an AppsFilter */
- public static AppsFilterImpl create(@NonNull PackageManagerServiceInjector injector,
+ public static AppsFilter create(@NonNull PackageManagerServiceInjector injector,
@NonNull PackageManagerInternal pmInt) {
final boolean forceSystemAppsQueryable =
injector.getContext().getResources()
@@ -602,7 +514,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
injector.getUserManagerInternal().getUserInfos());
}
};
- AppsFilterImpl appsFilter = new AppsFilterImpl(stateProvider, featureConfig,
+ AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig,
forcedQueryablePackageNames, forceSystemAppsQueryable, null,
injector.getBackgroundExecutor(), pmInt);
featureConfig.setAppsFilter(appsFilter);
@@ -615,7 +527,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
/** Returns true if the querying package may query for the potential target package */
private static boolean canQueryViaComponents(AndroidPackage querying,
- AndroidPackage potentialTarget, WatchedArrayList<String> protectedBroadcasts) {
+ AndroidPackage potentialTarget, Set<String> protectedBroadcasts) {
if (!querying.getQueriesIntents().isEmpty()) {
for (Intent intent : querying.getQueriesIntents()) {
if (matchesPackage(intent, potentialTarget, protectedBroadcasts)) {
@@ -687,7 +599,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
private static boolean matchesPackage(Intent intent, AndroidPackage potentialTarget,
- WatchedArrayList<String> protectedBroadcasts) {
+ Set<String> protectedBroadcasts) {
if (matchesAnyComponents(
intent, potentialTarget.getServices(), null /*protectedBroadcasts*/)) {
return true;
@@ -708,7 +620,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
private static boolean matchesAnyComponents(Intent intent,
List<? extends ParsedMainComponent> components,
- WatchedArrayList<String> protectedBroadcasts) {
+ Set<String> protectedBroadcasts) {
for (int i = ArrayUtils.size(components) - 1; i >= 0; i--) {
ParsedMainComponent component = components.get(i);
if (!component.isExported()) {
@@ -722,7 +634,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
private static boolean matchesAnyFilter(Intent intent, ParsedComponent component,
- WatchedArrayList<String> protectedBroadcasts) {
+ Set<String> protectedBroadcasts) {
List<ParsedIntentInfo> intents = component.getIntents();
for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) {
IntentFilter intentFilter = intents.get(i).getIntentFilter();
@@ -734,10 +646,10 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
private static boolean matchesIntentFilter(Intent intent, IntentFilter intentFilter,
- @Nullable WatchedArrayList<String> protectedBroadcasts) {
+ @Nullable Set<String> protectedBroadcasts) {
return intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(),
- intent.getData(), intent.getCategories(), "AppsFilter", true,
- protectedBroadcasts != null ? protectedBroadcasts.untrackedStorage() : null) > 0;
+ intent.getData(), intent.getCategories(), "AppsFilter", true, protectedBroadcasts)
+ > 0;
}
/**
@@ -753,19 +665,20 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
if (recipientUid == visibleUid) {
return false;
}
- final boolean changed;
- synchronized (mLock) {
- changed = retainOnUpdate
- ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid)
- : mImplicitlyQueryable.add(recipientUid, visibleUid);
- if (changed && DEBUG_LOGGING) {
- Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: "
- + recipientUid + " -> " + visibleUid);
- }
+ final boolean changed = retainOnUpdate
+ ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid)
+ : mImplicitlyQueryable.add(recipientUid, visibleUid);
+ if (changed && DEBUG_LOGGING) {
+ Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: "
+ + recipientUid + " -> " + visibleUid);
}
- synchronized (mCacheLock) {
- // update the cache in a one-off manner since we've got all the information we need.
- mShouldFilterCache.put(recipientUid, visibleUid, false);
+
+ if (mSystemReady) {
+ synchronized (mCacheLock) {
+ // update the cache in a one-off manner since we've got all the information we
+ // need.
+ mShouldFilterCache.put(recipientUid, visibleUid, false);
+ }
}
if (changed) {
onChanged();
@@ -779,6 +692,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
updateEntireShouldFilterCacheAsync();
onChanged();
+ mSystemReady = true;
}
/**
@@ -799,8 +713,8 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
mStateProvider.runWithState((settings, users) -> {
ArraySet<String> additionalChangedPackages =
addPackageInternal(newPkgSetting, settings);
- synchronized (mCacheLock) {
- updateShouldFilterCacheForPackage(mShouldFilterCache, null, newPkgSetting,
+ if (mSystemReady) {
+ updateShouldFilterCacheForPackage(null, newPkgSetting,
settings, users, USER_ALL, settings.size());
if (additionalChangedPackages != null) {
for (int index = 0; index < additionalChangedPackages.size(); index++) {
@@ -814,12 +728,12 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
continue;
}
- updateShouldFilterCacheForPackage(mShouldFilterCache, null,
+ updateShouldFilterCacheForPackage(null,
changedPkgSetting, settings, users, USER_ALL,
settings.size());
}
}
- }
+ } // else, rebuild entire cache when system is ready
});
} finally {
onChanged();
@@ -841,11 +755,9 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
mSystemSigningDetails = newPkgSetting.getSigningDetails();
// and since we add overlays before we add the framework, let's revisit already added
// packages for signature matches
- synchronized (mLock) {
- for (PackageStateInternal setting : existingSettings.values()) {
- if (isSystemSigned(mSystemSigningDetails, setting)) {
- mForceQueryable.add(setting.getAppId());
- }
+ for (PackageStateInternal setting : existingSettings.values()) {
+ if (isSystemSigned(mSystemSigningDetails, setting)) {
+ mForceQueryable.add(setting.getAppId());
}
}
}
@@ -855,75 +767,68 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
return null;
}
- synchronized (mLock) {
- if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) {
- mQueriesViaComponentRequireRecompute = true;
- }
+ if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) {
+ mQueriesViaComponentRequireRecompute = true;
+ }
- final boolean newIsForceQueryable =
- mForceQueryable.contains(newPkgSetting.getAppId())
- /* shared user that is already force queryable */
- || newPkgSetting.isForceQueryableOverride() /* adb override */
- || (newPkgSetting.isSystem() && (mSystemAppsQueryable
- || newPkg.isForceQueryable()
- || ArrayUtils.contains(mForceQueryableByDevicePackageNames,
- newPkg.getPackageName())));
- if (newIsForceQueryable
- || (mSystemSigningDetails != null
- && isSystemSigned(mSystemSigningDetails, newPkgSetting))) {
- mForceQueryable.add(newPkgSetting.getAppId());
- }
+ final boolean newIsForceQueryable =
+ mForceQueryable.contains(newPkgSetting.getAppId())
+ /* shared user that is already force queryable */
+ || newPkgSetting.isForceQueryableOverride() /* adb override */
+ || (newPkgSetting.isSystem() && (mSystemAppsQueryable
+ || newPkg.isForceQueryable()
+ || ArrayUtils.contains(mForceQueryableByDevicePackageNames,
+ newPkg.getPackageName())));
+ if (newIsForceQueryable
+ || (mSystemSigningDetails != null
+ && isSystemSigned(mSystemSigningDetails, newPkgSetting))) {
+ mForceQueryable.add(newPkgSetting.getAppId());
+ }
- for (int i = existingSettings.size() - 1; i >= 0; i--) {
- final PackageStateInternal existingSetting = existingSettings.valueAt(i);
- if (existingSetting.getAppId() == newPkgSetting.getAppId()
- || existingSetting.getPkg()
- == null) {
- continue;
+ for (int i = existingSettings.size() - 1; i >= 0; i--) {
+ final PackageStateInternal existingSetting = existingSettings.valueAt(i);
+ if (existingSetting.getAppId() == newPkgSetting.getAppId() || existingSetting.getPkg()
+ == null) {
+ continue;
+ }
+ final AndroidPackage existingPkg = existingSetting.getPkg();
+ // let's evaluate the ability of already added packages to see this new package
+ if (!newIsForceQueryable) {
+ if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(existingPkg,
+ newPkg, mProtectedBroadcasts)) {
+ mQueriesViaComponent.add(existingSetting.getAppId(), newPkgSetting.getAppId());
}
- final AndroidPackage existingPkg = existingSetting.getPkg();
- // let's evaluate the ability of already added packages to see this new package
- if (!newIsForceQueryable) {
- if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(existingPkg,
- newPkg, mProtectedBroadcasts)) {
- mQueriesViaComponent.add(existingSetting.getAppId(),
- newPkgSetting.getAppId());
- }
- if (canQueryViaPackage(existingPkg, newPkg)
- || canQueryAsInstaller(existingSetting, newPkg)) {
- mQueriesViaPackage.add(existingSetting.getAppId(),
- newPkgSetting.getAppId());
- }
- if (canQueryViaUsesLibrary(existingPkg, newPkg)) {
- mQueryableViaUsesLibrary.add(existingSetting.getAppId(),
- newPkgSetting.getAppId());
- }
+ if (canQueryViaPackage(existingPkg, newPkg)
+ || canQueryAsInstaller(existingSetting, newPkg)) {
+ mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId());
}
- // now we'll evaluate our new package's ability to see existing packages
- if (!mForceQueryable.contains(existingSetting.getAppId())) {
- if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(newPkg,
- existingPkg, mProtectedBroadcasts)) {
- mQueriesViaComponent.add(newPkgSetting.getAppId(),
- existingSetting.getAppId());
- }
- if (canQueryViaPackage(newPkg, existingPkg)
- || canQueryAsInstaller(newPkgSetting, existingPkg)) {
- mQueriesViaPackage.add(newPkgSetting.getAppId(),
- existingSetting.getAppId());
- }
- if (canQueryViaUsesLibrary(newPkg, existingPkg)) {
- mQueryableViaUsesLibrary.add(newPkgSetting.getAppId(),
- existingSetting.getAppId());
- }
+ if (canQueryViaUsesLibrary(existingPkg, newPkg)) {
+ mQueryableViaUsesLibrary.add(existingSetting.getAppId(),
+ newPkgSetting.getAppId());
}
- // if either package instruments the other, mark both as visible to one another
- if (newPkgSetting.getPkg() != null && existingSetting.getPkg() != null
- && (pkgInstruments(newPkgSetting.getPkg(), existingSetting.getPkg())
- || pkgInstruments(existingSetting.getPkg(), newPkgSetting.getPkg()))) {
+ }
+ // now we'll evaluate our new package's ability to see existing packages
+ if (!mForceQueryable.contains(existingSetting.getAppId())) {
+ if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(newPkg,
+ existingPkg, mProtectedBroadcasts)) {
+ mQueriesViaComponent.add(newPkgSetting.getAppId(), existingSetting.getAppId());
+ }
+ if (canQueryViaPackage(newPkg, existingPkg)
+ || canQueryAsInstaller(newPkgSetting, existingPkg)) {
mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId());
- mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId());
+ }
+ if (canQueryViaUsesLibrary(newPkg, existingPkg)) {
+ mQueryableViaUsesLibrary.add(newPkgSetting.getAppId(),
+ existingSetting.getAppId());
}
}
+ // if either package instruments the other, mark both as visible to one another
+ if (newPkgSetting.getPkg() != null && existingSetting.getPkg() != null
+ && (pkgInstruments(newPkgSetting.getPkg(), existingSetting.getPkg())
+ || pkgInstruments(existingSetting.getPkg(), newPkgSetting.getPkg()))) {
+ mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId());
+ mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId());
+ }
}
int existingSize = existingSettings.size();
@@ -944,6 +849,9 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
private void removeAppIdFromVisibilityCache(int appId) {
+ if (!mSystemReady) {
+ return;
+ }
synchronized (mCacheLock) {
for (int i = 0; i < mShouldFilterCache.size(); i++) {
if (UserHandle.getAppId(mShouldFilterCache.keyAt(i)) == appId) {
@@ -976,32 +884,23 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
+ "updating the whole cache");
userId = USER_ALL;
}
- WatchedSparseBooleanMatrix cache =
- updateEntireShouldFilterCacheInner(settings, users, userId);
- synchronized (mCacheLock) {
- mShouldFilterCache.copyFrom(cache);
- }
+ updateEntireShouldFilterCacheInner(settings, users, userId);
});
}
- @NonNull
- private WatchedSparseBooleanMatrix updateEntireShouldFilterCacheInner(
+ private void updateEntireShouldFilterCacheInner(
ArrayMap<String, ? extends PackageStateInternal> settings, UserInfo[] users,
int subjectUserId) {
- final WatchedSparseBooleanMatrix cache;
- if (subjectUserId == USER_ALL) {
- cache = new WatchedSparseBooleanMatrix(users.length * settings.size());
- } else {
- synchronized (mCacheLock) {
- cache = mShouldFilterCache.snapshot();
+ synchronized (mCacheLock) {
+ if (subjectUserId == USER_ALL) {
+ mShouldFilterCache.clear();
}
- cache.setCapacity(users.length * settings.size());
+ mShouldFilterCache.setCapacity(users.length * settings.size());
}
for (int i = settings.size() - 1; i >= 0; i--) {
- updateShouldFilterCacheForPackage(cache,
+ updateShouldFilterCacheForPackage(
null /*skipPackage*/, settings.valueAt(i), settings, users, subjectUserId, i);
}
- return cache;
}
private void updateEntireShouldFilterCacheAsync() {
@@ -1020,8 +919,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
packagesCache.put(settings.keyAt(i), pkg);
}
});
- WatchedSparseBooleanMatrix cache = updateEntireShouldFilterCacheInner(
- settingsCopy, usersRef[0], USER_ALL);
+
boolean[] changed = new boolean[1];
// We have a cache, let's make sure the world hasn't changed out from under us.
mStateProvider.runWithState((settings, users) -> {
@@ -1044,34 +942,39 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
Slog.i(TAG, "Rebuilding cache with lock due to package change.");
}
} else {
- synchronized (mCacheLock) {
- mShouldFilterCache.copyFrom(cache);
- }
+ updateEntireShouldFilterCacheInner(settingsCopy, usersRef[0], USER_ALL);
}
});
}
public void onUserCreated(int newUserId) {
+ if (!mSystemReady) {
+ return;
+ }
updateEntireShouldFilterCache(newUserId);
onChanged();
}
public void onUserDeleted(@UserIdInt int userId) {
+ if (!mSystemReady) {
+ return;
+ }
removeShouldFilterCacheForUser(userId);
onChanged();
}
private void updateShouldFilterCacheForPackage(String packageName) {
mStateProvider.runWithState((settings, users) -> {
- synchronized (mCacheLock) {
- updateShouldFilterCacheForPackage(mShouldFilterCache, null /* skipPackage */,
- settings.get(packageName), settings, users, USER_ALL,
- settings.size() /*maxIndex*/);
+ if (!mSystemReady) {
+ return;
}
+ updateShouldFilterCacheForPackage(null /* skipPackage */,
+ settings.get(packageName), settings, users, USER_ALL,
+ settings.size() /*maxIndex*/);
});
}
- private void updateShouldFilterCacheForPackage(@NonNull WatchedSparseBooleanMatrix cache,
+ private void updateShouldFilterCacheForPackage(
@Nullable String skipPackageName, PackageStateInternal subjectSetting, ArrayMap<String,
? extends PackageStateInternal> allSettings, UserInfo[] allUsers, int subjectUserId,
int maxIndex) {
@@ -1087,29 +990,31 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
if (subjectUserId == USER_ALL) {
for (int su = 0; su < allUsers.length; su++) {
- updateShouldFilterCacheForUser(cache, subjectSetting, allUsers, otherSetting,
+ updateShouldFilterCacheForUser(subjectSetting, allUsers, otherSetting,
allUsers[su].id);
}
} else {
- updateShouldFilterCacheForUser(cache, subjectSetting, allUsers, otherSetting,
+ updateShouldFilterCacheForUser(subjectSetting, allUsers, otherSetting,
subjectUserId);
}
}
}
- private void updateShouldFilterCacheForUser(@NonNull WatchedSparseBooleanMatrix cache,
+ private void updateShouldFilterCacheForUser(
PackageStateInternal subjectSetting, UserInfo[] allUsers,
PackageStateInternal otherSetting, int subjectUserId) {
for (int ou = 0; ou < allUsers.length; ou++) {
int otherUser = allUsers[ou].id;
int subjectUid = UserHandle.getUid(subjectUserId, subjectSetting.getAppId());
int otherUid = UserHandle.getUid(otherUser, otherSetting.getAppId());
- cache.put(subjectUid, otherUid,
- shouldFilterApplicationInternal(
- subjectUid, subjectSetting, otherSetting, otherUser));
- cache.put(otherUid, subjectUid,
- shouldFilterApplicationInternal(
- otherUid, otherSetting, subjectSetting, subjectUserId));
+ final boolean shouldFilterSubjectToOther = shouldFilterApplicationInternal(
+ subjectUid, subjectSetting, otherSetting, otherUser);
+ final boolean shouldFilterOtherToSubject = shouldFilterApplicationInternal(
+ otherUid, otherSetting, subjectSetting, subjectUserId);
+ synchronized (mCacheLock) {
+ mShouldFilterCache.put(subjectUid, otherUid, shouldFilterSubjectToOther);
+ mShouldFilterCache.put(otherUid, subjectUid, shouldFilterOtherToSubject);
+ }
}
}
@@ -1143,30 +1048,28 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
&& pkgSetting.getSigningDetails().signaturesMatchExactly(sysSigningDetails);
}
- private void collectProtectedBroadcasts(
+ private ArraySet<String> collectProtectedBroadcasts(
ArrayMap<String, ? extends PackageStateInternal> existingSettings,
@Nullable String excludePackage) {
- synchronized (mLock) {
- mProtectedBroadcasts.clear();
- for (int i = existingSettings.size() - 1; i >= 0; i--) {
- PackageStateInternal setting = existingSettings.valueAt(i);
- if (setting.getPkg() == null || setting.getPkg().getPackageName().equals(
- excludePackage)) {
- continue;
- }
- final List<String> protectedBroadcasts = setting.getPkg().getProtectedBroadcasts();
- if (!protectedBroadcasts.isEmpty()) {
- mProtectedBroadcasts.addAll(protectedBroadcasts);
- }
+ ArraySet<String> ret = new ArraySet<>();
+ for (int i = existingSettings.size() - 1; i >= 0; i--) {
+ PackageStateInternal setting = existingSettings.valueAt(i);
+ if (setting.getPkg() == null || setting.getPkg().getPackageName().equals(
+ excludePackage)) {
+ continue;
+ }
+ final List<String> protectedBroadcasts = setting.getPkg().getProtectedBroadcasts();
+ if (!protectedBroadcasts.isEmpty()) {
+ ret.addAll(protectedBroadcasts);
}
}
+ return ret;
}
/**
* This method recomputes all component / intent-based visibility and is intended to match the
* relevant logic of {@link #addPackageInternal(PackageStateInternal, ArrayMap)}
*/
- @GuardedBy("mLock")
private void recomputeComponentVisibility(
ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
mQueriesViaComponent.clear();
@@ -1194,16 +1097,24 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
/**
- * See {@link AppsFilterSnapshot#getVisibilityAllowList(PackageStateInternal, int[], ArrayMap)}
+ * Fetches all app Ids that a given setting is currently visible to, per provided user. This
+ * only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see
+ * all applications.
+ *
+ * If the setting is visible to all UIDs, null is returned. If an app is not visible to any
+ * applications, the int array will be empty.
+ *
+ * @param users the set of users that should be evaluated for this calculation
+ * @param existingSettings the set of all package settings that currently exist on device
+ * @return a SparseArray mapping userIds to a sorted int array of appIds that may view the
+ * provided setting or null if the app is visible to all and no allow list should be
+ * applied.
*/
- @Override
@Nullable
public SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
- synchronized (mLock) {
- if (mForceQueryable.contains(setting.getAppId())) {
- return null;
- }
+ if (mForceQueryable.contains(setting.getAppId())) {
+ return null;
}
// let's reserve max memory to limit the number of allocations
SparseArray<int[]> result = new SparseArray<>(users.length);
@@ -1253,7 +1164,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
* Equivalent to calling {@link #addPackage(PackageStateInternal, boolean)} with
* {@code isReplace} equal to {@code false}.
*
- * @see AppsFilterImpl#addPackage(PackageStateInternal, boolean)
+ * @see AppsFilter#addPackage(PackageStateInternal, boolean)
*/
public void addPackage(PackageStateInternal newPkgSetting) {
addPackage(newPkgSetting, false /* isReplace */);
@@ -1267,63 +1178,57 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
*/
public void removePackage(PackageStateInternal setting, boolean isReplace) {
mStateProvider.runWithState((settings, users) -> {
- final ArraySet<String> additionalChangedPackages;
- synchronized (mLock) {
- final int userCount = users.length;
- for (int u = 0; u < userCount; u++) {
- final int userId = users[u].id;
- final int removingUid = UserHandle.getUid(userId, setting.getAppId());
- mImplicitlyQueryable.remove(removingUid);
- for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
- mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid);
- }
-
- if (isReplace) {
- continue;
- }
-
- mRetainedImplicitlyQueryable.remove(removingUid);
- for (int i = mRetainedImplicitlyQueryable.size() - 1; i >= 0; i--) {
- mRetainedImplicitlyQueryable.remove(
- mRetainedImplicitlyQueryable.keyAt(i), removingUid);
- }
+ final int userCount = users.length;
+ for (int u = 0; u < userCount; u++) {
+ final int userId = users[u].id;
+ final int removingUid = UserHandle.getUid(userId, setting.getAppId());
+ mImplicitlyQueryable.remove(removingUid);
+ for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
+ mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid);
}
- if (!mQueriesViaComponentRequireRecompute) {
- mQueriesViaComponent.remove(setting.getAppId());
- for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
- mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i),
- setting.getAppId());
- }
+ if (isReplace) {
+ continue;
}
- mQueriesViaPackage.remove(setting.getAppId());
- for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
- mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.getAppId());
+
+ mRetainedImplicitlyQueryable.remove(removingUid);
+ for (int i = mRetainedImplicitlyQueryable.size() - 1; i >= 0; i--) {
+ mRetainedImplicitlyQueryable.remove(
+ mRetainedImplicitlyQueryable.keyAt(i), removingUid);
}
- mQueryableViaUsesLibrary.remove(setting.getAppId());
- for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) {
- mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i),
- setting.getAppId());
+ }
+
+ if (!mQueriesViaComponentRequireRecompute) {
+ mQueriesViaComponent.remove(setting.getAppId());
+ for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
+ mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.getAppId());
}
+ }
+ mQueriesViaPackage.remove(setting.getAppId());
+ for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
+ mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.getAppId());
+ }
+ mQueryableViaUsesLibrary.remove(setting.getAppId());
+ for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) {
+ mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i),
+ setting.getAppId());
+ }
- mForceQueryable.remove(setting.getAppId());
+ mForceQueryable.remove(setting.getAppId());
- if (setting.getPkg() != null
- && !setting.getPkg().getProtectedBroadcasts().isEmpty()) {
- final String removingPackageName = setting.getPkg().getPackageName();
- final ArrayList<String> protectedBroadcasts = new ArrayList<>();
- protectedBroadcasts.addAll(mProtectedBroadcasts.untrackedStorage());
- collectProtectedBroadcasts(settings, removingPackageName);
- if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) {
- mQueriesViaComponentRequireRecompute = true;
- }
+ if (setting.getPkg() != null && !setting.getPkg().getProtectedBroadcasts().isEmpty()) {
+ final String removingPackageName = setting.getPkg().getPackageName();
+ final Set<String> protectedBroadcasts = mProtectedBroadcasts;
+ mProtectedBroadcasts = collectProtectedBroadcasts(settings, removingPackageName);
+ if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) {
+ mQueriesViaComponentRequireRecompute = true;
}
+ }
- additionalChangedPackages =
- mOverlayReferenceMapper.removePkg(setting.getPackageName());
+ ArraySet<String> additionalChangedPackages =
+ mOverlayReferenceMapper.removePkg(setting.getPackageName());
- mFeatureConfig.updatePackageState(setting, true /*removed*/);
- }
+ mFeatureConfig.updatePackageState(setting, true /*removed*/);
// After removing all traces of the package, if it's part of a shared user, re-add other
// shared user members to re-establish visibility between them and other packages.
@@ -1342,7 +1247,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
removeAppIdFromVisibilityCache(setting.getAppId());
- if (setting.hasSharedUser()) {
+ if (mSystemReady && setting.hasSharedUser()) {
final ArraySet<PackageStateInternal> sharedUserPackages =
mPmInternal.getSharedUserPackages(setting.getSharedUserAppId());
for (int i = sharedUserPackages.size() - 1; i >= 0; i--) {
@@ -1351,39 +1256,44 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
if (siblingSetting == setting) {
continue;
}
- synchronized (mCacheLock) {
- updateShouldFilterCacheForPackage(mShouldFilterCache,
- setting.getPackageName(), siblingSetting, settings, users,
- USER_ALL, settings.size());
- }
+ updateShouldFilterCacheForPackage(
+ setting.getPackageName(), siblingSetting, settings, users,
+ USER_ALL, settings.size());
}
}
- if (additionalChangedPackages != null) {
- for (int index = 0; index < additionalChangedPackages.size(); index++) {
- String changedPackage = additionalChangedPackages.valueAt(index);
- PackageStateInternal changedPkgSetting = settings.get(changedPackage);
- if (changedPkgSetting == null) {
- // It's possible for the overlay mapper to know that an actor
- // package changed via an explicit reference, even if the actor
- // isn't installed, so skip if that's the case.
- continue;
- }
- synchronized (mCacheLock) {
- updateShouldFilterCacheForPackage(mShouldFilterCache, null,
+ if (mSystemReady) {
+ if (additionalChangedPackages != null) {
+ for (int index = 0; index < additionalChangedPackages.size(); index++) {
+ String changedPackage = additionalChangedPackages.valueAt(index);
+ PackageStateInternal changedPkgSetting = settings.get(changedPackage);
+ if (changedPkgSetting == null) {
+ // It's possible for the overlay mapper to know that an actor
+ // package changed via an explicit reference, even if the actor
+ // isn't installed, so skip if that's the case.
+ continue;
+ }
+
+ updateShouldFilterCacheForPackage(null,
changedPkgSetting, settings, users, USER_ALL, settings.size());
}
}
}
+
onChanged();
});
}
/**
- * See {@link AppsFilterSnapshot#shouldFilterApplication(int, Object, PackageStateInternal,
- * int)}
+ * Returns true if the calling package should not be able to see the target package, false if no
+ * filtering should be done.
+ *
+ * @param callingUid the uid of the caller attempting to access a package
+ * @param callingSetting the setting attempting to access a package or null if it could not be
+ * found
+ * @param targetPkgSetting the package being accessed
+ * @param userId the user in which this access is being attempted
*/
- @Override
public boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting,
PackageStateInternal targetPkgSetting, int userId) {
if (DEBUG_TRACING) {
@@ -1396,12 +1306,9 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
|| callingAppId == targetPkgSetting.getAppId()) {
return false;
}
- final boolean shouldUseCache;
- synchronized (mCacheLock) {
- shouldUseCache = mShouldFilterCache.size() != 0;
- }
- if (shouldUseCache) { // use cache
- if (!shouldFilterApplicationUsingCache(callingUid, targetPkgSetting.getAppId(),
+ if (mSystemReady) { // use cache
+ if (!shouldFilterApplicationUsingCache(callingUid,
+ targetPkgSetting.getAppId(),
userId)) {
return false;
}
@@ -1411,7 +1318,6 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
return false;
}
}
-
if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(callingAppId)) {
log(callingSetting, targetPkgSetting, "BLOCKED");
}
@@ -1560,147 +1466,142 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
return false;
}
- synchronized (mLock) {
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mForceQueryable");
- }
- if (mForceQueryable.contains(targetAppId)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "force queryable");
- }
- return false;
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mForceQueryable");
}
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaPackage");
- }
- if (mQueriesViaPackage.contains(callingAppId, targetAppId)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queries package");
- }
- return false;
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ if (mForceQueryable.contains(targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "force queryable");
}
+ return false;
}
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
- }
- if (mQueriesViaComponentRequireRecompute) {
- mStateProvider.runWithState((settings, users) -> {
- synchronized (mLock) {
- recomputeComponentVisibility(settings);
- }
- });
- }
- if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queries component");
- }
- return false;
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaPackage");
+ }
+ if (mQueriesViaPackage.contains(callingAppId, targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "queries package");
}
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
+ }
+ if (mQueriesViaComponentRequireRecompute) {
+ mStateProvider.runWithState((settings, users) -> {
+ recomputeComponentVisibility(settings);
+ });
+ }
+ if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "queries component");
}
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
+ }
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
- }
- final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
- if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "implicitly queryable for user");
- }
- return false;
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
+ }
+ final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
+ if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "implicitly queryable for user");
}
+ return false;
}
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable");
- }
- final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
- if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting,
- "retained implicitly queryable for user");
- }
- return false;
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable");
+ }
+ final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
+ if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting,
+ "retained implicitly queryable for user");
}
+ return false;
}
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mOverlayReferenceMapper");
- }
- final String targetName = targetPkg.getPackageName();
- if (callingSharedPkgSettings != null) {
- int size = callingSharedPkgSettings.size();
- for (int index = 0; index < size; index++) {
- PackageStateInternal pkgSetting = callingSharedPkgSettings.valueAt(
- index);
- if (mOverlayReferenceMapper.isValidActor(targetName,
- pkgSetting.getPackageName())) {
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting,
- "matches shared user of package that acts on target of "
- + "overlay");
- }
- return false;
- }
- }
- } else {
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mOverlayReferenceMapper");
+ }
+ final String targetName = targetPkg.getPackageName();
+ if (callingSharedPkgSettings != null) {
+ int size = callingSharedPkgSettings.size();
+ for (int index = 0; index < size; index++) {
+ PackageStateInternal pkgSetting = callingSharedPkgSettings.valueAt(index);
if (mOverlayReferenceMapper.isValidActor(targetName,
- callingPkgSetting.getPackageName())) {
+ pkgSetting.getPackageName())) {
if (DEBUG_LOGGING) {
log(callingPkgSetting, targetPkgSetting,
- "acts on target of overlay");
+ "matches shared user of package that acts on target of "
+ + "overlay");
}
return false;
}
}
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary");
- }
- if (mQueryableViaUsesLibrary.contains(callingAppId, targetAppId)) {
+ } else {
+ if (mOverlayReferenceMapper.isValidActor(targetName,
+ callingPkgSetting.getPackageName())) {
if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queryable for library users");
+ log(callingPkgSetting, targetPkgSetting, "acts on target of overlay");
}
return false;
}
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary");
+ }
+ if (mQueryableViaUsesLibrary.contains(callingAppId, targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "queryable for library users");
}
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
+
return true;
} finally {
if (DEBUG_TRACING) {
@@ -1709,11 +1610,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
}
- /**
- * See {@link AppsFilterSnapshot#canQueryPackage(AndroidPackage, String)}
- */
- @Override
- public boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget) {
+ boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget) {
int appId = UserHandle.getAppId(querying.getUid());
if (appId < Process.FIRST_APPLICATION_UID) {
return true;
@@ -1768,11 +1665,6 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
+ targetPkgSetting + " " + description);
}
- /**
- * See {@link AppsFilterSnapshot#dumpQueries(PrintWriter, Integer, DumpState, int[],
- * QuadFunction)}
- */
- @Override
public void dumpQueries(
PrintWriter pw, @Nullable Integer filteringAppId, DumpState dumpState, int[] users,
QuadFunction<Integer, Integer, Integer, Boolean, String[]> getPackagesForUid) {
@@ -1807,30 +1699,27 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
}
}
pw.println(" system apps queryable: " + mSystemAppsQueryable);
- synchronized (mLock) {
- dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(),
- "forceQueryable", " ", expandPackages);
- pw.println(" queries via package name:");
- dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages);
- pw.println(" queries via component:");
- dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages);
- pw.println(" queryable via interaction:");
- for (int user : users) {
- pw.append(" User ").append(Integer.toString(user)).println(":");
- dumpQueriesMap(pw,
- filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
- mImplicitlyQueryable, " ", expandPackages);
- dumpQueriesMap(pw,
- filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
- mRetainedImplicitlyQueryable, " ", expandPackages);
- }
- pw.println(" queryable via uses-library:");
- dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", expandPackages);
+ dumpPackageSet(pw, filteringAppId, mForceQueryable, "forceQueryable", " ", expandPackages);
+ pw.println(" queries via package name:");
+ dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages);
+ pw.println(" queries via component:");
+ dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages);
+ pw.println(" queryable via interaction:");
+ for (int user : users) {
+ pw.append(" User ").append(Integer.toString(user)).println(":");
+ dumpQueriesMap(pw,
+ filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
+ mImplicitlyQueryable, " ", expandPackages);
+ dumpQueriesMap(pw,
+ filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
+ mRetainedImplicitlyQueryable, " ", expandPackages);
}
+ pw.println(" queryable via uses-library:");
+ dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", expandPackages);
}
private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
- WatchedSparseSetArray<Integer> queriesMap, String spacing,
+ SparseSetArray<Integer> queriesMap, String spacing,
@Nullable ToString<Integer> toString) {
for (int i = 0; i < queriesMap.size(); i++) {
Integer callingId = queriesMap.keyAt(i);
@@ -1855,10 +1744,11 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
private interface ToString<T> {
String toString(T input);
+
}
private static <T> void dumpPackageSet(PrintWriter pw, @Nullable T filteringId,
- ArraySet<T> targetPkgSet, String subTitle, String spacing,
+ Set<T> targetPkgSet, String subTitle, String spacing,
@Nullable ToString<T> toString) {
if (targetPkgSet != null && targetPkgSet.size() > 0
&& (filteringId == null || targetPkgSet.contains(filteringId))) {
diff --git a/services/core/java/com/android/server/pm/AppsFilterSnapshot.java b/services/core/java/com/android/server/pm/AppsFilterSnapshot.java
deleted file mode 100644
index cb8c649ded00..000000000000
--- a/services/core/java/com/android/server/pm/AppsFilterSnapshot.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Process;
-import android.util.ArrayMap;
-import android.util.SparseArray;
-
-import com.android.internal.util.function.QuadFunction;
-import com.android.server.pm.parsing.pkg.AndroidPackage;
-import com.android.server.pm.pkg.PackageStateInternal;
-
-import java.io.PrintWriter;
-
-/**
- * Read-only interface used by computer and snapshots to query the visibility of packages
- */
-public interface AppsFilterSnapshot {
- /**
- * Fetches all app Ids that a given setting is currently visible to, per provided user. This
- * only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see
- * all applications.
- *
- * If the setting is visible to all UIDs, null is returned. If an app is not visible to any
- * applications, the int array will be empty.
- *
- * @param users the set of users that should be evaluated for this calculation
- * @param existingSettings the set of all package settings that currently exist on device
- * @return a SparseArray mapping userIds to a sorted int array of appIds that may view the
- * provided setting or null if the app is visible to all and no allow list should be
- * applied.
- */
- SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
- ArrayMap<String, ? extends PackageStateInternal> existingSettings);
-
- /**
- * Returns true if the calling package should not be able to see the target package, false if no
- * filtering should be done.
- *
- * @param callingUid the uid of the caller attempting to access a package
- * @param callingSetting the setting attempting to access a package or null if it could not be
- * found
- * @param targetPkgSetting the package being accessed
- * @param userId the user in which this access is being attempted
- */
- boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting,
- PackageStateInternal targetPkgSetting, int userId);
-
- /**
- * Returns whether the querying package is allowed to see the target package.
- *
- * @param querying the querying package
- * @param potentialTarget the package name of the target package
- */
- boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget);
-
- /**
- * Dump the packages that are queryable by the querying package.
- *
- * @param pw the output print writer
- * @param filteringAppId the querying package's app ID
- * @param dumpState the state of the dumping
- * @param users the users for which the packages are installed
- * @param getPackagesForUid the function that produces the package names for given uids
- */
- void dumpQueries(PrintWriter pw, @Nullable Integer filteringAppId, DumpState dumpState,
- int[] users,
- QuadFunction<Integer, Integer, Integer, Boolean, String[]> getPackagesForUid);
-
-}
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index bf1196d6b969..ed71f1eb5313 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -20,7 +20,6 @@ import static android.os.PowerExemptionManager.REASON_LOCKED_BOOT_COMPLETED;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
-import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY;
import static com.android.server.pm.PackageManagerService.PACKAGE_SCHEME;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.TAG;
@@ -86,11 +85,14 @@ public final class BroadcastHelper {
} else {
resolvedUserIds = userIds;
}
- doSendBroadcast(action, pkg, extras, flags, targetPkg, finishedReceiver,
- resolvedUserIds, false, broadcastAllowList, bOptions);
- if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
+
+ if (ArrayUtils.isEmpty(instantUserIds)) {
+ doSendBroadcast(action, pkg, extras, flags, targetPkg, finishedReceiver,
+ resolvedUserIds, false /* isInstantApp */, broadcastAllowList, bOptions);
+ } else {
+ // send restricted broadcasts for instant apps
doSendBroadcast(action, pkg, extras, flags, targetPkg, finishedReceiver,
- instantUserIds, true, null, bOptions);
+ instantUserIds, true /* isInstantApp */, null, bOptions);
}
} catch (RemoteException ex) {
}
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 3e204b6e6e4c..c259797942a7 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -599,4 +599,7 @@ public interface Computer extends PackageDataSnapshot {
void dumpPackagesProto(@NonNull ProtoOutputStream proto);
void dumpSharedLibrariesProto(@NonNull ProtoOutputStream protoOutputStream);
+
+ @NonNull
+ List<? extends PackageStateInternal> getVolumePackages(@NonNull String volumeUuid);
}
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 8ac3dca1991d..df7c3ec6f260 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -354,6 +354,11 @@ public class ComputerEngine implements Computer {
public void dumpSharedUsersProto(ProtoOutputStream proto) {
mSettings.dumpSharedUsersProto(proto);
}
+
+ public List<? extends PackageStateInternal> getVolumePackages(
+ @NonNull String volumeUuid) {
+ return mSettings.getVolumePackagesLPr(volumeUuid);
+ }
}
private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
@@ -380,7 +385,7 @@ public class ComputerEngine implements Computer {
private final ResolveInfo mInstantAppInstallerInfo;
private final InstantAppRegistry mInstantAppRegistry;
private final ApplicationInfo mLocalAndroidApplication;
- private final AppsFilterSnapshot mAppsFilter;
+ private final AppsFilter mAppsFilter;
private final WatchedArrayMap<String, Integer> mFrozenPackages;
// Immutable service attribute
@@ -5812,4 +5817,10 @@ public class ComputerEngine implements Computer {
public void dumpSharedLibrariesProto(@NonNull ProtoOutputStream proto) {
mSharedLibraries.dumpProto(proto);
}
+
+ @NonNull
+ @Override
+ public List<? extends PackageStateInternal> getVolumePackages(@NonNull String volumeUuid) {
+ return mSettings.getVolumePackages(volumeUuid);
+ }
}
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index bb2ba5cc498d..249099d122a1 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -358,9 +358,7 @@ final class DexOptHelper {
}
final long callingId = Binder.clearCallingIdentity();
try {
- synchronized (mPm.mInstallLock) {
- return performDexOptInternalWithDependenciesLI(p, pkgSetting, options);
- }
+ return performDexOptInternalWithDependenciesLI(p, pkgSetting, options);
} finally {
Binder.restoreCallingIdentity(callingId);
}
@@ -429,20 +427,18 @@ final class DexOptHelper {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
- synchronized (mPm.mInstallLock) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
- // Whoever is calling forceDexOpt wants a compiled package.
- // Don't use profiles since that may cause compilation to be skipped.
- final int res = performDexOptInternalWithDependenciesLI(pkg, packageState,
- new DexoptOptions(packageName,
- getDefaultCompilerFilter(),
- DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
+ // Whoever is calling forceDexOpt wants a compiled package.
+ // Don't use profiles since that may cause compilation to be skipped.
+ final int res = performDexOptInternalWithDependenciesLI(pkg, packageState,
+ new DexoptOptions(packageName,
+ getDefaultCompilerFilter(),
+ DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
- throw new IllegalStateException("Failed to dexopt: " + res);
- }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
+ throw new IllegalStateException("Failed to dexopt: " + res);
}
}
diff --git a/services/core/java/com/android/server/pm/InitAppsHelper.java b/services/core/java/com/android/server/pm/InitAppsHelper.java
index 15f26e7a6d6c..154f32a2e436 100644
--- a/services/core/java/com/android/server/pm/InitAppsHelper.java
+++ b/services/core/java/com/android/server/pm/InitAppsHelper.java
@@ -30,7 +30,7 @@ import static com.android.server.pm.PackageManagerService.SCAN_NO_DEX;
import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN;
import static com.android.server.pm.PackageManagerService.SYSTEM_PARTITIONS;
import static com.android.server.pm.PackageManagerService.TAG;
-import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_CHECK_MAX_SDK_VERSION;
+import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_APK_IN_APEX;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -359,7 +359,7 @@ final class InitAppsHelper {
try {
if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
// when scanning apk in apexes, we want to check the maxSdkVersion
- parseFlags |= PARSE_CHECK_MAX_SDK_VERSION;
+ parseFlags |= PARSE_APK_IN_APEX;
}
mInstallPackageHelper.installPackagesFromDir(scanDir, frameworkSplits, parseFlags,
scanFlags, packageParser, executorService);
diff --git a/services/core/java/com/android/server/pm/IntentResolverInterceptor.java b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
index 603badb276b2..f5eee5ac160d 100644
--- a/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
+++ b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
@@ -23,11 +23,12 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.res.Resources;
import android.provider.DeviceConfig;
+import android.util.Slog;
import com.android.internal.R;
+import com.android.internal.app.ChooserActivity;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.server.LocalServices;
import com.android.server.wm.ActivityInterceptorCallback;
@@ -35,25 +36,28 @@ import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptorInfo
import com.android.server.wm.ActivityTaskManagerInternal;
/**
- * Service to register an {@code ActivityInterceptorCallback} that modifies any {@code Intent}
- * that's being used to launch a user-space {@code ChooserActivity} by setting the destination
- * component to the delegated component when appropriate.
+ * Redirects Activity starts for the system bundled {@link ChooserActivity} to an external
+ * Sharesheet implementation by modifying the target component when appropriate.
+ * <p>
+ * Note: config_chooserActivity (Used also by ActivityTaskSupervisor) is already updated to point
+ * to the new instance. This value is read and used for the new target component.
*/
public final class IntentResolverInterceptor {
private static final String TAG = "IntentResolverIntercept";
-
private final Context mContext;
- private boolean mUseDelegateChooser;
+ private final ComponentName mFrameworkChooserComponent;
+ private final ComponentName mUnbundledChooserComponent;
+ private boolean mUseUnbundledSharesheet;
private final ActivityInterceptorCallback mActivityInterceptorCallback =
new ActivityInterceptorCallback() {
@Nullable
@Override
public ActivityInterceptResult intercept(ActivityInterceptorInfo info) {
- if (mUseDelegateChooser && isChooserActivity(info)) {
- return new ActivityInterceptResult(
- modifyChooserIntent(info.intent),
- info.checkedOptions);
+ if (mUseUnbundledSharesheet && isSystemChooserActivity(info)) {
+ Slog.d(TAG, "Redirecting to UNBUNDLED Sharesheet");
+ info.intent.setComponent(mUnbundledChooserComponent);
+ return new ActivityInterceptResult(info.intent, info.checkedOptions);
}
return null;
}
@@ -61,10 +65,13 @@ public final class IntentResolverInterceptor {
public IntentResolverInterceptor(Context context) {
mContext = context;
+ mFrameworkChooserComponent = new ComponentName(mContext, ChooserActivity.class);
+ mUnbundledChooserComponent = ComponentName.unflattenFromString(
+ Resources.getSystem().getString(R.string.config_chooserActivity));
}
/**
- * Start listening for intents and USE_DELEGATE_CHOOSER property changes.
+ * Start listening for intents and USE_UNBUNDLED_SHARESHEET property changes.
*/
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
public void registerListeners() {
@@ -73,36 +80,25 @@ public final class IntentResolverInterceptor {
mActivityInterceptorCallback);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
- mContext.getMainExecutor(), properties -> updateUseDelegateChooser());
- updateUseDelegateChooser();
+ mContext.getMainExecutor(), properties -> updateUseUnbundledSharesheet());
+ updateUseUnbundledSharesheet();
}
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
- private void updateUseDelegateChooser() {
- mUseDelegateChooser = DeviceConfig.getBoolean(
+ private void updateUseUnbundledSharesheet() {
+ mUseUnbundledSharesheet = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.USE_UNBUNDLED_SHARESHEET,
false);
+ if (mUseUnbundledSharesheet) {
+ Slog.d(TAG, "using UNBUNDLED Sharesheet");
+ } else {
+ Slog.d(TAG, "using FRAMEWORK Sharesheet");
+ }
}
- private Intent modifyChooserIntent(Intent intent) {
- intent.setComponent(getUnbundledChooserComponentName());
- return intent;
- }
-
- private static boolean isChooserActivity(ActivityInterceptorInfo info) {
- ComponentName targetComponent = new ComponentName(info.aInfo.packageName, info.aInfo.name);
-
- return targetComponent.equals(getSystemChooserComponentName())
- || targetComponent.equals(getUnbundledChooserComponentName());
- }
-
- private static ComponentName getSystemChooserComponentName() {
- return new ComponentName("android", "com.android.internal.app.ChooserActivity");
- }
-
- private static ComponentName getUnbundledChooserComponentName() {
- return ComponentName.unflattenFromString(
- Resources.getSystem().getString(R.string.config_chooserActivity));
+ private boolean isSystemChooserActivity(ActivityInterceptorInfo info) {
+ return mFrameworkChooserComponent.getPackageName().equals(info.aInfo.packageName)
+ && mFrameworkChooserComponent.getClassName().equals(info.aInfo.name);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 002d500e4df5..9b5984e09c8b 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -410,7 +410,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
// Their staging dirs will be removed too
PackageInstallerSession root = !session.hasParentSessionId()
? session : mSessions.get(session.getParentSessionId());
- if (!root.isDestroyed()) {
+ if (root == null) {
+ Slog.e(TAG, "freeStageDirs: found an orphaned session: "
+ + session.sessionId + " parent=" + session.getParentSessionId());
+ } else if (!root.isDestroyed()) {
root.abandon();
}
} else {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4f152d6c0819..f6d8d72cc382 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -720,7 +720,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
@Watched
- final AppsFilterImpl mAppsFilter;
+ final AppsFilter mAppsFilter;
final PackageParser2.Callback mPackageParserCallback;
@@ -979,7 +979,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
public final InstantAppRegistry instantAppRegistry;
public final ApplicationInfo androidApplication;
public final String appPredictionServicePackage;
- public final AppsFilterSnapshot appsFilter;
+ public final AppsFilter appsFilter;
public final ComponentResolverApi componentResolver;
public final PackageManagerService service;
public final WatchedArrayMap<String, Integer> frozenPackages;
@@ -1431,8 +1431,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
RuntimePermissionsPersistence.createInstance(),
i.getPermissionManagerServiceInternal(),
domainVerificationService, lock),
- (i, pm) -> AppsFilterImpl.create(i,
- i.getLocalService(PackageManagerInternal.class)),
+ (i, pm) -> AppsFilter.create(i, i.getLocalService(PackageManagerInternal.class)),
(i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
(i, pm) -> SystemConfig.getInstance(),
(i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
@@ -3537,6 +3536,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
"");
}
+ Log.w(TAG, "Missing required system package: " + packageName + (packageInfo != null
+ ? ", but found with extended search." : "."));
return null;
}
} finally {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
index 396994b04514..a02237fa90ce 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
@@ -99,7 +99,7 @@ public class PackageManagerServiceInjector {
private final Singleton<UserManagerService>
mUserManagerProducer;
private final Singleton<Settings> mSettingsProducer;
- private final Singleton<AppsFilterImpl> mAppsFilterProducer;
+ private final Singleton<AppsFilter> mAppsFilterProducer;
private final Singleton<PlatformCompat>
mPlatformCompatProducer;
private final Singleton<SystemConfig> mSystemConfigProducer;
@@ -148,7 +148,7 @@ public class PackageManagerServiceInjector {
Producer<PermissionManagerServiceInternal> permissionManagerServiceProducer,
Producer<UserManagerService> userManagerProducer,
Producer<Settings> settingsProducer,
- Producer<AppsFilterImpl> appsFilterProducer,
+ Producer<AppsFilter> appsFilterProducer,
Producer<PlatformCompat> platformCompatProducer,
Producer<SystemConfig> systemConfigProducer,
Producer<PackageDexOptimizer> packageDexOptimizerProducer,
@@ -282,7 +282,7 @@ public class PackageManagerServiceInjector {
return mSettingsProducer.get(this, mPackageManager);
}
- public AppsFilterImpl getAppsFilter() {
+ public AppsFilter getAppsFilter() {
return mAppsFilterProducer.get(this, mPackageManager);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index e142ed631092..d6ab78bd27ea 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3694,7 +3694,7 @@ class PackageManagerShellCommand extends ShellCommand {
}
List<PermissionInfo> ps = mPermissionManager
.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/);
- final int count = ps.size();
+ final int count = (ps == null ? 0 : ps.size());
boolean first = true;
for (int p = 0 ; p < count ; p++) {
PermissionInfo pi = ps.get(p);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 698dbe945e6f..b53cfc558f6e 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4342,8 +4342,8 @@ public final class Settings implements Watchable, Snappable {
* Return all {@link PackageSetting} that are actively installed on the
* given {@link VolumeInfo#fsUuid}.
*/
- List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
- ArrayList<PackageSetting> res = new ArrayList<>();
+ List<? extends PackageStateInternal> getVolumePackagesLPr(String volumeUuid) {
+ ArrayList<PackageStateInternal> res = new ArrayList<>();
for (int i = 0; i < mPackages.size(); i++) {
final PackageSetting setting = mPackages.valueAt(i);
if (Objects.equals(volumeUuid, setting.getVolumeUuid())) {
diff --git a/services/core/java/com/android/server/pm/SharedUidMigration.java b/services/core/java/com/android/server/pm/SharedUidMigration.java
index e44ef662efff..5fe08dd1de65 100644
--- a/services/core/java/com/android/server/pm/SharedUidMigration.java
+++ b/services/core/java/com/android/server/pm/SharedUidMigration.java
@@ -61,7 +61,7 @@ public final class SharedUidMigration {
public @interface Strategy {}
@Strategy
- private static final int DEFAULT = BEST_EFFORT;
+ private static final int DEFAULT = NEW_INSTALL_ONLY;
/**
* Whether shared UID migration is fully disabled. Disabled means the sharedUserMaxSdkVersion
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index 8c6b19b3361c..666776b4161e 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -109,8 +109,9 @@ public final class StorageEventHelper extends StorageEventListener {
// Remove any apps installed on the forgotten volume
synchronized (mPm.mLock) {
- final List<PackageSetting> packages = mPm.mSettings.getVolumePackagesLPr(fsUuid);
- for (PackageSetting ps : packages) {
+ final List<? extends PackageStateInternal> packages =
+ mPm.mSettings.getVolumePackagesLPr(fsUuid);
+ for (PackageStateInternal ps : packages) {
Slog.d(TAG, "Destroying " + ps.getPackageName()
+ " because volume was forgotten");
mPm.deletePackageVersioned(new VersionedPackage(ps.getPackageName(),
@@ -145,14 +146,14 @@ public final class StorageEventHelper extends StorageEventListener {
final int parseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_EXTERNAL_STORAGE;
final Settings.VersionInfo ver;
- final List<PackageSetting> packages;
+ final List<? extends PackageStateInternal> packages;
final InstallPackageHelper installPackageHelper = new InstallPackageHelper(mPm);
synchronized (mPm.mLock) {
ver = mPm.mSettings.findOrCreateVersion(volumeUuid);
packages = mPm.mSettings.getVolumePackagesLPr(volumeUuid);
}
- for (PackageSetting ps : packages) {
+ for (PackageStateInternal ps : packages) {
freezers.add(mPm.freezePackage(ps.getPackageName(), "loadPrivatePackagesInner"));
synchronized (mPm.mInstallLock) {
final AndroidPackage pkg;
@@ -243,9 +244,9 @@ public final class StorageEventHelper extends StorageEventListener {
final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
synchronized (mPm.mInstallLock) {
synchronized (mPm.mLock) {
- final List<PackageSetting> packages =
+ final List<? extends PackageStateInternal> packages =
mPm.mSettings.getVolumePackagesLPr(volumeUuid);
- for (PackageSetting ps : packages) {
+ for (PackageStateInternal ps : packages) {
if (ps.getPkg() == null) continue;
final AndroidPackage pkg = ps.getPkg();
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 7e4da945709b..4fae6b8e1271 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -45,7 +45,6 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.util.ArrayUtils;
@@ -94,8 +93,6 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
private final Context mContext;
private IPackageManager mPackageManager;
- private final Object mInstallLock;
- @GuardedBy("mInstallLock")
private final Installer mInstaller;
private final Handler mHandler;
@@ -105,10 +102,9 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
}
public ArtManagerService(Context context, Installer installer,
- Object installLock) {
+ Object ignored) {
mContext = context;
mInstaller = installer;
- mInstallLock = installLock;
mHandler = new Handler(BackgroundThread.getHandler().getLooper());
LocalServices.addService(ArtManagerInternal.class, new ArtManagerInternalImpl());
@@ -273,16 +269,14 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
private void createProfileSnapshot(String packageName, String profileName, String classpath,
int appId, ISnapshotRuntimeProfileCallback callback) {
// Ask the installer to snapshot the profile.
- synchronized (mInstallLock) {
- try {
- if (!mInstaller.createProfileSnapshot(appId, packageName, profileName, classpath)) {
- postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
- return;
- }
- } catch (InstallerException e) {
+ try {
+ if (!mInstaller.createProfileSnapshot(appId, packageName, profileName, classpath)) {
postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
return;
}
+ } catch (InstallerException e) {
+ postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
+ return;
}
// Open the snapshot and invoke the callback.
@@ -308,13 +302,11 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
Slog.d(TAG, "Destroying profile snapshot for" + packageName + ":" + profileName);
}
- synchronized (mInstallLock) {
- try {
- mInstaller.destroyProfileSnapshot(packageName, profileName);
- } catch (InstallerException e) {
- Slog.e(TAG, "Failed to destroy profile snapshot for " +
- packageName + ":" + profileName, e);
- }
+ try {
+ mInstaller.destroyProfileSnapshot(packageName, profileName);
+ } catch (InstallerException e) {
+ Slog.e(TAG, "Failed to destroy profile snapshot for " + packageName + ":" + profileName,
+ e);
}
}
@@ -480,9 +472,7 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
for (int i = packageProfileNames.size() - 1; i >= 0; i--) {
String codePath = packageProfileNames.keyAt(i);
String profileName = packageProfileNames.valueAt(i);
- synchronized (mInstallLock) {
- mInstaller.dumpProfiles(sharedGid, pkg.getPackageName(), profileName, codePath);
- }
+ mInstaller.dumpProfiles(sharedGid, pkg.getPackageName(), profileName, codePath);
}
} catch (InstallerException e) {
Slog.w(TAG, "Failed to dump profiles", e);
@@ -512,10 +502,8 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
") to " + outDexFile);
final long callingId = Binder.clearCallingIdentity();
try {
- synchronized (mInstallLock) {
- return mInstaller.compileLayouts(apkPath, packageName, outDexFile,
- pkg.getUid());
- }
+ return mInstaller.compileLayouts(apkPath, packageName, outDexFile,
+ pkg.getUid());
} finally {
Binder.restoreCallingIdentity(callingId);
}
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index f255db4a9801..9897c42e4cec 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -209,8 +209,6 @@ public class ParsingPackageUtils {
public static final int SDK_VERSION = Build.VERSION.SDK_INT;
public static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES;
- public static final String[] PREVIOUS_CODENAMES =
- Build.VERSION.KNOWN_CODENAMES.toArray(new String[]{});
public static boolean sCompatibilityModeEnabled = true;
public static boolean sUseRoundIcon = false;
@@ -238,7 +236,7 @@ public class ParsingPackageUtils {
*/
public static final int PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY = 1 << 7;
public static final int PARSE_FRAMEWORK_RES_SPLITS = 1 << 8;
- public static final int PARSE_CHECK_MAX_SDK_VERSION = 1 << 9;
+ public static final int PARSE_APK_IN_APEX = 1 << 9;
public static final int PARSE_CHATTY = 1 << 31;
@@ -1534,7 +1532,7 @@ public class ParsingPackageUtils {
ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)
throws IOException, XmlPullParserException {
if (SDK_VERSION > 0) {
- final boolean checkMaxSdkVersion = (flags & PARSE_CHECK_MAX_SDK_VERSION) != 0;
+ final boolean isApkInApex = (flags & PARSE_APK_IN_APEX) != 0;
TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdk);
try {
int minVers = ParsingUtils.DEFAULT_MIN_SDK_VERSION;
@@ -1569,7 +1567,7 @@ public class ParsingPackageUtils {
targetCode = minCode;
}
- if (checkMaxSdkVersion) {
+ if (isApkInApex) {
val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_maxSdkVersion);
if (val != null) {
// maxSdkVersion only supports integer
@@ -1578,7 +1576,8 @@ public class ParsingPackageUtils {
}
ParseResult<Integer> targetSdkVersionResult = FrameworkParsingPackageUtils
- .computeTargetSdkVersion(targetVers, targetCode, SDK_CODENAMES, input);
+ .computeTargetSdkVersion(targetVers, targetCode, SDK_CODENAMES, input,
+ isApkInApex);
if (targetSdkVersionResult.isError()) {
return input.error(targetSdkVersionResult);
}
@@ -1601,7 +1600,7 @@ public class ParsingPackageUtils {
pkg.setMinSdkVersion(minSdkVersion)
.setTargetSdkVersion(targetSdkVersion);
- if (checkMaxSdkVersion) {
+ if (isApkInApex) {
ParseResult<Integer> maxSdkVersionResult = FrameworkParsingPackageUtils
.computeMaxSdkVersion(maxVers, SDK_VERSION, input);
if (maxSdkVersionResult.isError()) {
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index 2f68f56a7de0..bce1cce0f47f 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -29,6 +29,7 @@ import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.content.Intent.EXTRA_PACKAGE_NAME;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.SensorPrivacyManager.EXTRA_ALL_SENSORS;
import static android.hardware.SensorPrivacyManager.EXTRA_SENSOR;
@@ -77,6 +78,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.res.Configuration;
import android.graphics.drawable.Icon;
import android.hardware.ISensorPrivacyListener;
@@ -155,6 +157,7 @@ public final class SensorPrivacyService extends SystemService {
private final AppOpsManager mAppOpsManager;
private final AppOpsManagerInternal mAppOpsManagerInternal;
private final TelephonyManager mTelephonyManager;
+ private final PackageManagerInternal mPackageManagerInternal;
private CameraPrivacyLightController mCameraPrivacyLightController;
@@ -178,6 +181,7 @@ public final class SensorPrivacyService extends SystemService {
mActivityManagerInternal = getLocalService(ActivityManagerInternal.class);
mActivityTaskManager = context.getSystemService(ActivityTaskManager.class);
mTelephonyManager = context.getSystemService(TelephonyManager.class);
+ mPackageManagerInternal = getLocalService(PackageManagerInternal.class);
mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl();
}
@@ -828,6 +832,12 @@ public final class SensorPrivacyService extends SystemService {
* sensor privacy.
*/
private void enforceObserveSensorPrivacyPermission() {
+ String systemUIPackage = mContext.getString(R.string.config_systemUi);
+ if (Binder.getCallingUid() == mPackageManagerInternal
+ .getPackageUid(systemUIPackage, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM)) {
+ // b/221782106, possible race condition with role grant might bootloop device.
+ return;
+ }
enforcePermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY,
"Observing sensor privacy changes requires the following permission: "
+ android.Manifest.permission.OBSERVE_SENSOR_PRIVACY);
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
index c0ab65a3215c..05d92beed11f 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
@@ -17,7 +17,6 @@
package com.android.server.soundtrigger_middleware;
import android.annotation.NonNull;
-import android.media.permission.SafeCloseable;
import android.media.soundtrigger.ModelParameterRange;
import android.media.soundtrigger.PhraseRecognitionEvent;
import android.media.soundtrigger.PhraseSoundModel;
@@ -30,6 +29,7 @@ import android.media.soundtrigger.Status;
import android.os.IBinder;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
@@ -63,18 +63,24 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal,
ICaptureStateNotifier.Listener {
- private final @NonNull ISoundTriggerHal mDelegate;
+ @NonNull private final ISoundTriggerHal mDelegate;
private GlobalCallback mGlobalCallback;
+ /**
+ * This lock must be held to synchronize forward calls (start/stop/onCaptureStateChange) that
+ * update the mActiveModels set and mCaptureState.
+ * It must not be locked in HAL callbacks to avoid deadlocks.
+ */
+ @NonNull private final Object mStartStopLock = new Object();
/**
* Information about a model that is currently loaded. This is needed in order to be able to
* send abort events to its designated callback.
*/
private static class LoadedModel {
- final int type;
- final @NonNull ModelCallback callback;
+ public final int type;
+ @NonNull public final ModelCallback callback;
- private LoadedModel(int type, @NonNull ModelCallback callback) {
+ LoadedModel(int type, @NonNull ModelCallback callback) {
this.type = type;
this.callback = callback;
}
@@ -83,19 +89,19 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
/**
* This map holds the model type for every model that is loaded.
*/
- private final @NonNull Map<Integer, LoadedModel> mLoadedModels = new ConcurrentHashMap<>();
+ @NonNull private final Map<Integer, LoadedModel> mLoadedModels = new ConcurrentHashMap<>();
/**
* A set of all models that are currently active.
* We use this in order to know which models to stop in case of external capture.
* Used as a lock to synchronize operations that effect activity.
*/
- private final @NonNull Set<Integer> mActiveModels = new HashSet<>();
+ @NonNull private final Set<Integer> mActiveModels = new HashSet<>();
/**
* Notifier for changes in capture state.
*/
- private final @NonNull ICaptureStateNotifier mNotifier;
+ @NonNull private final ICaptureStateNotifier mNotifier;
/**
* Whether capture is active.
@@ -106,10 +112,10 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
* Since we're wrapping the death recipient, we need to keep a translation map for unlinking.
* Key is the client recipient, value is the wrapper.
*/
- private final @NonNull Map<IBinder.DeathRecipient, IBinder.DeathRecipient>
+ @NonNull private final Map<IBinder.DeathRecipient, IBinder.DeathRecipient>
mDeathRecipientMap = new ConcurrentHashMap<>();
- private final @NonNull CallbackThread mCallbackThread = new CallbackThread();
+ @NonNull private final CallbackThread mCallbackThread = new CallbackThread();
public SoundTriggerHalConcurrentCaptureHandler(
@NonNull ISoundTriggerHal delegate,
@@ -122,20 +128,28 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
@Override
public void startRecognition(int modelHandle, int deviceHandle, int ioHandle,
RecognitionConfig config) {
- synchronized (mActiveModels) {
- if (mCaptureState) {
- throw new RecoverableException(Status.RESOURCE_CONTENTION);
+ synchronized (mStartStopLock) {
+ synchronized (mActiveModels) {
+ if (mCaptureState) {
+ throw new RecoverableException(Status.RESOURCE_CONTENTION);
+ }
+ mDelegate.startRecognition(modelHandle, deviceHandle, ioHandle, config);
+ mActiveModels.add(modelHandle);
}
- mDelegate.startRecognition(modelHandle, deviceHandle, ioHandle, config);
- mActiveModels.add(modelHandle);
}
}
@Override
public void stopRecognition(int modelHandle) {
- synchronized (mActiveModels) {
- mDelegate.stopRecognition(modelHandle);
- mActiveModels.remove(modelHandle);
+ synchronized (mStartStopLock) {
+ boolean wasActive;
+ synchronized (mActiveModels) {
+ wasActive = mActiveModels.remove(modelHandle);
+ }
+ if (wasActive) {
+ // Must be done outside of the lock, since it may trigger synchronous callbacks.
+ mDelegate.stopRecognition(modelHandle);
+ }
}
// Block until all previous events are delivered. Since this is potentially blocking on
// upward calls, it must be done outside the lock.
@@ -144,27 +158,38 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
@Override
public void onCaptureStateChange(boolean active) {
- synchronized (mActiveModels) {
+ synchronized (mStartStopLock) {
if (active) {
- // Abort all active models. This must be done as one transaction to the event
- // thread, in order to be able to dedupe events before they are delivered.
- try (SafeCloseable ignored = mCallbackThread.stallReader()) {
- for (int modelHandle : mActiveModels) {
- mDelegate.stopRecognition(modelHandle);
- LoadedModel model = mLoadedModels.get(modelHandle);
- // An abort event must be the last one for its model.
- mCallbackThread.pushWithDedupe(modelHandle, true,
- () -> notifyAbort(modelHandle, model));
- }
- }
+ abortAllActiveModels();
} else {
- mGlobalCallback.onResourcesAvailable();
+ if (mGlobalCallback != null) {
+ mGlobalCallback.onResourcesAvailable();
+ }
}
-
mCaptureState = active;
}
}
+ private void abortAllActiveModels() {
+ while (true) {
+ int toStop;
+ synchronized (mActiveModels) {
+ Iterator<Integer> iterator = mActiveModels.iterator();
+ if (!iterator.hasNext()) {
+ return;
+ }
+ toStop = iterator.next();
+ mActiveModels.remove(toStop);
+ }
+ // Invoke stop outside of the lock.
+ mDelegate.stopRecognition(toStop);
+
+ LoadedModel model = mLoadedModels.get(toStop);
+ // Queue an abort event (no need to flush).
+ mCallbackThread.push(() -> notifyAbort(toStop, model));
+ }
+ }
+
@Override
public int loadSoundModel(SoundModel soundModel, ModelCallback callback) {
int handle = mDelegate.loadSoundModel(soundModel, new CallbackWrapper(callback));
@@ -188,23 +213,13 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
@Override
public void registerCallback(GlobalCallback callback) {
- mGlobalCallback = new GlobalCallback() {
- @Override
- public void onResourcesAvailable() {
- mCallbackThread.push(callback::onResourcesAvailable);
- }
- };
+ mGlobalCallback = () -> mCallbackThread.push(callback::onResourcesAvailable);
mDelegate.registerCallback(mGlobalCallback);
}
@Override
public void linkToDeath(IBinder.DeathRecipient recipient) {
- IBinder.DeathRecipient wrapper = new IBinder.DeathRecipient() {
- @Override
- public void binderDied() {
- mCallbackThread.push(() -> recipient.binderDied());
- }
- };
+ IBinder.DeathRecipient wrapper = () -> mCallbackThread.push(recipient::binderDied);
mDelegate.linkToDeath(wrapper);
mDeathRecipientMap.put(recipient, wrapper);
}
@@ -215,7 +230,7 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
}
private class CallbackWrapper implements ISoundTriggerHal.ModelCallback {
- private final @NonNull ISoundTriggerHal.ModelCallback mDelegateCallback;
+ @NonNull private final ISoundTriggerHal.ModelCallback mDelegateCallback;
private CallbackWrapper(@NonNull ModelCallback delegateCallback) {
mDelegateCallback = delegateCallback;
@@ -223,18 +238,36 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
@Override
public void recognitionCallback(int modelHandle, RecognitionEvent event) {
- // A recognition event must be the last one for its model, unless it is a forced one
- // (those leave the model active).
- mCallbackThread.pushWithDedupe(modelHandle, !event.recognitionStillActive,
- () -> mDelegateCallback.recognitionCallback(modelHandle, event));
+ synchronized (mActiveModels) {
+ if (!mActiveModels.contains(modelHandle)) {
+ // Discard the event.
+ return;
+ }
+ if (!event.recognitionStillActive) {
+ mActiveModels.remove(modelHandle);
+ }
+ // A recognition event must be the last one for its model, unless it indicates that
+ // recognition is still active.
+ mCallbackThread.push(
+ () -> mDelegateCallback.recognitionCallback(modelHandle, event));
+ }
}
@Override
public void phraseRecognitionCallback(int modelHandle, PhraseRecognitionEvent event) {
- // A recognition event must be the last one for its model, unless it is a forced one
- // (those leave the model active).
- mCallbackThread.pushWithDedupe(modelHandle, !event.common.recognitionStillActive,
- () -> mDelegateCallback.phraseRecognitionCallback(modelHandle, event));
+ synchronized (mActiveModels) {
+ if (!mActiveModels.contains(modelHandle)) {
+ // Discard the event.
+ return;
+ }
+ if (!event.common.recognitionStillActive) {
+ mActiveModels.remove(modelHandle);
+ }
+ // A recognition event must be the last one for its model, unless it indicates that
+ // recognition is still active.
+ mCallbackThread.push(
+ () -> mDelegateCallback.phraseRecognitionCallback(modelHandle, event));
+ }
}
@Override
@@ -254,36 +287,12 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
* <ul>
* <li>Events are processed on a separate thread than the thread that pushed them, in the order
* they were pushed.
- * <li>Events can be deduped upon entry to the queue. This is achieved as follows:
- * <ul>
- * <li>Temporarily stall the reader via {@link #stallReader()}.
- * <li>Within this scope, push as many events as needed via
- * {@link #pushWithDedupe(int, boolean, Runnable)}.
- * If an event with the same model handle as the one being pushed is already in the queue
- * and has been marked as "lastForModel", the new event will be discarded before entering
- * the queue.
- * <li>Finally, un-stall the reader by existing the scope.
- * <li>Events that do not require deduping can be pushed via {@link #push(Runnable)}.
- * </ul>
* <li>Events can be flushed via {@link #flush()}. This will block until all events pushed prior
* to this call have been fully processed.
* </ul>
*/
private static class CallbackThread {
- private static class Entry {
- final boolean lastForModel;
- final int modelHandle;
- final Runnable runnable;
-
- private Entry(boolean lastForModel, int modelHandle, Runnable runnable) {
- this.lastForModel = lastForModel;
- this.modelHandle = modelHandle;
- this.runnable = runnable;
- }
- }
-
- private boolean mStallReader = false;
- private final Queue<Entry> mList = new LinkedList<>();
+ private final Queue<Runnable> mList = new LinkedList<>();
private int mPushCount = 0;
private int mProcessedCount = 0;
@@ -312,23 +321,11 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
* @param runnable The runnable to push.
*/
void push(Runnable runnable) {
- pushEntry(new Entry(false, 0, runnable), false);
- }
-
-
- /**
- * Push a new runnable to the queue, with deduping.
- * If an entry with the same model handle is already in the queue and was designated as
- * last for model, this one will be discarded.
- *
- * @param modelHandle The model handle, used for deduping purposes.
- * @param lastForModel If true, this entry will be considered the last one for this model
- * and any subsequence calls for this handle (whether lastForModel or
- * not) will be discarded while this entry is in the queue.
- * @param runnable The runnable to push.
- */
- void pushWithDedupe(int modelHandle, boolean lastForModel, Runnable runnable) {
- pushEntry(new Entry(lastForModel, modelHandle, runnable), true);
+ synchronized (mList) {
+ mList.add(runnable);
+ mPushCount++;
+ mList.notifyAll();
+ }
}
/**
@@ -346,45 +343,15 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal
}
}
- /**
- * Creates a scope (using a try-with-resources block), within which events that are pushed
- * remain queued and processed. This is useful in order to utilize deduping.
- */
- SafeCloseable stallReader() {
- synchronized (mList) {
- mStallReader = true;
- return () -> {
- synchronized (mList) {
- mStallReader = false;
- mList.notifyAll();
- }
- };
- }
- }
-
- private void pushEntry(Entry entry, boolean dedupe) {
- synchronized (mList) {
- if (dedupe) {
- for (Entry existing : mList) {
- if (existing.lastForModel && existing.modelHandle == entry.modelHandle) {
- return;
- }
- }
- }
- mList.add(entry);
- mPushCount++;
- mList.notifyAll();
- }
- }
-
private Runnable pop() throws InterruptedException {
synchronized (mList) {
- while (mStallReader || mList.isEmpty()) {
+ while (mList.isEmpty()) {
mList.wait();
}
- return mList.remove().runnable;
+ return mList.remove();
}
}
+
}
/** Notify the client that recognition has been aborted. */
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw3Compat.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw3Compat.java
index 0a085ba4265f..ebe0ff85167d 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw3Compat.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw3Compat.java
@@ -206,6 +206,16 @@ public class SoundTriggerHw3Compat implements ISoundTriggerHal {
public void onResourcesAvailable() {
mDelegate.onResourcesAvailable();
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return ISoundTriggerHwGlobalCallback.VERSION;
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return ISoundTriggerHwGlobalCallback.HASH;
+ }
}
private static class ModelCallbackAdaper extends ISoundTriggerHwCallback.Stub {
@@ -233,5 +243,15 @@ public class SoundTriggerHw3Compat implements ISoundTriggerHal {
event.recognitionStillActive |= event.status == RecognitionStatus.FORCED;
mDelegate.recognitionCallback(model, event);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return ISoundTriggerHwCallback.VERSION;
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return ISoundTriggerHwCallback.HASH;
+ }
}
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 80877382f75a..b6855726c122 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -903,11 +903,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void hideAuthenticationDialog() {
+ public void hideAuthenticationDialog(long requestId) {
enforceBiometricDialog();
if (mBar != null) {
try {
- mBar.hideAuthenticationDialog();
+ mBar.hideAuthenticationDialog(requestId);
} catch (RemoteException ex) {
}
}
diff --git a/services/core/java/com/android/server/telecom/OWNERS b/services/core/java/com/android/server/telecom/OWNERS
index 39be2c1aecc4..cad25a4cec0d 100644
--- a/services/core/java/com/android/server/telecom/OWNERS
+++ b/services/core/java/com/android/server/telecom/OWNERS
@@ -1,6 +1 @@
-breadley@google.com
-hallliu@google.com
-tgunn@google.com
-xiaotonj@google.com
-shuoq@google.com
-rgreenwalt@google.com
+file:platform/frameworks/base:/telecomm/OWNERS
diff --git a/services/core/java/com/android/server/utils/WatchedArrayList.java b/services/core/java/com/android/server/utils/WatchedArrayList.java
index 6059f9675e34..bb0ba1329d86 100644
--- a/services/core/java/com/android/server/utils/WatchedArrayList.java
+++ b/services/core/java/com/android/server/utils/WatchedArrayList.java
@@ -273,13 +273,6 @@ public class WatchedArrayList<E> extends WatchableImpl
}
/**
- * Return true if all the objects in the given collection are in this array list.
- */
- public boolean containsAll(Collection<?> c) {
- return mStorage.containsAll(c);
- }
-
- /**
* Ensure capacity.
*/
public void ensureCapacity(int min) {
diff --git a/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java b/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java
index c43e7f9babe6..25ae00004b3e 100644
--- a/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java
+++ b/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java
@@ -18,7 +18,6 @@ package com.android.server.utils;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
@@ -169,19 +168,12 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
* A copy constructor that can be used for snapshotting.
*/
private WatchedSparseBooleanMatrix(WatchedSparseBooleanMatrix r) {
- copyFrom(r);
- }
-
- /**
- * Copy from src to this.
- */
- public void copyFrom(@NonNull WatchedSparseBooleanMatrix src) {
- mOrder = src.mOrder;
- mSize = src.mSize;
- mKeys = src.mKeys.clone();
- mMap = src.mMap.clone();
- mInUse = src.mInUse.clone();
- mValues = src.mValues.clone();
+ mOrder = r.mOrder;
+ mSize = r.mSize;
+ mKeys = r.mKeys.clone();
+ mMap = r.mMap.clone();
+ mInUse = r.mInUse.clone();
+ mValues = r.mValues.clone();
}
/**
diff --git a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java b/services/core/java/com/android/server/utils/WatchedSparseSetArray.java
deleted file mode 100644
index 05db12e49a13..000000000000
--- a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.utils;
-
-import android.annotation.NonNull;
-import android.util.ArraySet;
-import android.util.SparseSetArray;
-
-
-/**
- * A watched variant of SparseSetArray. Changes to the array are notified to
- * registered {@link Watcher}s.
- * @param <T> The element type, stored in the SparseSetArray.
- */
-public class WatchedSparseSetArray<T> extends WatchableImpl implements Snappable {
- // The storage
- private final SparseSetArray mStorage;
-
- // A private convenience function
- private void onChanged() {
- dispatchChange(this);
- }
-
- public WatchedSparseSetArray() {
- mStorage = new SparseSetArray();
- }
-
- /**
- * Creates a new WatchedSparseSetArray from an existing WatchedSparseSetArray and copy its data
- */
- public WatchedSparseSetArray(@NonNull WatchedSparseSetArray<T> watchedSparseSetArray) {
- mStorage = new SparseSetArray(watchedSparseSetArray.untrackedStorage());
- }
-
- /**
- * Return the underlying storage. This breaks the wrapper but is necessary when
- * passing the array to distant methods.
- */
- public SparseSetArray<T> untrackedStorage() {
- return mStorage;
- }
-
- /**
- * Add a value for key n.
- * @return FALSE when the value already existed for the given key, TRUE otherwise.
- */
- public boolean add(int n, T value) {
- final boolean res = mStorage.add(n, value);
- onChanged();
- return res;
- }
-
- /**
- * Removes all mappings from this SparseSetArray.
- */
- public void clear() {
- mStorage.clear();
- onChanged();
- }
-
- /**
- * @return whether the value exists for the key n.
- */
- public boolean contains(int n, T value) {
- return mStorage.contains(n, value);
- }
-
- /**
- * @return the set of items of key n
- */
- public ArraySet<T> get(int n) {
- return mStorage.get(n);
- }
-
- /**
- * Remove a value for key n.
- * @return TRUE when the value existed for the given key and removed, FALSE otherwise.
- */
- public boolean remove(int n, T value) {
- if (mStorage.remove(n, value)) {
- onChanged();
- return true;
- }
- return false;
- }
-
- /**
- * Remove all values for key n.
- */
- public void remove(int n) {
- mStorage.remove(n);
- onChanged();
- }
-
- /**
- * Return the size of the SparseSetArray.
- */
- public int size() {
- return mStorage.size();
- }
-
- /**
- * Return the key stored at the given index.
- */
- public int keyAt(int index) {
- return mStorage.keyAt(index);
- }
-
- /**
- * Return the size of the array at the given index.
- */
- public int sizeAt(int index) {
- return mStorage.sizeAt(index);
- }
-
- /**
- * Return the value in the SetArray at the given key index and value index.
- */
- public T valueAt(int intIndex, int valueIndex) {
- return (T) mStorage.valueAt(intIndex, valueIndex);
- }
-
- @NonNull
- @Override
- public Object snapshot() {
- WatchedSparseSetArray l = new WatchedSparseSetArray(this);
- l.seal();
- return l;
- }
-
- /**
- * Make <this> a snapshot of the argument. Note that <this> is immutable when the
- * method returns. <this> must be empty when the function is called.
- * @param r The source array, which is copied into <this>
- */
- public void snapshot(@NonNull WatchedSparseSetArray<T> r) {
- snapshot(this, r);
- }
-
- /**
- * Make the destination a copy of the source. If the element is a subclass of Snapper then the
- * copy contains snapshots of the elements. Otherwise the copy contains references to the
- * elements. The destination must be initially empty. Upon return, the destination is
- * immutable.
- * @param dst The destination array. It must be empty.
- * @param src The source array. It is not modified.
- */
- public static void snapshot(@NonNull WatchedSparseSetArray dst,
- @NonNull WatchedSparseSetArray src) {
- if (dst.size() != 0) {
- throw new IllegalArgumentException("snapshot destination is not empty");
- }
- final int arraySize = src.size();
- for (int i = 0; i < arraySize; i++) {
- final ArraySet set = src.get(i);
- final int setSize = set.size();
- for (int j = 0; j < setSize; j++) {
- dst.add(src.keyAt(i), set.valueAt(j));
- }
- }
- dst.seal();
- }
-}
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 597f7f284730..be38005abb63 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -544,6 +544,7 @@ public class VcnGatewayConnection extends StateMachine {
private final boolean mIsMobileDataEnabled;
@NonNull private final IpSecManager mIpSecManager;
+ @NonNull private final ConnectivityManager mConnectivityManager;
@Nullable private IpSecTunnelInterface mTunnelIface = null;
@@ -701,6 +702,7 @@ public class VcnGatewayConnection extends StateMachine {
mLastSnapshot,
mUnderlyingNetworkControllerCallback);
mIpSecManager = mVcnContext.getContext().getSystemService(IpSecManager.class);
+ mConnectivityManager = mVcnContext.getContext().getSystemService(ConnectivityManager.class);
addState(mDisconnectedState);
addState(mDisconnectingState);
@@ -1683,6 +1685,14 @@ public class VcnGatewayConnection extends StateMachine {
clearFailedAttemptCounterAndSafeModeAlarm();
break;
case NetworkAgent.VALIDATION_STATUS_NOT_VALID:
+ // Trigger re-validation of underlying networks; if it
+ // fails, the VCN will attempt to migrate away.
+ if (mUnderlying != null) {
+ mConnectivityManager.reportNetworkConnectivity(
+ mUnderlying.network,
+ false /* hasConnectivity */);
+ }
+
// Will only set a new alarm if no safe mode alarm is
// currently scheduled.
setSafeModeAlarm();
@@ -1869,6 +1879,10 @@ public class VcnGatewayConnection extends StateMachine {
IpSecManager.DIRECTION_OUT);
updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig);
+
+ // Trigger re-validation after migration events.
+ mConnectivityManager.reportNetworkConnectivity(
+ mNetworkAgent.getNetwork(), false /* hasConnectivity */);
}
private void handleUnderlyingNetworkChanged(@NonNull Message msg) {
diff --git a/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java b/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java
index 3550bda282dd..12e68b10c3df 100644
--- a/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java
@@ -141,8 +141,16 @@ abstract class AbstractVibratorStep extends Step {
*/
protected List<Step> nextSteps(long nextStartTime, long vibratorOffTimeout,
int segmentsPlayed) {
+ int nextSegmentIndex = segmentIndex + segmentsPlayed;
+ int effectSize = effect.getSegments().size();
+ int repeatIndex = effect.getRepeatIndex();
+ if (nextSegmentIndex >= effectSize && repeatIndex >= 0) {
+ // Count the loops that were played.
+ int loopSize = effectSize - repeatIndex;
+ nextSegmentIndex = repeatIndex + ((nextSegmentIndex - effectSize) % loopSize);
+ }
Step nextStep = conductor.nextVibrateStep(nextStartTime, controller, effect,
- segmentIndex + segmentsPlayed, vibratorOffTimeout);
+ nextSegmentIndex, vibratorOffTimeout);
return nextStep == null ? VibrationStepConductor.EMPTY_STEP_LIST : Arrays.asList(nextStep);
}
}
diff --git a/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java b/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java
index d1ea80557419..3bc11c8f8322 100644
--- a/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java
@@ -32,6 +32,11 @@ import java.util.List;
* {@link PrimitiveSegment} starting at the current index.
*/
final class ComposePrimitivesVibratorStep extends AbstractVibratorStep {
+ /**
+ * Default limit to the number of primitives in a composition, if none is defined by the HAL,
+ * to prevent repeating effects from generating an infinite list.
+ */
+ private static final int DEFAULT_COMPOSITION_SIZE_LIMIT = 100;
ComposePrimitivesVibratorStep(VibrationStepConductor conductor, long startTime,
VibratorController controller, VibrationEffect.Composed effect, int index,
@@ -49,18 +54,8 @@ final class ComposePrimitivesVibratorStep extends AbstractVibratorStep {
// Load the next PrimitiveSegments to create a single compose call to the vibrator,
// limited to the vibrator composition maximum size.
int limit = controller.getVibratorInfo().getCompositionSizeMax();
- int segmentCount = limit > 0
- ? Math.min(effect.getSegments().size(), segmentIndex + limit)
- : effect.getSegments().size();
- List<PrimitiveSegment> primitives = new ArrayList<>();
- for (int i = segmentIndex; i < segmentCount; i++) {
- VibrationEffectSegment segment = effect.getSegments().get(i);
- if (segment instanceof PrimitiveSegment) {
- primitives.add((PrimitiveSegment) segment);
- } else {
- break;
- }
- }
+ List<PrimitiveSegment> primitives = unrollPrimitiveSegments(effect, segmentIndex,
+ limit > 0 ? limit : DEFAULT_COMPOSITION_SIZE_LIMIT);
if (primitives.isEmpty()) {
Slog.w(VibrationThread.TAG, "Ignoring wrong segment for a ComposePrimitivesStep: "
@@ -81,4 +76,44 @@ final class ComposePrimitivesVibratorStep extends AbstractVibratorStep {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
}
+
+ /**
+ * Get the primitive segments to be played by this step as a single composition, starting at
+ * {@code startIndex} until:
+ *
+ * <ol>
+ * <li>There are no more segments in the effect;
+ * <li>The first non-primitive segment is found;
+ * <li>The given limit to the composition size is reached.
+ * </ol>
+ *
+ * <p>If the effect is repeating then this method will generate the largest composition within
+ * given limit.
+ */
+ private List<PrimitiveSegment> unrollPrimitiveSegments(VibrationEffect.Composed effect,
+ int startIndex, int limit) {
+ List<PrimitiveSegment> segments = new ArrayList<>(limit);
+ int segmentCount = effect.getSegments().size();
+ int repeatIndex = effect.getRepeatIndex();
+
+ for (int i = startIndex; segments.size() < limit; i++) {
+ if (i == segmentCount) {
+ if (repeatIndex >= 0) {
+ i = repeatIndex;
+ } else {
+ // Non-repeating effect, stop collecting primitives.
+ break;
+ }
+ }
+ VibrationEffectSegment segment = effect.getSegments().get(i);
+ if (segment instanceof PrimitiveSegment) {
+ segments.add((PrimitiveSegment) segment);
+ } else {
+ // First non-primitive segment, stop collecting primitives.
+ break;
+ }
+ }
+
+ return segments;
+ }
}
diff --git a/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java b/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java
index 73bf933f8bc9..919f1be27ef9 100644
--- a/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java
@@ -33,6 +33,11 @@ import java.util.List;
* {@link StepSegment} or {@link RampSegment} starting at the current index.
*/
final class ComposePwleVibratorStep extends AbstractVibratorStep {
+ /**
+ * Default limit to the number of PWLE segments, if none is defined by the HAL, to prevent
+ * repeating effects from generating an infinite list.
+ */
+ private static final int DEFAULT_PWLE_SIZE_LIMIT = 100;
ComposePwleVibratorStep(VibrationStepConductor conductor, long startTime,
VibratorController controller, VibrationEffect.Composed effect, int index,
@@ -50,18 +55,8 @@ final class ComposePwleVibratorStep extends AbstractVibratorStep {
// Load the next RampSegments to create a single composePwle call to the vibrator,
// limited to the vibrator PWLE maximum size.
int limit = controller.getVibratorInfo().getPwleSizeMax();
- int segmentCount = limit > 0
- ? Math.min(effect.getSegments().size(), segmentIndex + limit)
- : effect.getSegments().size();
- List<RampSegment> pwles = new ArrayList<>();
- for (int i = segmentIndex; i < segmentCount; i++) {
- VibrationEffectSegment segment = effect.getSegments().get(i);
- if (segment instanceof RampSegment) {
- pwles.add((RampSegment) segment);
- } else {
- break;
- }
- }
+ List<RampSegment> pwles = unrollRampSegments(effect, segmentIndex,
+ limit > 0 ? limit : DEFAULT_PWLE_SIZE_LIMIT);
if (pwles.isEmpty()) {
Slog.w(VibrationThread.TAG, "Ignoring wrong segment for a ComposePwleStep: "
@@ -81,4 +76,88 @@ final class ComposePwleVibratorStep extends AbstractVibratorStep {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
}
+
+ /**
+ * Get the ramp segments to be played by this step for a waveform, starting at
+ * {@code startIndex} until:
+ *
+ * <ol>
+ * <li>There are no more segments in the effect;
+ * <li>The first non-ramp segment is found;
+ * <li>The given limit to the PWLE size is reached.
+ * </ol>
+ *
+ * <p>If the effect is repeating then this method will generate the largest PWLE within given
+ * limit. This will also optimize to end the list at a ramp to zero-amplitude, if possible, and
+ * avoid braking down the effect in non-zero amplitude.
+ */
+ private List<RampSegment> unrollRampSegments(VibrationEffect.Composed effect, int startIndex,
+ int limit) {
+ List<RampSegment> segments = new ArrayList<>(limit);
+ float bestBreakAmplitude = 1;
+ int bestBreakPosition = limit; // Exclusive index.
+
+ int segmentCount = effect.getSegments().size();
+ int repeatIndex = effect.getRepeatIndex();
+
+ // Loop once after reaching the limit to see if breaking it will really be necessary, then
+ // apply the best break position found, otherwise return the full list as it fits the limit.
+ for (int i = startIndex; segments.size() <= limit; i++) {
+ if (i == segmentCount) {
+ if (repeatIndex >= 0) {
+ i = repeatIndex;
+ } else {
+ // Non-repeating effect, stop collecting ramps.
+ break;
+ }
+ }
+ VibrationEffectSegment segment = effect.getSegments().get(i);
+ if (segment instanceof RampSegment) {
+ RampSegment rampSegment = (RampSegment) segment;
+ segments.add(rampSegment);
+
+ if (isBetterBreakPosition(segments, bestBreakAmplitude, limit)) {
+ // Mark this position as the best one so far to break a long waveform.
+ bestBreakAmplitude = rampSegment.getEndAmplitude();
+ bestBreakPosition = segments.size(); // Break after this ramp ends.
+ }
+ } else {
+ // First non-ramp segment, stop collecting ramps.
+ break;
+ }
+ }
+
+ return segments.size() > limit
+ // Remove excessive segments, using the best breaking position recorded.
+ ? segments.subList(0, bestBreakPosition)
+ // Return all collected ramp segments.
+ : segments;
+ }
+
+ /**
+ * Returns true if the current segment list represents a better break position for a PWLE,
+ * given the current amplitude being used for breaking it at a smaller size and the size limit.
+ */
+ private boolean isBetterBreakPosition(List<RampSegment> segments,
+ float currentBestBreakAmplitude, int limit) {
+ RampSegment lastSegment = segments.get(segments.size() - 1);
+ float breakAmplitudeCandidate = lastSegment.getEndAmplitude();
+ int breakPositionCandidate = segments.size();
+
+ if (breakPositionCandidate > limit) {
+ // We're beyond limit, last break position found should be used.
+ return false;
+ }
+ if (breakAmplitudeCandidate == 0) {
+ // Breaking at amplitude zero at any position is always preferable.
+ return true;
+ }
+ if (breakPositionCandidate < limit / 2) {
+ // Avoid breaking at the first half of the allowed maximum size, even if amplitudes are
+ // lower, to avoid creating PWLEs that are too small unless it's to break at zero.
+ return false;
+ }
+ // Prefer lower amplitudes at a later position for breaking the PWLE in a more subtle way.
+ return breakAmplitudeCandidate <= currentBestBreakAmplitude;
+ }
}
diff --git a/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java b/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java
index d5c11161bdfa..1f0d2d71d25c 100644
--- a/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java
@@ -33,6 +33,12 @@ import java.util.List;
* and amplitude to simulate waveforms represented by a sequence of {@link StepSegment}.
*/
final class SetAmplitudeVibratorStep extends AbstractVibratorStep {
+ /**
+ * The repeating waveform keeps the vibrator ON all the time. Use a minimum duration to
+ * prevent short patterns from turning the vibrator ON too frequently.
+ */
+ private static final int REPEATING_EFFECT_ON_DURATION = 5000; // 5s
+
private long mNextOffTime;
SetAmplitudeVibratorStep(VibrationStepConductor conductor, long startTime,
@@ -170,10 +176,7 @@ final class SetAmplitudeVibratorStep extends AbstractVibratorStep {
repeatIndex = -1;
}
if (i == startIndex) {
- // The repeating waveform keeps the vibrator ON all the time. Use a minimum
- // of 1s duration to prevent short patterns from turning the vibrator ON too
- // frequently.
- return Math.max(timing, 1000);
+ return Math.max(timing, REPEATING_EFFECT_ON_DURATION);
}
}
if (i == segmentCount && effect.getRepeatIndex() < 0) {
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 3ffca9660098..bf3298558cd6 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -989,12 +989,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
*/
@NonNull
private VibrationAttributes fixupVibrationAttributes(@Nullable VibrationAttributes attrs,
- CombinedVibration effect) {
+ @Nullable CombinedVibration effect) {
if (attrs == null) {
attrs = DEFAULT_ATTRIBUTES;
}
int usage = attrs.getUsage();
- if ((usage == VibrationAttributes.USAGE_UNKNOWN) && effect.isHapticFeedbackCandidate()) {
+ if ((usage == VibrationAttributes.USAGE_UNKNOWN)
+ && (effect != null) && effect.isHapticFeedbackCandidate()) {
usage = VibrationAttributes.USAGE_TOUCH;
}
int flags = attrs.getFlags();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d8ad2a57afa4..22bfcc47bd90 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -8087,7 +8087,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED;
final int orientation = orientationRequested
? requestedOrientation
- : newParentConfiguration.orientation;
+ // We should use the original orientation of the activity when possible to avoid
+ // forcing the activity in the opposite orientation.
+ : mCompatDisplayInsets.mOriginalRequestedOrientation != ORIENTATION_UNDEFINED
+ ? mCompatDisplayInsets.mOriginalRequestedOrientation
+ : newParentConfiguration.orientation;
int rotation = newParentConfiguration.windowConfiguration.getRotation();
final boolean isFixedToUserRotation = mDisplayContent == null
|| mDisplayContent.getDisplayRotation().isFixedToUserRotation();
@@ -9356,8 +9360,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* compatibility mode activity compute the configuration without relying on its current display.
*/
static class CompatDisplayInsets {
- /** The original rotation the compat insets were computed in */
+ /** The original rotation the compat insets were computed in. */
final @Rotation int mOriginalRotation;
+ /** The original requested orientation for the activity. */
+ final @Configuration.Orientation int mOriginalRequestedOrientation;
/** The container width on rotation 0. */
private final int mWidth;
/** The container height on rotation 0. */
@@ -9386,6 +9392,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Nullable Rect fixedOrientationBounds) {
mOriginalRotation = display.getRotation();
mIsFloating = container.getWindowConfiguration().tasksAreFloating();
+ mOriginalRequestedOrientation = container.getRequestedConfigurationOrientation();
if (mIsFloating) {
final Rect containerBounds = container.getWindowConfiguration().getBounds();
mWidth = containerBounds.width();
diff --git a/services/core/java/com/android/server/wm/AnimationAdapter.java b/services/core/java/com/android/server/wm/AnimationAdapter.java
index a7430912c0b9..b039646c1697 100644
--- a/services/core/java/com/android/server/wm/AnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/AnimationAdapter.java
@@ -43,7 +43,7 @@ interface AnimationAdapter {
/**
* @return Whether we should show a background behind the animating windows.
- * @see Animation#getShowBackground()
+ * @see Animation#getShowBackdrop()
*/
default boolean getShowBackground() {
return false;
@@ -51,7 +51,7 @@ interface AnimationAdapter {
/**
* @return The background color to use during an animation if getShowBackground returns true.
- * @see Animation#getBackgroundColor()
+ * @see Animation#getBackdropColor()
*/
default int getBackgroundColor() {
return 0;
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 5c09f09d9313..68a09a6d4b9b 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -843,7 +843,7 @@ public class AppTransition implements Dump {
setAppTransitionFinishedCallbackIfNeeded(a);
if (mNextAppTransitionBackgroundColor != 0) {
- a.setBackgroundColor(mNextAppTransitionBackgroundColor);
+ a.setBackdropColor(mNextAppTransitionBackgroundColor);
}
return a;
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 0b4d8876cf8f..cefc8717ed01 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -653,7 +653,7 @@ public class AppTransitionController {
final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizer(task);
final RemoteAnimationDefinition definition = organizer != null
? mDisplayContent.mAtmService.mTaskFragmentOrganizerController
- .getRemoteAnimationDefinition(organizer)
+ .getRemoteAnimationDefinition(organizer, task.mTaskId)
: null;
final RemoteAnimationAdapter adapter = definition != null
? definition.getAdapter(transit, activityTypes)
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a982078a25b6..81560d4f8676 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -551,6 +551,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
final FixedRotationTransitionListener mFixedRotationTransitionListener =
new FixedRotationTransitionListener();
+ private PhysicalDisplaySwitchTransitionLauncher mDisplaySwitchTransitionLauncher;
+
/** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
@@ -848,10 +850,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
w.onResizeHandled();
}
- if (w.mActivityRecord != null) {
- w.mActivityRecord.layoutLetterbox(w);
- }
-
if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrame()
+ " mParentFrame=" + w.getParentFrame()
+ " mDisplayFrame=" + w.getDisplayFrame());
@@ -1047,6 +1045,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mAppTransitionController = new AppTransitionController(mWmService, this);
mTransitionController.registerLegacyListener(mFixedRotationTransitionListener);
mUnknownAppVisibilityController = new UnknownAppVisibilityController(mWmService, this);
+ mDisplaySwitchTransitionLauncher = new PhysicalDisplaySwitchTransitionLauncher(this,
+ mTransitionController);
final InputChannel inputChannel = mWmService.mInputManager.monitorInput(
"PointerEventDispatcher" + mDisplayId, mDisplayId);
@@ -2755,6 +2755,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// metrics are updated as rotation settings might depend on them
mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this,
/* includeRotationSettings */ false);
+ mDisplaySwitchTransitionLauncher.requestDisplaySwitchTransitionIfNeeded(mDisplayId,
+ mInitialDisplayWidth, mInitialDisplayHeight, newWidth, newHeight);
}
// If there is an override set for base values - use it, otherwise use new values.
@@ -2783,6 +2785,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mInitialRoundedCorners = newRoundedCorners;
mCurrentUniqueDisplayId = newUniqueId;
reconfigureDisplayLocked();
+
+ if (physicalDisplayChanged) {
+ mDisplaySwitchTransitionLauncher.onDisplayUpdated();
+ }
}
}
@@ -3109,6 +3115,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mTransitionController.unregisterLegacyListener(mFixedRotationTransitionListener);
handleAnimatingStoppedAndTransition();
mWmService.stopFreezingDisplayLocked();
+ mDisplaySwitchTransitionLauncher.destroy();
super.removeImmediately();
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
mPointerEventDispatcher.dispose();
@@ -6362,10 +6369,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* Notifies the remote insets controller that the top focused window has changed.
*
* @param packageName The name of the package that is open in the top focused window.
+ * @param requestedVisibilities The insets visibilities requested by the focussed window.
*/
- void topFocusedWindowChanged(String packageName) {
+ void topFocusedWindowChanged(String packageName, InsetsVisibilities requestedVisibilities) {
try {
- mRemoteInsetsController.topFocusedWindowChanged(packageName);
+ mRemoteInsetsController.topFocusedWindowChanged(packageName, requestedVisibilities);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver package in top focused window change", e);
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 06f449e52478..566ed6076526 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1548,7 +1548,7 @@ public class DisplayPolicy {
win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale,
sTmpClientFrames);
- win.setFrames(sTmpClientFrames);
+ win.setFrames(sTmpClientFrames, win.mRequestedWidth, win.mRequestedHeight);
}
WindowState getTopFullscreenOpaqueWindow() {
@@ -1810,14 +1810,10 @@ public class DisplayPolicy {
/**
* Called when the resource overlays change.
*/
- void onOverlayChanged() {
+ public void onOverlayChangedLw() {
updateCurrentUserResources();
- // Update the latest display size, cutout.
- mDisplayContent.updateDisplayInfo();
- // The height of status bar needs to update in case display cutout is changed.
onConfigurationChanged();
- // The height of status bar can affect screen size configuration.
- mDisplayContent.reconfigureDisplayLocked();
+ mSystemGestures.onConfigurationChanged();
}
/**
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index 8d1425d17d47..67dd89ee295c 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -29,6 +29,7 @@ import android.graphics.PointF;
import android.os.Debug;
import android.os.IBinder;
import android.util.Slog;
+import android.view.Display;
import android.view.InputApplicationHandle;
import android.view.KeyEvent;
import android.view.SurfaceControl;
@@ -194,6 +195,9 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
int firstExternalDisplayId = DEFAULT_DISPLAY;
for (int i = mService.mRoot.mChildren.size() - 1; i >= 0; --i) {
final DisplayContent displayContent = mService.mRoot.mChildren.get(i);
+ if (displayContent.getDisplayInfo().state == Display.STATE_OFF) {
+ continue;
+ }
// Heuristic solution here. Currently when "Freeform windows" developer option is
// enabled we automatically put secondary displays in freeform mode and emulating
// "desktop mode". It also makes sense to show the pointer on the same display.
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 9844cb5fe8f8..a7b37281842a 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -533,7 +533,7 @@ class InsetsPolicy {
}
if (remoteInsetsControllerControlsSystemBars(focusedWin)) {
mDisplayContent.mRemoteInsetsControlTarget.topFocusedWindowChanged(
- focusedWin.mAttrs.packageName);
+ focusedWin.mAttrs.packageName, focusedWin.getRequestedVisibilities());
return mDisplayContent.mRemoteInsetsControlTarget;
}
if (mPolicy.areSystemBarsForcedShownLw()) {
@@ -590,7 +590,7 @@ class InsetsPolicy {
}
if (remoteInsetsControllerControlsSystemBars(focusedWin)) {
mDisplayContent.mRemoteInsetsControlTarget.topFocusedWindowChanged(
- focusedWin.mAttrs.packageName);
+ focusedWin.mAttrs.packageName, focusedWin.getRequestedVisibilities());
return mDisplayContent.mRemoteInsetsControlTarget;
}
if (mPolicy.areSystemBarsForcedShownLw()) {
diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
new file mode 100644
index 000000000000..9c1d5601dad5
--- /dev/null
+++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.TRANSIT_CHANGE;
+
+import static com.android.internal.R.bool.config_unfoldTransitionEnabled;
+import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.devicestate.DeviceStateManager;
+import android.os.HandlerExecutor;
+import android.window.TransitionRequestInfo;
+
+public class PhysicalDisplaySwitchTransitionLauncher {
+
+ private final DisplayContent mDisplayContent;
+ private final DeviceStateManager mDeviceStateManager;
+ private final Context mContext;
+ private final TransitionController mTransitionController;
+
+ private DeviceStateListener mDeviceStateListener;
+
+ /**
+ * If on a foldable device represents whether the device is folded or not
+ */
+ private boolean mIsFolded;
+ private Transition mTransition;
+
+ public PhysicalDisplaySwitchTransitionLauncher(DisplayContent displayContent,
+ TransitionController transitionController) {
+ mDisplayContent = displayContent;
+ mContext = mDisplayContent.mWmService.mContext;
+ mTransitionController = transitionController;
+
+ mDeviceStateManager = mContext.getSystemService(DeviceStateManager.class);
+
+ if (mDeviceStateManager != null) {
+ mDeviceStateListener = new DeviceStateListener(mContext);
+ mDeviceStateManager
+ .registerCallback(new HandlerExecutor(mDisplayContent.mWmService.mH),
+ mDeviceStateListener);
+ }
+ }
+
+ public void destroy() {
+ if (mDeviceStateManager != null) {
+ mDeviceStateManager.unregisterCallback(mDeviceStateListener);
+ }
+ }
+
+ /**
+ * Requests to start a transition for the physical display switch
+ */
+ public void requestDisplaySwitchTransitionIfNeeded(int displayId, int oldDisplayWidth,
+ int oldDisplayHeight, int newDisplayWidth, int newDisplayHeight) {
+ if (!mTransitionController.isShellTransitionsEnabled()) return;
+ if (!mDisplayContent.getLastHasContent()) return;
+
+ boolean shouldRequestUnfoldTransition = !mIsFolded
+ && mContext.getResources().getBoolean(config_unfoldTransitionEnabled)
+ && ValueAnimator.areAnimatorsEnabled();
+
+ if (!shouldRequestUnfoldTransition) {
+ return;
+ }
+
+ final TransitionRequestInfo.DisplayChange displayChange =
+ new TransitionRequestInfo.DisplayChange(displayId);
+
+ final Rect startAbsBounds = new Rect(0, 0, oldDisplayWidth, oldDisplayHeight);
+ displayChange.setStartAbsBounds(startAbsBounds);
+ final Rect endAbsBounds = new Rect(0, 0, newDisplayWidth, newDisplayHeight);
+ displayChange.setEndAbsBounds(endAbsBounds);
+ displayChange.setPhysicalDisplayChanged(true);
+
+ final Transition t = mTransitionController.requestTransitionIfNeeded(TRANSIT_CHANGE,
+ 0 /* flags */,
+ mDisplayContent, mDisplayContent, null /* remoteTransition */,
+ displayChange);
+
+ if (t != null) {
+ mDisplayContent.mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
+ mTransitionController.collectForDisplayChange(mDisplayContent, t);
+ mTransition = t;
+ }
+ }
+
+ public void onDisplayUpdated() {
+ if (mTransition != null) {
+ mTransition.setAllReady();
+ mTransition = null;
+ }
+ }
+
+ class DeviceStateListener extends DeviceStateManager.FoldStateListener {
+
+ DeviceStateListener(Context context) {
+ super(context, newIsFolded -> mIsFolded = newIsFolded);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 6d96cf06a00b..eca201dc2bda 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -304,10 +304,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
mService.stopAppSwitches();
}
- if (mCaller != null) {
- mCaller.setRunningRecentsAnimation(false);
- }
-
mWindowManager.inSurfaceTransaction(() -> {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"RecentsAnimation#onAnimationFinished_inSurfaceTransaction");
@@ -413,6 +409,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
if (mWindowManager.mRoot.isLayoutNeeded()) {
mWindowManager.mRoot.performSurfacePlacement();
}
+ if (mCaller != null) {
+ mCaller.setRunningRecentsAnimation(false);
+ }
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
});
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 6bb63d933353..65ae3fcb4c90 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -216,6 +216,10 @@ class ScreenRotationAnimation {
t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE);
t.reparent(mBackColorSurface, displayContent.getSurfaceControl());
+ // If hdr layers are on-screen, e.g. picture-in-picture mode, the screenshot of
+ // rotation animation is an sdr image containing tone-mapping hdr content, then
+ // disable dimming effect to get avoid of hdr content being dimmed during animation.
+ t.setDimmingEnabled(mScreenshotLayer, false);
t.setLayer(mBackColorSurface, -1);
t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma});
t.setAlpha(mBackColorSurface, 1);
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 0a92ffced48d..bd351acf5119 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -32,6 +32,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.RemoteAnimationDefinition;
import android.window.ITaskFragmentOrganizer;
import android.window.ITaskFragmentOrganizerController;
@@ -83,11 +84,12 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
new WeakHashMap<>();
/**
- * @see android.window.TaskFragmentOrganizer#registerRemoteAnimations(
- * RemoteAnimationDefinition)
+ * Map from Task Id to {@link RemoteAnimationDefinition}.
+ * @see android.window.TaskFragmentOrganizer#registerRemoteAnimations(int,
+ * RemoteAnimationDefinition) )
*/
- @Nullable
- private RemoteAnimationDefinition mRemoteAnimationDefinition;
+ private final SparseArray<RemoteAnimationDefinition> mRemoteAnimationDefinitions =
+ new SparseArray<>();
TaskFragmentOrganizerState(ITaskFragmentOrganizer organizer) {
mOrganizer = organizer;
@@ -251,7 +253,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
@Override
- public void registerRemoteAnimations(ITaskFragmentOrganizer organizer,
+ public void registerRemoteAnimations(ITaskFragmentOrganizer organizer, int taskId,
RemoteAnimationDefinition definition) {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
@@ -264,19 +266,20 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
if (organizerState == null) {
throw new IllegalStateException("The organizer hasn't been registered.");
}
- if (organizerState.mRemoteAnimationDefinition != null) {
+ if (organizerState.mRemoteAnimationDefinitions.contains(taskId)) {
throw new IllegalStateException(
"The organizer has already registered remote animations="
- + organizerState.mRemoteAnimationDefinition);
+ + organizerState.mRemoteAnimationDefinitions.get(taskId)
+ + " for TaskId=" + taskId);
}
definition.setCallingPidUid(pid, uid);
- organizerState.mRemoteAnimationDefinition = definition;
+ organizerState.mRemoteAnimationDefinitions.put(taskId, definition);
}
}
@Override
- public void unregisterRemoteAnimations(ITaskFragmentOrganizer organizer) {
+ public void unregisterRemoteAnimations(ITaskFragmentOrganizer organizer, int taskId) {
final int pid = Binder.getCallingPid();
final long uid = Binder.getCallingUid();
synchronized (mGlobalLock) {
@@ -290,7 +293,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
return;
}
- organizerState.mRemoteAnimationDefinition = null;
+ organizerState.mRemoteAnimationDefinitions.remove(taskId);
}
}
@@ -300,11 +303,13 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
*/
@Nullable
public RemoteAnimationDefinition getRemoteAnimationDefinition(
- ITaskFragmentOrganizer organizer) {
+ ITaskFragmentOrganizer organizer, int taskId) {
synchronized (mGlobalLock) {
final TaskFragmentOrganizerState organizerState =
mTaskFragmentOrganizerState.get(organizer.asBinder());
- return organizerState != null ? organizerState.mRemoteAnimationDefinition : null;
+ return organizerState != null
+ ? organizerState.mRemoteAnimationDefinitions.get(taskId)
+ : null;
}
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 14737d44fe22..a32a6087a04d 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -132,7 +132,12 @@ class WallpaperController {
return false;
}
} else {
- if (w.mActivityRecord != null && !w.mActivityRecord.isVisibleRequested()) {
+ 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)) {
// An activity that is not going to remain visible shouldn't be the target.
return false;
}
@@ -157,14 +162,17 @@ class WallpaperController {
& TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);
boolean needsShowWhenLockedWallpaper = false;
- if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
- && mService.mPolicy.isKeyguardLocked()
- && (mService.mPolicy.isKeyguardOccluded()
- || mService.mPolicy.isKeyguardUnoccluding())) {
- // The lowest show when locked window decides whether we need to put the wallpaper
- // behind.
- needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
- || (w.mActivityRecord != null && !w.mActivityRecord.fillsParent());
+ if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && mService.mPolicy.isKeyguardLocked()) {
+ final TransitionController tc = w.mTransitionController;
+ final boolean isInTransition = tc.isShellTransitionsEnabled()
+ && tc.inTransition(w);
+ if (mService.mPolicy.isKeyguardOccluded() || mService.mPolicy.isKeyguardUnoccluding()
+ || isInTransition) {
+ // The lowest show when locked window decides whether we need to put the wallpaper
+ // behind.
+ needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
+ || (w.mActivityRecord != null && !w.mActivityRecord.fillsParent());
+ }
}
if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {
@@ -288,6 +296,11 @@ class WallpaperController {
&& (mWallpaperTarget != winGoingAway || mPrevWallpaperTarget != null)) {
return;
}
+ if (mFindResults.useTopWallpaperAsTarget) {
+ // wallpaper target is going away but there has request to use top wallpaper
+ // Keep wallpaper visible.
+ return;
+ }
for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
final WallpaperWindowToken token = mWallpaperTokens.get(i);
token.setVisibility(false);
diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
index b6d668dde9d8..34b9913c9738 100644
--- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java
+++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
@@ -87,12 +87,12 @@ public class WindowAnimationSpec implements AnimationSpec {
@Override
public boolean getShowBackground() {
- return mAnimation.getShowBackground();
+ return mAnimation.getShowBackdrop();
}
@Override
public int getBackgroundColor() {
- return mAnimation.getBackgroundColor();
+ return mAnimation.getBackdropColor();
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 99e7817d22ce..77d31df0bee7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -181,7 +181,6 @@ import android.hardware.configstore.V1_1.ISurfaceFlingerConfigs;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.input.InputManager;
-import android.hardware.input.InputManagerInternal;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -256,7 +255,6 @@ import android.view.IWindowSessionCallback;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
import android.view.InputDevice;
-import android.view.InputEvent;
import android.view.InputWindowHandle;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
@@ -2639,7 +2637,17 @@ public class WindowManagerService extends IWindowManager.Stub
void updateWindowLayout(Session session, IWindow client, LayoutParams attrs, int flags,
ClientWindowFrames clientWindowFrames, int requestedWidth, int requestedHeight) {
- // TODO(b/161810301): Finish the implementation.
+ final long origId = Binder.clearCallingIdentity();
+ synchronized (mGlobalLock) {
+ final WindowState win = windowForClientLocked(session, client, false);
+ if (win == null) {
+ return;
+ }
+ win.setFrames(clientWindowFrames, requestedWidth, requestedHeight);
+
+ // TODO(b/161810301): Finish the implementation.
+ }
+ Binder.restoreCallingIdentity(origId);
}
public boolean outOfMemoryWindow(Session session, IWindow client) {
@@ -6305,8 +6313,6 @@ public class WindowManagerService extends IWindowManager.Stub
+ " callers=" + Debug.getCallers(3));
return NAV_BAR_INVALID;
}
- displayContent.performLayout(false /* initial */,
- false /* updateInputWindows */);
return displayContent.getDisplayPolicy().getNavBarPosition();
}
}
@@ -6968,17 +6974,13 @@ public class WindowManagerService extends IWindowManager.Stub
}
public void onOverlayChanged() {
- // Post to display thread so it can get the latest display info.
- mH.post(() -> {
- synchronized (mGlobalLock) {
- mAtmService.deferWindowLayout();
- try {
- mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().onOverlayChanged());
- } finally {
- mAtmService.continueWindowLayout();
- }
- }
- });
+ synchronized (mGlobalLock) {
+ mRoot.forAllDisplays(displayContent -> {
+ displayContent.getDisplayPolicy().onOverlayChangedLw();
+ displayContent.updateDisplayInfo();
+ });
+ requestTraversal();
+ }
}
@Override
@@ -8316,37 +8318,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public boolean injectInputAfterTransactionsApplied(InputEvent ev, int mode,
- boolean waitForAnimations) {
- boolean isDown;
- boolean isUp;
-
- if (ev instanceof KeyEvent) {
- KeyEvent keyEvent = (KeyEvent) ev;
- isDown = keyEvent.getAction() == KeyEvent.ACTION_DOWN;
- isUp = keyEvent.getAction() == KeyEvent.ACTION_UP;
- } else {
- MotionEvent motionEvent = (MotionEvent) ev;
- isDown = motionEvent.getAction() == MotionEvent.ACTION_DOWN;
- isUp = motionEvent.getAction() == MotionEvent.ACTION_UP;
- }
- final boolean isMouseEvent = ev.getSource() == InputDevice.SOURCE_MOUSE;
-
- // For ACTION_DOWN, syncInputTransactions before injecting input.
- // For all mouse events, also sync before injecting.
- // For ACTION_UP, sync after injecting.
- if (isDown || isMouseEvent) {
- syncInputTransactions(waitForAnimations);
- }
- final boolean result =
- LocalServices.getService(InputManagerInternal.class).injectInputEvent(ev, mode);
- if (isUp) {
- syncInputTransactions(waitForAnimations);
- }
- return result;
- }
-
- @Override
public void syncInputTransactions(boolean waitForAnimations) {
final long token = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 654c4602fe39..8546e8002602 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -33,6 +33,7 @@ import static android.view.InsetsState.ITYPE_INVALID;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.SurfaceControl.Transaction;
import static android.view.SurfaceControl.getGlobalTransaction;
+import static android.view.ViewRootImpl.LOCAL_LAYOUT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
@@ -249,6 +250,7 @@ import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.window.ClientWindowFrames;
import android.window.IOnBackInvokedCallback;
+import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.KeyInterceptionInfo;
@@ -1083,9 +1085,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
*/
void setOnBackInvokedCallback(
@Nullable IOnBackInvokedCallback onBackInvokedCallback, int priority) {
- ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "%s: Setting back callback %s. Client IWindow %s",
- this, onBackInvokedCallback, mClient);
- if (priority >= 0) {
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "WindowState: Setting back callback %s (priority: %d) "
+ + "(Client IWindow: %s). (WindowState: %s)",
+ onBackInvokedCallback, priority, mClient, this);
+ if (priority >= WindowOnBackInvokedDispatcher.PRIORITY_DEFAULT) {
mApplicationOnBackInvokedCallback = onBackInvokedCallback;
mSystemOnBackInvokedCallback = null;
} else {
@@ -1357,31 +1360,36 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mActivityRecord != null && mActivityRecord.mWaitForEnteringPinnedMode;
}
- // TODO(b/161810301): Make the frame be passed from the client side.
- void setFrames(ClientWindowFrames clientWindowFrames) {
- mHaveFrame = true;
-
+ void setFrames(ClientWindowFrames clientWindowFrames, int requestedWidth, int requestedHeight) {
final WindowFrames windowFrames = mWindowFrames;
mTmpRect.set(windowFrames.mParentFrame);
- windowFrames.mDisplayFrame.set(clientWindowFrames.displayFrame);
- windowFrames.mParentFrame.set(clientWindowFrames.parentFrame);
- windowFrames.mFrame.set(clientWindowFrames.frame);
- windowFrames.setParentFrameWasClippedByDisplayCutout(
- clientWindowFrames.isParentFrameClippedByDisplayCutout);
-
- if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight
- || !mTmpRect.equals(windowFrames.mParentFrame)) {
- mLastRequestedWidth = mRequestedWidth;
- mLastRequestedHeight = mRequestedHeight;
- windowFrames.setContentChanged(true);
- }
- windowFrames.mCompatFrame.set(windowFrames.mFrame);
- if (hasCompatScale()) {
- // Also the scaled frame that we report to the app needs to be
- // adjusted to be in its coordinate space.
- windowFrames.mCompatFrame.scale(mInvGlobalScale);
+ if (LOCAL_LAYOUT) {
+ windowFrames.mCompatFrame.set(clientWindowFrames.frame);
+
+ windowFrames.mFrame.set(clientWindowFrames.frame);
+ windowFrames.mDisplayFrame.set(clientWindowFrames.displayFrame);
+ windowFrames.mParentFrame.set(clientWindowFrames.parentFrame);
+ if (hasCompatScale()) {
+ // The frames sent from the client need to be adjusted to the real coordinate space.
+ windowFrames.mFrame.scale(mGlobalScale);
+ windowFrames.mDisplayFrame.scale(mGlobalScale);
+ windowFrames.mParentFrame.scale(mGlobalScale);
+ }
+ } else {
+ windowFrames.mDisplayFrame.set(clientWindowFrames.displayFrame);
+ windowFrames.mParentFrame.set(clientWindowFrames.parentFrame);
+ windowFrames.mFrame.set(clientWindowFrames.frame);
+
+ windowFrames.mCompatFrame.set(windowFrames.mFrame);
+ if (hasCompatScale()) {
+ // Also, the scaled frame that we report to the app needs to be adjusted to be in
+ // its coordinate space.
+ windowFrames.mCompatFrame.scale(mInvGlobalScale);
+ }
}
+ windowFrames.setParentFrameWasClippedByDisplayCutout(
+ clientWindowFrames.isParentFrameClippedByDisplayCutout);
// Calculate relative frame
windowFrames.mRelFrame.set(windowFrames.mFrame);
@@ -1399,6 +1407,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
windowFrames.mRelFrame.offsetTo(windowFrames.mFrame.left - parentLeft,
windowFrames.mFrame.top - parentTop);
+ if (requestedWidth != mLastRequestedWidth || requestedHeight != mLastRequestedHeight
+ || !mTmpRect.equals(windowFrames.mParentFrame)) {
+ mLastRequestedWidth = requestedWidth;
+ mLastRequestedHeight = requestedHeight;
+ windowFrames.setContentChanged(true);
+ }
+
if (mAttrs.type == TYPE_DOCK_DIVIDER) {
if (!windowFrames.mFrame.equals(windowFrames.mLastFrame)) {
mMovedByResize = true;
@@ -1414,6 +1429,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
updateSourceFrame(windowFrames.mFrame);
+
+ if (LOCAL_LAYOUT) {
+ if (!mHaveFrame) {
+ // The first frame should not be considered as moved.
+ updateLastFrames();
+ }
+ }
+
+ if (mActivityRecord != null && !mIsChildWindow) {
+ mActivityRecord.layoutLetterbox(this);
+ }
+ mSurfacePlacementNeeded = true;
+ mHaveFrame = true;
}
void updateSourceFrame(Rect winFrame) {
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 31b557949e36..17016a6eb314 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -106,7 +106,6 @@ static struct {
jmethodID interceptMotionBeforeQueueingNonInteractive;
jmethodID interceptKeyBeforeDispatching;
jmethodID dispatchUnhandledKey;
- jmethodID checkInjectEventsPermission;
jmethodID onPointerDownOutsideFocus;
jmethodID getVirtualKeyQuietTimeMillis;
jmethodID getExcludedDeviceNames;
@@ -329,7 +328,6 @@ public:
bool dispatchUnhandledKey(const sp<IBinder>& token, const KeyEvent* keyEvent,
uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) override;
void pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) override;
- bool checkInjectEventsPermissionNonReentrant(int32_t injectorPid, int32_t injectorUid) override;
void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) override;
void setPointerCapture(const PointerCaptureRequest& request) override;
void notifyDropWindow(const sp<IBinder>& token, float x, float y) override;
@@ -1368,18 +1366,6 @@ void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType,
android_server_PowerManagerService_userActivity(eventTime, eventType, displayId);
}
-bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
- int32_t injectorPid, int32_t injectorUid) {
- ATRACE_CALL();
- JNIEnv* env = jniEnv();
- jboolean result = env->CallBooleanMethod(mServiceObj,
- gServiceClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
- if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
- result = false;
- }
- return result;
-}
-
void NativeInputManager::onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) {
ATRACE_CALL();
JNIEnv* env = jniEnv();
@@ -1706,11 +1692,12 @@ static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jclass /* clazz */,
static_cast<BlockUntrustedTouchesMode>(mode));
}
-static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
- jlong ptr, jobject inputEventObj, jint injectorPid, jint injectorUid,
- jint syncMode, jint timeoutMillis, jint policyFlags) {
+static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, jlong ptr,
+ jobject inputEventObj, jboolean injectIntoUid, jint uid,
+ jint syncMode, jint timeoutMillis, jint policyFlags) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+ const std::optional<int32_t> targetUid = injectIntoUid ? std::make_optional(uid) : std::nullopt;
// static_cast is safe because the value was already checked at the Java layer
InputEventInjectionSync mode = static_cast<InputEventInjectionSync>(syncMode);
@@ -1723,8 +1710,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
}
const InputEventInjectionResult result =
- im->getInputManager()->getDispatcher().injectInputEvent(&keyEvent, injectorPid,
- injectorUid, mode,
+ im->getInputManager()->getDispatcher().injectInputEvent(&keyEvent, targetUid, mode,
std::chrono::milliseconds(
timeoutMillis),
uint32_t(policyFlags));
@@ -1737,8 +1723,8 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
}
const InputEventInjectionResult result =
- im->getInputManager()->getDispatcher().injectInputEvent(motionEvent, injectorPid,
- injectorUid, mode,
+ im->getInputManager()->getDispatcher().injectInputEvent(motionEvent, targetUid,
+ mode,
std::chrono::milliseconds(
timeoutMillis),
uint32_t(policyFlags));
@@ -2359,7 +2345,7 @@ static const JNINativeMethod gInputManagerMethods[] = {
{"nativeSetMaximumObscuringOpacityForTouch", "(JF)V",
(void*)nativeSetMaximumObscuringOpacityForTouch},
{"nativeSetBlockUntrustedTouchesMode", "(JI)V", (void*)nativeSetBlockUntrustedTouchesMode},
- {"nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I",
+ {"nativeInjectInputEvent", "(JLandroid/view/InputEvent;ZIIII)I",
(void*)nativeInjectInputEvent},
{"nativeVerifyInputEvent", "(JLandroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
(void*)nativeVerifyInputEvent},
@@ -2499,9 +2485,6 @@ int register_android_server_InputManager(JNIEnv* env) {
"dispatchUnhandledKey",
"(Landroid/os/IBinder;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
- GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz,
- "checkInjectEventsPermission", "(II)Z");
-
GET_METHOD_ID(gServiceClassInfo.onPointerDownOutsideFocus, clazz,
"onPointerDownOutsideFocus", "(Landroid/os/IBinder;)V");
diff --git a/services/core/jni/gnss/Gnss.cpp b/services/core/jni/gnss/Gnss.cpp
index f6459eaa444e..8934c3a6abde 100644
--- a/services/core/jni/gnss/Gnss.cpp
+++ b/services/core/jni/gnss/Gnss.cpp
@@ -170,7 +170,15 @@ jboolean GnssHal::isSupported() {
}
void GnssHal::linkToDeath() {
- // TODO: linkToDeath for AIDL HAL
+ if (gnssHalAidl != nullptr) {
+ gnssHalDeathRecipientAidl = new GnssDeathRecipientAidl();
+ status_t linked = IInterface::asBinder(gnssHalAidl)->linkToDeath(gnssHalDeathRecipientAidl);
+ if (linked != OK) {
+ ALOGE("Unable to link to GNSS AIDL HAL death notification");
+ } else {
+ ALOGD("Successfully linked to GNSS AIDL HAl death notification");
+ }
+ }
if (gnssHal != nullptr) {
gnssHalDeathRecipient = new GnssDeathRecipient();
diff --git a/services/core/jni/gnss/Gnss.h b/services/core/jni/gnss/Gnss.h
index c6743d62af45..458da8a6e514 100644
--- a/services/core/jni/gnss/Gnss.h
+++ b/services/core/jni/gnss/Gnss.h
@@ -28,6 +28,7 @@
#include <android/hardware/gnss/2.0/IGnss.h>
#include <android/hardware/gnss/2.1/IGnss.h>
#include <android/hardware/gnss/BnGnss.h>
+#include <binder/IBinder.h>
#include <log/log.h>
#include "AGnss.h"
@@ -50,13 +51,24 @@ namespace android::gnss {
struct GnssDeathRecipient : virtual public hardware::hidl_death_recipient {
// hidl_death_recipient interface
virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override {
- ALOGE("IGNSS hidl service failed, trying to recover...");
+ ALOGE("GNSS HIDL service failed, trying to recover...");
+ onServiceDied();
+ }
+ static void onServiceDied() {
JNIEnv* env = android::AndroidRuntime::getJNIEnv();
env->CallVoidMethod(android::mCallbacksObj, method_reportGnssServiceDied);
}
};
+struct GnssDeathRecipientAidl : virtual public IBinder::DeathRecipient {
+ // IBinder::DeathRecipient implementation
+ virtual void binderDied(const wp<IBinder>& who) override {
+ ALOGE("GNSS AIDL service failed, trying to recover...");
+ GnssDeathRecipient::onServiceDied();
+ }
+};
+
class GnssHal {
public:
GnssHal();
@@ -109,6 +121,7 @@ public:
private:
sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
+ sp<GnssDeathRecipientAidl> gnssHalDeathRecipientAidl = nullptr;
sp<hardware::gnss::V1_0::IGnss> gnssHal = nullptr;
sp<hardware::gnss::V1_1::IGnss> gnssHal_V1_1 = nullptr;
sp<hardware::gnss::V2_0::IGnss> gnssHal_V2_0 = nullptr;
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 5b4febda62ef..0e9a04f1fdde 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -26,7 +26,7 @@
<xs:element name="displayConfiguration">
<xs:complexType>
<xs:sequence>
- <xs:element type="densityMap" name="densityMap" minOccurs="0" maxOccurs="1">
+ <xs:element type="densityMapping" name="densityMapping" minOccurs="0" maxOccurs="1">
<xs:annotation name="nullable"/>
<xs:annotation name="final"/>
</xs:element>
@@ -281,7 +281,7 @@
</xs:sequence>
</xs:complexType>
- <xs:complexType name="densityMap">
+ <xs:complexType name="densityMapping">
<xs:sequence>
<xs:element name="density" type="density" maxOccurs="unbounded" minOccurs="1">
</xs:element>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index ba83c9fbcf91..075edd77af1d 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -30,8 +30,8 @@ package com.android.server.display.config {
method public final void setWidth(@NonNull java.math.BigInteger);
}
- public class DensityMap {
- ctor public DensityMap();
+ public class DensityMapping {
+ ctor public DensityMapping();
method public java.util.List<com.android.server.display.config.Density> getDensity();
}
@@ -40,7 +40,7 @@ package com.android.server.display.config {
method @NonNull public final com.android.server.display.config.Thresholds getAmbientBrightnessChangeThresholds();
method public final java.math.BigInteger getAmbientLightHorizonLong();
method public final java.math.BigInteger getAmbientLightHorizonShort();
- method @Nullable public final com.android.server.display.config.DensityMap getDensityMap();
+ method @Nullable public final com.android.server.display.config.DensityMapping getDensityMapping();
method @NonNull public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholds();
method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode();
method public final com.android.server.display.config.SensorDetails getLightSensor();
@@ -56,7 +56,7 @@ package com.android.server.display.config {
method public final void setAmbientBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
method public final void setAmbientLightHorizonLong(java.math.BigInteger);
method public final void setAmbientLightHorizonShort(java.math.BigInteger);
- method public final void setDensityMap(@Nullable com.android.server.display.config.DensityMap);
+ method public final void setDensityMapping(@Nullable com.android.server.display.config.DensityMapping);
method public final void setDisplayBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
method public final void setLightSensor(com.android.server.display.config.SensorDetails);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2b64be283b36..62447c071c63 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -13354,8 +13354,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (receivers.isEmpty()) {
return;
}
- packageIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- mContext.sendBroadcastAsUser(packageIntent, userHandle);
+ for (ResolveInfo receiver : receivers) {
+ final Intent componentIntent = new Intent(packageIntent)
+ .setComponent(receiver.getComponentInfo().getComponentName())
+ .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ mContext.sendBroadcastAsUser(componentIntent, userHandle);
+ }
} catch (RemoteException ex) {
Slogf.w(LOG_TAG, "Cannot get list of broadcast receivers for %s because: %s.",
intent.getAction(), ex);
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index e1fe1d8433ef..90fd8edacce3 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -685,11 +685,13 @@ public class MidiService extends IMidiManager.Stub {
private boolean hasNonMidiUuids(BluetoothDevice btDevice) {
ParcelUuid[] uuidParcels = btDevice.getUuids();
- // The assumption is that these services are indicative of devices that
- // ARE NOT MIDI devices.
- for (ParcelUuid parcel : uuidParcels) {
- if (mNonMidiUUIDs.contains(parcel)) {
- return true;
+ if (uuidParcels != null) {
+ // The assumption is that these services are indicative of devices that
+ // ARE NOT MIDI devices.
+ for (ParcelUuid parcel : uuidParcels) {
+ if (mNonMidiUUIDs.contains(parcel)) {
+ return true;
+ }
}
}
return false;
diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
index 7b152247eb9c..7017440a86bb 100644
--- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
+++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
@@ -34,6 +34,7 @@ import com.android.server.pm.test.override.PackageManagerComponentLabelIconOverr
import com.android.server.testutils.TestHandler
import com.android.server.testutils.mock
import com.android.server.testutils.mockThrowOnUnmocked
+import com.android.server.testutils.spy
import com.android.server.testutils.whenever
import com.android.server.wm.ActivityTaskManagerInternal
import com.google.common.truth.Truth.assertThat
@@ -45,9 +46,13 @@ import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.intThat
+import org.mockito.Mockito.never
import org.mockito.Mockito.same
+import org.mockito.Mockito.verify
import org.testng.Assert.assertThrows
import java.io.File
import java.util.UUID
@@ -360,7 +365,7 @@ class PackageManagerComponentLabelIconOverrideTest {
val mockActivityTaskManager: ActivityTaskManagerInternal = mockThrowOnUnmocked {
whenever(this.isCallerRecents(anyInt())) { false }
}
- val mockAppsFilter: AppsFilterImpl = mockThrowOnUnmocked {
+ val mockAppsFilter: AppsFilter = mockThrowOnUnmocked {
whenever(this.shouldFilterApplication(anyInt(), any<PackageSetting>(),
any<PackageSetting>(), anyInt())) { false }
whenever(this.snapshot()) { this@mockThrowOnUnmocked }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index 47b715ebd7c0..c0b4f0fe5812 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -36,11 +36,15 @@ import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_FINE_LOCATION;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_SYSTEM;
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_MASK;
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
+import static android.app.usage.UsageStatsManager.REASON_SUB_DEFAULT_UNDEFINED;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_USER_FLAG_INTERACTION;
+import static android.app.usage.UsageStatsManager.REASON_SUB_MASK;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_USER_INTERACTION;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_EXEMPTED;
@@ -93,6 +97,7 @@ import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal.AppBackgroundRestrictionListener;
import android.app.ActivityManagerInternal.BindServiceEventListener;
@@ -146,6 +151,7 @@ import com.android.server.am.AppFGSTracker.AppFGSPolicy;
import com.android.server.am.AppMediaSessionTracker.AppMediaSessionPolicy;
import com.android.server.am.AppRestrictionController.ConstantsObserver;
import com.android.server.am.AppRestrictionController.NotificationHelper;
+import com.android.server.am.AppRestrictionController.RestrictionSettings;
import com.android.server.am.AppRestrictionController.UidBatteryUsageProvider;
import com.android.server.am.BaseAppStateTimeEvents.BaseTimeEvent;
import com.android.server.apphibernation.AppHibernationManagerInternal;
@@ -165,6 +171,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.verification.VerificationMode;
+import java.io.File;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -356,6 +363,7 @@ public final class BackgroundRestrictionTest {
verify(mAppBindServiceEventsTracker.mInjector.getActivityManagerInternal())
.addBindServiceEventListener(mBindServiceEventListenerCap.capture());
mBindServiceEventListener = mBindServiceEventListenerCap.getValue();
+ waitForIdleHandler(mBgRestrictionController.getBackgroundHandler());
}
@After
@@ -663,7 +671,7 @@ public final class BackgroundRestrictionTest {
mAppFGSTracker.onForegroundServiceStateChanged(testPkgName, testUid,
testPid, true);
mAppFGSTracker.onForegroundServiceNotificationUpdated(
- testPkgName, testUid, notificationId);
+ testPkgName, testUid, notificationId, false);
mAppFGSTracker.mNotificationListener.onNotificationPosted(new StatusBarNotification(
testPkgName, null, notificationId, null, testUid, testPid,
new Notification(), UserHandle.of(testUser), null, mCurrentTimeMillis), null);
@@ -840,7 +848,7 @@ public final class BackgroundRestrictionTest {
// Pretend we have the notification dismissed.
mAppFGSTracker.onForegroundServiceNotificationUpdated(
- testPkgName, testUid, -notificationId);
+ testPkgName, testUid, notificationId, true);
clearInvocations(mInjector.getAppStandbyInternal());
clearInvocations(mInjector.getNotificationManager());
clearInvocations(mBgRestrictionController);
@@ -877,7 +885,7 @@ public final class BackgroundRestrictionTest {
// Pretend notification is back on.
mAppFGSTracker.onForegroundServiceNotificationUpdated(
- testPkgName, testUid, notificationId);
+ testPkgName, testUid, notificationId, false);
// Now we'll prompt the user even it has a FGS with notification.
bgPromptFgsWithNotiToBgRestricted.set(true);
clearInvocations(mInjector.getAppStandbyInternal());
@@ -1216,7 +1224,7 @@ public final class BackgroundRestrictionTest {
mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
testPid1, true);
mAppFGSTracker.onForegroundServiceNotificationUpdated(
- testPkgName1, testUid1, fgsNotificationId);
+ testPkgName1, testUid1, fgsNotificationId, false);
mAppFGSTracker.mNotificationListener.onNotificationPosted(new StatusBarNotification(
testPkgName1, null, fgsNotificationId, null, testUid1, testPid1,
new Notification(), UserHandle.of(testUser1), null, mCurrentTimeMillis), null);
@@ -1227,7 +1235,7 @@ public final class BackgroundRestrictionTest {
// Pretend we have the notification dismissed.
mAppFGSTracker.onForegroundServiceNotificationUpdated(
- testPkgName1, testUid1, -fgsNotificationId);
+ testPkgName1, testUid1, fgsNotificationId, true);
// Verify we have the notification.
notificationId = checkNotificationShown(
@@ -1492,7 +1500,7 @@ public final class BackgroundRestrictionTest {
if (withNotification) {
final int notificationId = 1000;
mAppFGSTracker.onForegroundServiceNotificationUpdated(
- packageName, uid, notificationId);
+ packageName, uid, notificationId, false);
final StatusBarNotification noti = new StatusBarNotification(
packageName, null, notificationId, null, uid, pid,
new Notification(), UserHandle.of(UserHandle.getUserId(uid)),
@@ -2788,6 +2796,96 @@ public final class BackgroundRestrictionTest {
new double[] {10.0d, 1.0d, 12.0d, 1.0d, 18.0d, 1.0d})));
}
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testPersistRestrictionSettings() throws Exception {
+ final RestrictionSettings settings = mBgRestrictionController.mRestrictionSettings;
+ final String testPkg0 = TEST_PACKAGE_BASE + 0;
+ final String testPkg1 = TEST_PACKAGE_BASE + 1;
+ final String testPkg2 = TEST_PACKAGE_BASE + 2;
+ final String testPkg3 = TEST_PACKAGE_BASE + 3;
+ final int testUid0 = UserHandle.getUid(TEST_USER0, TEST_PACKAGE_APPID_BASE + 0);
+ final int testUid1 = UserHandle.getUid(TEST_USER0, TEST_PACKAGE_APPID_BASE + 1);
+ final int testUid2 = UserHandle.getUid(TEST_USER1, TEST_PACKAGE_APPID_BASE + 2);
+ final int testUid3 = UserHandle.getUid(TEST_USER1, TEST_PACKAGE_APPID_BASE + 3);
+ settings.reset();
+ setRestrictionSettings(settings, testPkg0, testUid0,
+ RESTRICTION_LEVEL_ADAPTIVE_BUCKET,
+ 10_000L, REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_UNDEFINED,
+ new long[] {0L, 0L}, false);
+ setRestrictionSettings(settings, testPkg1, testUid1,
+ RESTRICTION_LEVEL_RESTRICTED_BUCKET,
+ 20_000L, REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE,
+ new long[] {10_000L, 0L}, false);
+ setRestrictionSettings(settings, testPkg2, testUid2,
+ RESTRICTION_LEVEL_BACKGROUND_RESTRICTED,
+ 25_000L, REASON_MAIN_FORCED_BY_USER | REASON_SUB_FORCED_USER_FLAG_INTERACTION,
+ new long[] {0L, 15_000L}, false);
+ setRestrictionSettings(settings, testPkg3, testUid3,
+ RESTRICTION_LEVEL_RESTRICTED_BUCKET,
+ 30_000L, REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_UNDEFINED,
+ new long[] {0L, 0L}, false);
+ RestrictionSettings test = (RestrictionSettings) settings.clone();
+
+ // Verify our clone works correctly.
+ assertTrue(settings.equals(test));
+
+ // Reset the test object.
+ test.resetToDefault();
+
+ // Save the original data into xml.
+ settings.persistToXml(TEST_USER0);
+ settings.persistToXml(TEST_USER1);
+
+ // Load it to our test object.
+ test.loadFromXml(false);
+ // Verify we restored it correctly.
+ assertTrue(settings.equals(test));
+
+ // Remove one package.
+ settings.removePackage(testPkg3, testUid3);
+ // Verify it.
+ verifyLoadedSettings(settings);
+
+ // Add it back.
+ setRestrictionSettings(settings, testPkg3, testUid3,
+ RESTRICTION_LEVEL_RESTRICTED_BUCKET,
+ 30_000L, REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_UNDEFINED,
+ new long[] {0L, 1_000L}, true);
+ // Verify it.
+ verifyLoadedSettings(settings);
+
+ // Remove one user.
+ settings.removeUser(TEST_USER1);
+ // Verify it.
+ verifyLoadedSettings(settings);
+ }
+
+ private void verifyLoadedSettings(RestrictionSettings settings) throws Exception {
+ // Make a new copy and reset it.
+ RestrictionSettings test = (RestrictionSettings) settings.clone();
+ test.resetToDefault();
+
+ // Wait for the idleness so the data is persisted.
+ waitForIdleHandler(mBgRestrictionController.getBackgroundHandler());
+ // Load it to our test object.
+ test.loadFromXml(false);
+ // Verify we restored it correctly.
+ assertTrue(settings.equals(test));
+ }
+
+ @SuppressWarnings("GuardedBy")
+ private void setRestrictionSettings(RestrictionSettings settings, String pkgName, int uid,
+ int level, long levelTs, int reason, long[] notificationTime, boolean persist) {
+ mCurrentTimeMillis = levelTs;
+ settings.update(pkgName, uid, level, reason & REASON_MAIN_MASK, reason & REASON_SUB_MASK);
+ final RestrictionSettings.PkgSettings pkgSettings = settings.getRestrictionSettingsLocked(
+ uid, pkgName);
+ for (int i = 0; i < notificationTime.length; i++) {
+ pkgSettings.setLastNotificationTime(i, notificationTime[i], persist);
+ }
+ }
+
private LinkedList<UidStateEventWithBattery> createUidStateEventWithBatteryList(
boolean[] isStart, long[] timestamps, double[] batteryUsage) {
final LinkedList<UidStateEventWithBattery> result = new LinkedList<>();
@@ -2948,6 +3046,21 @@ public final class BackgroundRestrictionTest {
void scheduleInitTrackers(Handler handler, Runnable initializers) {
initializers.run();
}
+
+ @Override
+ File getDataSystemDeDirectory(@UserIdInt int userId) {
+ return new File(mContext.getFilesDir(), Integer.toString(userId));
+ }
+
+ @Override
+ long currentTimeMillis() {
+ return mCurrentTimeMillis;
+ }
+
+ @Override
+ boolean isTest() {
+ return true;
+ }
}
private class TestBaseTrackerInjector<T extends BaseAppStatePolicy>
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
index 023608c68ee3..09565b42e515 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -231,6 +231,14 @@ public class GameManagerServiceTests {
.thenReturn(configString);
}
+ // Loading boost will be disabled for most apps, so treat enabling loading boost as a special
+ // case.
+ private void mockDeviceConfigPerformanceEnableLoadingBoost() {
+ String configString = "mode=2,downscaleFactor=0.5,loadingBoost=0";
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configString);
+ }
+
private void mockDeviceConfigBattery() {
String configString = "mode=3,downscaleFactor=0.7,fps=30";
when(DeviceConfig.getProperty(anyString(), anyString()))
@@ -566,6 +574,21 @@ public class GameManagerServiceTests {
assertEquals(gameManagerService.isAngleEnabled(mPackageName, USER_ID_1), angleEnabled);
}
+ private void checkLoadingBoost(GameManagerService gameManagerService, int gameMode,
+ int loadingBoost) {
+ gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+
+ // Validate GamePackageConfiguration returns the correct value.
+ GameManagerService.GamePackageConfiguration config =
+ gameManagerService.getConfig(mPackageName);
+ assertEquals(
+ loadingBoost, config.getGameModeConfiguration(gameMode).getLoadingBoostDuration());
+
+ // Validate GameManagerService.getLoadingBoostDuration() returns the correct value.
+ assertEquals(
+ loadingBoost, gameManagerService.getLoadingBoostDuration(mPackageName, USER_ID_1));
+ }
+
private void checkFps(GameManagerService gameManagerService, int gameMode, int fps) {
if (gameManagerService == null) {
gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper());
@@ -922,6 +945,21 @@ public class GameManagerServiceTests {
}
/**
+ * PERFORMANCE game mode is configured through Phenotype. The app hasn't specified any
+ * metadata.
+ */
+ @Test
+ public void testInterventionAllowLoadingBoostDefault() throws Exception {
+ GameManagerService gameManagerService = new GameManagerService(
+ mMockContext, mTestLooper.getLooper());
+
+ startUser(gameManagerService, USER_ID_1);
+ mockDeviceConfigPerformance();
+ mockModifyGameModeGranted();
+ checkLoadingBoost(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, -1);
+ }
+
+ /**
* PERFORMANCE game mode is configured through Phenotype. The app has opted-out of ANGLE.
*/
@Test
@@ -955,6 +993,25 @@ public class GameManagerServiceTests {
checkAngleEnabled(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, true);
}
+ /**
+ * PERFORMANCE game mode is configured through Phenotype. The app has redundantly specified the
+ * Loading Boost metadata default value of "true".
+ */
+ @Test
+ public void testInterventionAllowLoadingBoost() throws Exception {
+ mockDeviceConfigPerformanceEnableLoadingBoost();
+
+ GameManagerService gameManagerService =
+ new GameManagerService(mMockContext, mTestLooper.getLooper());
+ startUser(gameManagerService, USER_ID_1);
+ mockModifyGameModeGranted();
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_PERFORMANCE,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+ mockInterventionsEnabledFromXml();
+ checkLoadingBoost(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
+ }
+
@Test
public void testGameModeConfigAllowFpsTrue() throws Exception {
mockDeviceConfigAll();
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DensityMapTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DensityMappingTest.java
index 3f69f1b723e3..ae7a2a40d195 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DensityMapTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DensityMappingTest.java
@@ -16,7 +16,7 @@
package com.android.server.display;
-import static com.android.server.display.DensityMap.Entry;
+import static com.android.server.display.DensityMapping.Entry;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
@@ -29,37 +29,37 @@ import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class DensityMapTest {
+public class DensityMappingTest {
@Test
public void testConstructor_withBadConfig_throwsException() {
assertThrows(IllegalStateException.class, () ->
- DensityMap.createByOwning(new Entry[]{
+ DensityMapping.createByOwning(new Entry[]{
new Entry(1080, 1920, 320),
new Entry(1080, 1920, 320)})
);
assertThrows(IllegalStateException.class, () ->
- DensityMap.createByOwning(new Entry[]{
+ DensityMapping.createByOwning(new Entry[]{
new Entry(1080, 1920, 320),
new Entry(1920, 1080, 120)})
);
assertThrows(IllegalStateException.class, () ->
- DensityMap.createByOwning(new Entry[]{
+ DensityMapping.createByOwning(new Entry[]{
new Entry(1080, 1920, 320),
new Entry(2160, 3840, 120)})
);
assertThrows(IllegalStateException.class, () ->
- DensityMap.createByOwning(new Entry[]{
+ DensityMapping.createByOwning(new Entry[]{
new Entry(1080, 1920, 320),
new Entry(3840, 2160, 120)})
);
// Two entries with the same diagonal
assertThrows(IllegalStateException.class, () ->
- DensityMap.createByOwning(new Entry[]{
+ DensityMapping.createByOwning(new Entry[]{
new Entry(500, 500, 123),
new Entry(100, 700, 456)})
);
@@ -67,77 +67,77 @@ public class DensityMapTest {
@Test
public void testGetDensityForResolution_withResolutionMatch_returnsDensityFromConfig() {
- DensityMap densityMap = DensityMap.createByOwning(new Entry[]{
+ DensityMapping densityMapping = DensityMapping.createByOwning(new Entry[]{
new Entry(720, 1280, 213),
new Entry(1080, 1920, 320),
new Entry(2160, 3840, 640)});
- assertEquals(213, densityMap.getDensityForResolution(720, 1280));
- assertEquals(213, densityMap.getDensityForResolution(1280, 720));
+ assertEquals(213, densityMapping.getDensityForResolution(720, 1280));
+ assertEquals(213, densityMapping.getDensityForResolution(1280, 720));
- assertEquals(320, densityMap.getDensityForResolution(1080, 1920));
- assertEquals(320, densityMap.getDensityForResolution(1920, 1080));
+ assertEquals(320, densityMapping.getDensityForResolution(1080, 1920));
+ assertEquals(320, densityMapping.getDensityForResolution(1920, 1080));
- assertEquals(640, densityMap.getDensityForResolution(2160, 3840));
- assertEquals(640, densityMap.getDensityForResolution(3840, 2160));
+ assertEquals(640, densityMapping.getDensityForResolution(2160, 3840));
+ assertEquals(640, densityMapping.getDensityForResolution(3840, 2160));
}
@Test
public void testGetDensityForResolution_withDiagonalMatch_returnsDensityFromConfig() {
- DensityMap densityMap = DensityMap.createByOwning(
+ DensityMapping densityMapping = DensityMapping.createByOwning(
new Entry[]{ new Entry(500, 500, 123)});
// 500x500 has the same diagonal as 100x700
- assertEquals(123, densityMap.getDensityForResolution(100, 700));
+ assertEquals(123, densityMapping.getDensityForResolution(100, 700));
}
@Test
public void testGetDensityForResolution_withOneEntry_withNoMatch_returnsExtrapolatedDensity() {
- DensityMap densityMap = DensityMap.createByOwning(
+ DensityMapping densityMapping = DensityMapping.createByOwning(
new Entry[]{ new Entry(1080, 1920, 320)});
- assertEquals(320, densityMap.getDensityForResolution(1081, 1920));
- assertEquals(320, densityMap.getDensityForResolution(1080, 1921));
+ assertEquals(320, densityMapping.getDensityForResolution(1081, 1920));
+ assertEquals(320, densityMapping.getDensityForResolution(1080, 1921));
- assertEquals(640, densityMap.getDensityForResolution(2160, 3840));
- assertEquals(640, densityMap.getDensityForResolution(3840, 2160));
+ assertEquals(640, densityMapping.getDensityForResolution(2160, 3840));
+ assertEquals(640, densityMapping.getDensityForResolution(3840, 2160));
- assertEquals(213, densityMap.getDensityForResolution(720, 1280));
- assertEquals(213, densityMap.getDensityForResolution(1280, 720));
+ assertEquals(213, densityMapping.getDensityForResolution(720, 1280));
+ assertEquals(213, densityMapping.getDensityForResolution(1280, 720));
}
@Test
public void testGetDensityForResolution_withTwoEntries_withNoMatch_returnExtrapolatedDensity() {
- DensityMap densityMap = DensityMap.createByOwning(new Entry[]{
+ DensityMapping densityMapping = DensityMapping.createByOwning(new Entry[]{
new Entry(1080, 1920, 320),
new Entry(2160, 3840, 320)});
// Resolution is smaller than all entries
- assertEquals(213, densityMap.getDensityForResolution(720, 1280));
- assertEquals(213, densityMap.getDensityForResolution(1280, 720));
+ assertEquals(213, densityMapping.getDensityForResolution(720, 1280));
+ assertEquals(213, densityMapping.getDensityForResolution(1280, 720));
// Resolution is bigger than all entries
- assertEquals(320 * 2, densityMap.getDensityForResolution(2160 * 2, 3840 * 2));
- assertEquals(320 * 2, densityMap.getDensityForResolution(3840 * 2, 2160 * 2));
+ assertEquals(320 * 2, densityMapping.getDensityForResolution(2160 * 2, 3840 * 2));
+ assertEquals(320 * 2, densityMapping.getDensityForResolution(3840 * 2, 2160 * 2));
}
@Test
public void testGetDensityForResolution_withNoMatch_returnsInterpolatedDensity() {
{
- DensityMap densityMap = DensityMap.createByOwning(new Entry[]{
+ DensityMapping densityMapping = DensityMapping.createByOwning(new Entry[]{
new Entry(1080, 1920, 320),
new Entry(2160, 3840, 320)});
- assertEquals(320, densityMap.getDensityForResolution(2000, 2000));
+ assertEquals(320, densityMapping.getDensityForResolution(2000, 2000));
}
{
- DensityMap densityMap = DensityMap.createByOwning(new Entry[]{
+ DensityMapping densityMapping = DensityMapping.createByOwning(new Entry[]{
new Entry(720, 1280, 213),
new Entry(2160, 3840, 640)});
- assertEquals(320, densityMap.getDensityForResolution(1080, 1920));
- assertEquals(320, densityMap.getDensityForResolution(1920, 1080));
+ assertEquals(320, densityMapping.getDensityForResolution(1080, 1920));
+ assertEquals(320, densityMapping.getDensityForResolution(1920, 1080));
}
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 9a4f8e261124..43ba39adcb85 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -2164,6 +2164,49 @@ public class QuotaControllerTest {
}
}
+ @Test
+ public void testIsWithinEJQuotaLocked_TempAllowlisting_Restricted() {
+ setDischarging();
+ JobStatus js = createExpeditedJobStatus("testIsWithinEJQuotaLocked_TempAllowlisting_Restricted", 1);
+ setStandbyBucket(RESTRICTED_INDEX, js);
+ setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_FREQUENT_MS, 10 * MINUTE_IN_MILLIS);
+ final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+ mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+ createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), true);
+ mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+ createTimingSession(now - (30 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), true);
+ mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+ createTimingSession(now - (5 * MINUTE_IN_MILLIS), 4 * MINUTE_IN_MILLIS, 5), true);
+ synchronized (mQuotaController.mLock) {
+ assertFalse(mQuotaController.isWithinEJQuotaLocked(js));
+ }
+
+ setProcessState(ActivityManager.PROCESS_STATE_RECEIVER);
+ final long gracePeriodMs = 15 * SECOND_IN_MILLIS;
+ setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TEMP_ALLOWLIST_MS, gracePeriodMs);
+ Handler handler = mQuotaController.getHandler();
+ spyOn(handler);
+
+ // The temp allowlist should not enable RESTRICTED apps' to schedule & start EJs if they're
+ // out of quota.
+ mTempAllowlistListener.onAppAdded(mSourceUid);
+ synchronized (mQuotaController.mLock) {
+ assertFalse(mQuotaController.isWithinEJQuotaLocked(js));
+ }
+ advanceElapsedClock(10 * SECOND_IN_MILLIS);
+ mTempAllowlistListener.onAppRemoved(mSourceUid);
+ advanceElapsedClock(10 * SECOND_IN_MILLIS);
+ // Still in grace period
+ synchronized (mQuotaController.mLock) {
+ assertFalse(mQuotaController.isWithinEJQuotaLocked(js));
+ }
+ advanceElapsedClock(6 * SECOND_IN_MILLIS);
+ // Out of grace period.
+ synchronized (mQuotaController.mLock) {
+ assertFalse(mQuotaController.isWithinEJQuotaLocked(js));
+ }
+ }
+
/**
* Tests that Timers properly track sessions when an app becomes top and is closed.
*/
@@ -5559,6 +5602,111 @@ public class QuotaControllerTest {
mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
}
+ @Test
+ public void testEJTimerTracking_TempAllowlisting_Restricted() {
+ setDischarging();
+ setProcessState(ActivityManager.PROCESS_STATE_RECEIVER);
+ final long gracePeriodMs = 15 * SECOND_IN_MILLIS;
+ setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TEMP_ALLOWLIST_MS, gracePeriodMs);
+ Handler handler = mQuotaController.getHandler();
+ spyOn(handler);
+
+ JobStatus job = createExpeditedJobStatus("testEJTimerTracking_TempAllowlisting_Restricted", 1);
+ setStandbyBucket(RESTRICTED_INDEX, job);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStartTrackingJobLocked(job, null);
+ }
+ assertNull(mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+ List<TimingSession> expected = new ArrayList<>();
+
+ long start = JobSchedulerService.sElapsedRealtimeClock.millis();
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.prepareForExecutionLocked(job);
+ }
+ advanceElapsedClock(10 * SECOND_IN_MILLIS);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStopTrackingJobLocked(job, job, true);
+ }
+ expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+ assertEquals(expected,
+ mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+ advanceElapsedClock(SECOND_IN_MILLIS);
+
+ // Job starts after app is added to temp allowlist and stops before removal.
+ start = JobSchedulerService.sElapsedRealtimeClock.millis();
+ mTempAllowlistListener.onAppAdded(mSourceUid);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStartTrackingJobLocked(job, null);
+ mQuotaController.prepareForExecutionLocked(job);
+ }
+ advanceElapsedClock(10 * SECOND_IN_MILLIS);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStopTrackingJobLocked(job, null, false);
+ }
+ expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+ assertEquals(expected,
+ mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+ // Job starts after app is added to temp allowlist and stops after removal,
+ // before grace period ends.
+ start = JobSchedulerService.sElapsedRealtimeClock.millis();
+ mTempAllowlistListener.onAppAdded(mSourceUid);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStartTrackingJobLocked(job, null);
+ mQuotaController.prepareForExecutionLocked(job);
+ }
+ advanceElapsedClock(10 * SECOND_IN_MILLIS);
+ mTempAllowlistListener.onAppRemoved(mSourceUid);
+ long elapsedGracePeriodMs = 2 * SECOND_IN_MILLIS;
+ advanceElapsedClock(elapsedGracePeriodMs);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStopTrackingJobLocked(job, null, false);
+ }
+ expected.add(createTimingSession(start, 12 * SECOND_IN_MILLIS, 1));
+ assertEquals(expected,
+ mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+ advanceElapsedClock(SECOND_IN_MILLIS);
+ elapsedGracePeriodMs += SECOND_IN_MILLIS;
+
+ // Job starts during grace period and ends after grace period ends
+ start = JobSchedulerService.sElapsedRealtimeClock.millis();
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStartTrackingJobLocked(job, null);
+ mQuotaController.prepareForExecutionLocked(job);
+ }
+ final long remainingGracePeriod = gracePeriodMs - elapsedGracePeriodMs;
+ advanceElapsedClock(remainingGracePeriod);
+ // Wait for handler to update Timer
+ // Can't directly evaluate the message because for some reason, the captured message returns
+ // the wrong 'what' even though the correct message goes to the handler and the correct
+ // path executes.
+ verify(handler, timeout(gracePeriodMs + 5 * SECOND_IN_MILLIS)).handleMessage(any());
+ advanceElapsedClock(10 * SECOND_IN_MILLIS);
+ expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS + remainingGracePeriod, 1));
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStopTrackingJobLocked(job, job, true);
+ }
+ assertEquals(expected,
+ mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+ // Job starts and runs completely after temp allowlist grace period.
+ advanceElapsedClock(10 * SECOND_IN_MILLIS);
+ start = JobSchedulerService.sElapsedRealtimeClock.millis();
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStartTrackingJobLocked(job, null);
+ mQuotaController.prepareForExecutionLocked(job);
+ }
+ advanceElapsedClock(10 * SECOND_IN_MILLIS);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStopTrackingJobLocked(job, job, true);
+ }
+ expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+ assertEquals(expected,
+ mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+ }
+
/**
* Tests that Timers properly track sessions when TOP state and temp allowlisting overlaps.
*/
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java
index cd70020f5c28..b76abe6c74aa 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java
@@ -84,6 +84,8 @@ public class FakeSettingsHelper extends SettingsHelper {
private final Setting mBackgroundThrottlePackageWhitelistSetting = new Setting(
Collections.emptySet());
private final Setting mGnssMeasurementsFullTrackingSetting = new Setting(Boolean.FALSE);
+ private final Setting mAdasPackageAllowlist = new Setting(
+ new PackageTagsList.Builder().build());
private final Setting mIgnoreSettingsAllowlist = new Setting(
new PackageTagsList.Builder().build());
private final Setting mBackgroundThrottleProximityAlertIntervalSetting = new Setting(
@@ -194,10 +196,29 @@ public class FakeSettingsHelper extends SettingsHelper {
}
@Override
+ public PackageTagsList getAdasAllowlist() {
+ return mAdasPackageAllowlist.getValue(PackageTagsList.class);
+ }
+
+ @Override
+ public void addAdasAllowlistChangedListener(GlobalSettingChangedListener listener) {
+ mAdasPackageAllowlist.addListener(listener);
+ }
+
+ @Override
+ public void removeAdasAllowlistChangedListener(GlobalSettingChangedListener listener) {
+ mAdasPackageAllowlist.removeListener(listener);
+ }
+
+ @Override
public PackageTagsList getIgnoreSettingsAllowlist() {
return mIgnoreSettingsAllowlist.getValue(PackageTagsList.class);
}
+ public void setAdasSettingsAllowlist(PackageTagsList newValue) {
+ mAdasPackageAllowlist.setValue(newValue);
+ }
+
public void setIgnoreSettingsAllowlist(PackageTagsList newValue) {
mIgnoreSettingsAllowlist.setValue(newValue);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
index d8f409dfce66..71cc65b484ee 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
@@ -1107,6 +1107,10 @@ public class LocationProviderManagerTest {
doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+ mInjector.getSettingsHelper().setAdasSettingsAllowlist(
+ new PackageTagsList.Builder().add(
+ IDENTITY.getPackageName()).build());
+
createManager(GPS_PROVIDER);
ILocationListener listener1 = createMockLocationListener();
@@ -1136,6 +1140,10 @@ public class LocationProviderManagerTest {
doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+ mInjector.getSettingsHelper().setAdasSettingsAllowlist(
+ new PackageTagsList.Builder().add(
+ IDENTITY.getPackageName()).build());
+
createManager(GPS_PROVIDER);
ILocationListener listener1 = createMockLocationListener();
@@ -1160,11 +1168,16 @@ public class LocationProviderManagerTest {
@Test
public void testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled() {
+ doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
+ doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
new PackageTagsList.Builder().add(
IDENTITY.getPackageName()).build());
- doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
- doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+
+ mInjector.getSettingsHelper().setAdasSettingsAllowlist(
+ new PackageTagsList.Builder().add(
+ IDENTITY.getPackageName()).build());
createManager(GPS_PROVIDER);
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 353c8e22cceb..0567f58b1bbe 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -194,7 +194,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
val packageParser: PackageParser2 = mock()
val keySetManagerService: KeySetManagerService = mock()
val packageAbiHelper: PackageAbiHelper = mock()
- val appsFilter: AppsFilterImpl = mock {
+ val appsFilter: AppsFilter = mock {
whenever(snapshot()) { this@mock }
}
val dexManager: DexManager = mock()
diff --git a/services/tests/servicestests/src/com/android/server/EntropyMixerTest.java b/services/tests/servicestests/src/com/android/server/EntropyMixerTest.java
index 58d6dae1637a..68dcc7d7fb50 100644
--- a/services/tests/servicestests/src/com/android/server/EntropyMixerTest.java
+++ b/services/tests/servicestests/src/com/android/server/EntropyMixerTest.java
@@ -16,26 +16,116 @@
package com.android.server;
+import static org.junit.Assert.assertArrayEquals;
+
import android.content.Context;
-import android.os.FileUtils;
import android.test.AndroidTestCase;
+import org.junit.Test;
+
import java.io.File;
+import java.nio.file.Files;
+import java.util.Arrays;
/**
* Tests for {@link com.android.server.EntropyMixer}
*/
public class EntropyMixerTest extends AndroidTestCase {
- public void testInitialWrite() throws Exception {
- File dir = getContext().getDir("testInitialWrite", Context.MODE_PRIVATE);
- File file = File.createTempFile("testInitialWrite", "dat", dir);
+ private static final int SEED_FILE_SIZE = EntropyMixer.SEED_FILE_SIZE;
+
+ private File dir;
+ private File seedFile;
+ private File randomReadDevice;
+ private File randomWriteDevice;
+
+ @Override
+ public void setUp() throws Exception {
+ dir = getContext().getDir("test", Context.MODE_PRIVATE);
+ seedFile = createTempFile(dir, "entropy.dat");
+ randomReadDevice = createTempFile(dir, "urandomRead");
+ randomWriteDevice = createTempFile(dir, "urandomWrite");
+ }
+
+ private File createTempFile(File dir, String prefix) throws Exception {
+ File file = File.createTempFile(prefix, null, dir);
file.deleteOnExit();
- assertEquals(0, FileUtils.readTextFile(file, 0, null).length());
+ return file;
+ }
+
+ private byte[] repeatByte(byte b, int length) {
+ byte[] data = new byte[length];
+ Arrays.fill(data, b);
+ return data;
+ }
+
+ // Test initializing the EntropyMixer when the seed file doesn't exist yet.
+ @Test
+ public void testInitFirstBoot() throws Exception {
+ seedFile.delete();
+
+ byte[] urandomInjectedData = repeatByte((byte) 0x01, SEED_FILE_SIZE);
+ Files.write(randomReadDevice.toPath(), urandomInjectedData);
- // The constructor has the side effect of writing to file
- new EntropyMixer(getContext(), "/dev/null", file.getCanonicalPath());
+ // The constructor should have the side effect of writing to
+ // randomWriteDevice and creating seedFile.
+ new EntropyMixer(getContext(), seedFile, randomReadDevice, randomWriteDevice);
+
+ // Since there was no old seed file, the data that was written to
+ // randomWriteDevice should contain only device-specific information.
+ assertTrue(isDeviceSpecificInfo(Files.readAllBytes(randomWriteDevice.toPath())));
+
+ // The seed file should have been created.
+ validateSeedFile(seedFile, new byte[0], urandomInjectedData);
+ }
+
+ // Test initializing the EntropyMixer when the seed file already exists.
+ @Test
+ public void testInitNonFirstBoot() throws Exception {
+ byte[] previousSeed = repeatByte((byte) 0x01, SEED_FILE_SIZE);
+ Files.write(seedFile.toPath(), previousSeed);
+
+ byte[] urandomInjectedData = repeatByte((byte) 0x02, SEED_FILE_SIZE);
+ Files.write(randomReadDevice.toPath(), urandomInjectedData);
+
+ // The constructor should have the side effect of writing to
+ // randomWriteDevice and updating seedFile.
+ new EntropyMixer(getContext(), seedFile, randomReadDevice, randomWriteDevice);
+
+ // The data that was written to randomWriteDevice should consist of the
+ // previous seed followed by the device-specific information.
+ byte[] dataWrittenToUrandom = Files.readAllBytes(randomWriteDevice.toPath());
+ byte[] firstPartWritten = Arrays.copyOf(dataWrittenToUrandom, SEED_FILE_SIZE);
+ byte[] secondPartWritten =
+ Arrays.copyOfRange(
+ dataWrittenToUrandom, SEED_FILE_SIZE, dataWrittenToUrandom.length);
+ assertArrayEquals(previousSeed, firstPartWritten);
+ assertTrue(isDeviceSpecificInfo(secondPartWritten));
+
+ // The seed file should have been updated.
+ validateSeedFile(seedFile, previousSeed, urandomInjectedData);
+ }
+
+ private boolean isDeviceSpecificInfo(byte[] data) {
+ return new String(data).startsWith(EntropyMixer.DEVICE_SPECIFIC_INFO_HEADER);
+ }
- assertTrue(FileUtils.readTextFile(file, 0, null).length() > 0);
+ private void validateSeedFile(File seedFile, byte[] previousSeed, byte[] urandomInjectedData)
+ throws Exception {
+ final int unhashedLen = SEED_FILE_SIZE - 32;
+ byte[] newSeed = Files.readAllBytes(seedFile.toPath());
+ assertEquals(SEED_FILE_SIZE, newSeed.length);
+ assertEquals(SEED_FILE_SIZE, urandomInjectedData.length);
+ assertFalse(Arrays.equals(newSeed, previousSeed));
+ // The new seed should consist of the first SEED_FILE_SIZE - 32 bytes
+ // that were read from urandom, followed by a 32-byte hash that should
+ // *not* be the same as the last 32 bytes that were read from urandom.
+ byte[] firstPart = Arrays.copyOf(newSeed, unhashedLen);
+ byte[] secondPart = Arrays.copyOfRange(newSeed, unhashedLen, SEED_FILE_SIZE);
+ byte[] firstPartInjected = Arrays.copyOf(urandomInjectedData, unhashedLen);
+ byte[] secondPartInjected =
+ Arrays.copyOfRange(urandomInjectedData, unhashedLen, SEED_FILE_SIZE);
+ assertArrayEquals(firstPart, firstPartInjected);
+ assertFalse(Arrays.equals(secondPart, secondPartInjected));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java b/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
index 782d51941809..c940ef5c290d 100644
--- a/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
@@ -70,6 +70,7 @@ public class AnrHelperTest {
final Context context = getInstrumentation().getTargetContext();
runWithDexmakerShareClassLoader(() -> {
mAnrApp = mock(ProcessRecord.class);
+ mAnrApp.mPid = 12345;
final ProcessErrorStateRecord errorState = mock(ProcessErrorStateRecord.class);
setFieldValue(ProcessErrorStateRecord.class, errorState, "mProcLock",
new ActivityManagerProcLock());
@@ -130,7 +131,6 @@ public class AnrHelperTest {
}).when(mAnrApp.mErrorState).appNotResponding(anyString(), any(), any(), any(),
anyBoolean(), anyString(), anyBoolean());
final ApplicationInfo appInfo = new ApplicationInfo();
- mAnrApp.mPid = 12345;
final Runnable reportAnr = () -> mAnrHelper.appNotResponding(mAnrApp,
"activityShortComponentName", appInfo, "parentShortComponentName",
null /* parentProcess */, false /* aboveSystem */, "annotation");
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 2ad5eaeb9aaf..85d8aba58dbb 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -192,7 +192,7 @@ public class BiometricServiceTest {
waitForIdle();
assertNull(mBiometricService.mAuthSession);
- verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
}
@@ -211,7 +211,8 @@ public class BiometricServiceTest {
waitForIdle();
assertNotNull(mBiometricService.mAuthSession);
- verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog();
+ verify(mBiometricService.mStatusBarService, never())
+ .hideAuthenticationDialog(eq(TEST_REQUEST_ID));
assertEquals(STATE_CLIENT_DIED_CANCELLING,
mBiometricService.mAuthSession.getState());
@@ -225,7 +226,7 @@ public class BiometricServiceTest {
BiometricConstants.BIOMETRIC_ERROR_CANCELED,
0 /* vendorCode */);
waitForIdle();
- verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
assertNull(mBiometricService.mAuthSession);
}
@@ -666,7 +667,7 @@ public class BiometricServiceTest {
eq(BiometricAuthenticator.TYPE_FACE),
eq(BiometricPrompt.BIOMETRIC_ERROR_CANCELED),
eq(0) /* vendorCode */);
- verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
verify(mReceiver2, never()).onError(anyInt(), anyInt(), anyInt());
}
@@ -745,7 +746,7 @@ public class BiometricServiceTest {
eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
eq(0 /* vendorCode */));
// Dialog is hidden immediately
- verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
// Auth session is over
assertNull(mBiometricService.mAuthSession);
}
@@ -773,7 +774,8 @@ public class BiometricServiceTest {
eq(TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
eq(0 /* vendorCode */));
- verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog();
+ verify(mBiometricService.mStatusBarService, never())
+ .hideAuthenticationDialog(eq(TEST_REQUEST_ID));
verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
// SystemUI animation completed, client is notified, auth session is over
@@ -1152,7 +1154,7 @@ public class BiometricServiceTest {
verify(mReceiver1).onError(eq(TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
eq(0 /* vendorCode */));
- verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
index fe023374ba88..0b8e8adc5cc4 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -250,4 +251,18 @@ public class BiometricLoggerTest {
callback.onClientFinished(mClient, true /* success */);
verify(mSensorManager, never()).registerListener(any(), any(), anyInt());
}
+
+ @Test
+ public void testALSCallbackDestroyed() {
+ mLogger = createLogger();
+ final CallbackWithProbe<Probe> callback =
+ mLogger.createALSCallback(true /* startWithClient */);
+
+ callback.onClientStarted(mClient);
+ callback.onClientFinished(mClient, false /* success */);
+
+ reset(mSensorManager);
+ callback.getProbe().enable();
+ verify(mSensorManager, never()).registerListener(any(), any(), anyInt());
+ }
}
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 6c50ca35be79..746302224d21 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
@@ -31,9 +31,11 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.common.OperationContext;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.PointerContext;
+import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController;
@@ -63,12 +65,14 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
+import java.util.ArrayList;
import java.util.function.Consumer;
@Presubmit
@SmallTest
public class FingerprintAuthenticationClientTest {
+ private static final int SENSOR_ID = 4;
private static final int USER_ID = 8;
private static final long OP_ID = 7;
private static final long REQUEST_ID = 88;
@@ -93,6 +97,8 @@ public class FingerprintAuthenticationClientTest {
@Mock
private BiometricContext mBiometricContext;
@Mock
+ private BiometricManager mBiometricManager;
+ @Mock
private LockoutCache mLockoutCache;
@Mock
private IUdfpsOverlayController mUdfpsOverlayController;
@@ -118,6 +124,7 @@ public class FingerprintAuthenticationClientTest {
@Before
public void setup() {
+ mContext.addMockSystemService(BiometricManager.class, mBiometricManager);
when(mBiometricLogger.createALSCallback(anyBoolean())).thenAnswer(i ->
new CallbackWithProbe<>(mLuxProbe, i.getArgument(0)));
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
@@ -212,6 +219,18 @@ public class FingerprintAuthenticationClientTest {
}
@Test
+ public void luxProbeWhenFingerDown_unlessDestroyed() throws RemoteException {
+ final FingerprintAuthenticationClient client = createClient();
+ client.start(mCallback);
+ client.onAuthenticated(new Fingerprint("name", 2 /* enrollmentId */, SENSOR_ID),
+ true /* authenticated */, new ArrayList<>());
+ verify(mLuxProbe).destroy();
+
+ client.onAcquired(2, 0);
+ verify(mLuxProbe, never()).enable();
+ }
+
+ @Test
public void notifyHalWhenContextChanges() throws RemoteException {
final FingerprintAuthenticationClient client = createClient();
client.start(mCallback);
@@ -284,6 +303,6 @@ public class FingerprintAuthenticationClientTest {
true /* isStrongBiometric */,
null /* taskStackListener */, mLockoutCache,
mUdfpsOverlayController, mSideFpsController,
- false /* allowBackgroundAuthentication */, mSensorProps);
+ true /* allowBackgroundAuthentication */, mSensorProps);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index 40c039210939..864f31552ae3 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -20,8 +20,8 @@ import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REF
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS;
-import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR;
+import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE;
@@ -919,16 +919,6 @@ public class DisplayModeDirectorTest {
// Should be no vote initially
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
assertNull(vote);
-
- // Enabling GHBM votes for 60hz
- hbmListener.onHbmEnabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
- vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
- assertVoteForRefreshRate(vote, 60.f);
-
- // Disabling GHBM removes the vote
- hbmListener.onHbmDisabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
- vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
- assertNull(vote);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
index 18f264277b41..112db7612f29 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
@@ -61,7 +61,8 @@ public class ActiveSourceActionTest {
public void setUp() throws Exception {
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
- mHdmiControlService = new HdmiControlService(mContextSpy, Collections.emptyList()) {
+ mHdmiControlService = new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
AudioManager getAudioManager() {
return new AudioManager() {
@@ -93,6 +94,7 @@ public class ActiveSourceActionTest {
mHdmiControlService.setCecController(hdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(mContextSpy);
mHdmiControlService.setPowerManager(mPowerManager);
mPhysicalAddress = 0x2000;
@@ -153,7 +155,6 @@ public class ActiveSourceActionTest {
mHdmiControlService);
audioDevice.init();
mLocalDevices.add(audioDevice);
- mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
index e4c5ad6769d7..e4eecc6f6fa0 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
@@ -68,7 +68,8 @@ public class ArcInitiationActionFromAvrTest {
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
HdmiControlService hdmiControlService =
- new HdmiControlService(mContextSpy, Collections.emptyList()) {
+ new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
boolean isPowerStandby() {
return false;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index d73cdb5f53b0..5b114661fae8 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -68,7 +68,8 @@ public class ArcTerminationActionFromAvrTest {
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
HdmiControlService hdmiControlService =
- new HdmiControlService(mContextSpy, Collections.emptyList()) {
+ new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
AudioManager getAudioManager() {
return mAudioManager;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeControlTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeControlTest.java
new file mode 100644
index 000000000000..e06877f9144e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeControlTest.java
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
+
+import static com.android.server.hdmi.HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_BOOT_UP;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
+
+import static org.mockito.AdditionalMatchers.not;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.hardware.hdmi.DeviceFeatures;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.hardware.hdmi.HdmiPortInfo;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceVolumeManager;
+import android.media.AudioManager;
+import android.media.VolumeInfo;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.test.TestLooper;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.server.SystemService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * Tests that Absolute Volume Control (AVC) is enabled and disabled correctly, and that
+ * the device responds correctly to incoming <Report Audio Status> messages and API calls
+ * from AudioService when AVC is active.
+ *
+ * This is an abstract base class. Concrete subclasses specify the type of the local device, and the
+ * type of the System Audio device. This allows each test to be run for multiple setups.
+ *
+ * We test the following pairs of (local device, System Audio device):
+ * (Playback, TV): {@link PlaybackDeviceToTvAvcTest}
+ * (Playback, Audio System): {@link PlaybackDeviceToAudioSystemAvcTest}
+ * (TV, Audio System): {@link TvToAudioSystemAvcTest}
+ */
+public abstract class BaseAbsoluteVolumeControlTest {
+ private HdmiControlService mHdmiControlService;
+ private HdmiCecController mHdmiCecController;
+ private HdmiCecLocalDevice mHdmiCecLocalDevice;
+ private FakeHdmiCecConfig mHdmiCecConfig;
+ private FakePowerManagerWrapper mPowerManager;
+ private Looper mLooper;
+ private Context mContextSpy;
+ private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+
+ @Mock protected AudioManager mAudioManager;
+ protected FakeAudioDeviceVolumeManagerWrapper mAudioDeviceVolumeManager;
+
+ protected TestLooper mTestLooper = new TestLooper();
+ protected FakeNativeWrapper mNativeWrapper;
+
+ // Audio Status given by the System Audio device in its initial <Report Audio Status> that
+ // triggers AVC being enabled
+ private static final AudioStatus INITIAL_SYSTEM_AUDIO_DEVICE_STATUS =
+ new AudioStatus(50, false);
+
+ // VolumeInfo passed to AudioDeviceVolumeManager#setDeviceAbsoluteVolumeBehavior to enable AVC
+ private static final VolumeInfo ENABLE_AVC_VOLUME_INFO =
+ new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+ .setMuted(INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute())
+ .setVolumeIndex(INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume())
+ .setMaxVolumeIndex(AudioStatus.MAX_VOLUME)
+ .setMinVolumeIndex(AudioStatus.MIN_VOLUME)
+ .build();
+
+ protected abstract HdmiCecLocalDevice createLocalDevice(HdmiControlService hdmiControlService);
+
+ protected abstract int getPhysicalAddress();
+ protected abstract int getDeviceType();
+ protected abstract AudioDeviceAttributes getAudioOutputDevice();
+
+ protected abstract int getSystemAudioDeviceLogicalAddress();
+ protected abstract int getSystemAudioDeviceType();
+
+ @Before
+ public void setUp() throws RemoteException {
+ MockitoAnnotations.initMocks(this);
+
+ mContextSpy = spy(new ContextWrapper(
+ InstrumentationRegistry.getInstrumentation().getTargetContext()));
+
+ mAudioDeviceVolumeManager = spy(new FakeAudioDeviceVolumeManagerWrapper());
+
+ mHdmiControlService =
+ new HdmiControlService(InstrumentationRegistry.getTargetContext(),
+ Collections.singletonList(getDeviceType()),
+ mAudioDeviceVolumeManager) {
+ @Override
+ AudioManager getAudioManager() {
+ return mAudioManager;
+ }
+
+ @Override
+ protected void writeStringSystemProperty(String key, String value) {
+ // do nothing
+ }
+ };
+
+ mLooper = mTestLooper.getLooper();
+ mHdmiControlService.setIoLooper(mLooper);
+
+ mHdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
+ mHdmiCecConfig.setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_2_0);
+ mHdmiCecConfig.setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
+ HdmiControlManager.VOLUME_CONTROL_DISABLED);
+ mHdmiControlService.setHdmiCecConfig(mHdmiCecConfig);
+
+ mNativeWrapper = new FakeNativeWrapper();
+ mNativeWrapper.setPhysicalAddress(getPhysicalAddress());
+ mNativeWrapper.setPollAddressResponse(Constants.ADDR_TV, SendMessageResult.SUCCESS);
+
+ mHdmiCecController = HdmiCecController.createWithNativeWrapper(
+ mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setCecController(mHdmiCecController);
+ mHdmiControlService.setHdmiMhlController(
+ HdmiMhlControllerStub.create(mHdmiControlService));
+ mHdmiControlService.initService();
+ mPowerManager = new FakePowerManagerWrapper(mContextSpy);
+ mHdmiControlService.setPowerManager(mPowerManager);
+
+ mHdmiCecLocalDevice = createLocalDevice(mHdmiControlService);
+ mHdmiCecLocalDevice.init();
+ mLocalDevices.add(mHdmiCecLocalDevice);
+
+ HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1];
+ hdmiPortInfos[0] =
+ new HdmiPortInfo(1, HdmiPortInfo.PORT_OUTPUT, 0x0000, true, false, false);
+ mNativeWrapper.setPortInfo(hdmiPortInfos);
+ mNativeWrapper.setPortConnectionStatus(1, true);
+
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_BOOT_UP);
+ mTestLooper.dispatchAll();
+
+ // Simulate AudioManager's behavior and response when setDeviceVolumeBehavior is called
+ doAnswer(invocation -> {
+ setDeviceVolumeBehavior(invocation.getArgument(0), invocation.getArgument(1));
+ return null;
+ }).when(mAudioManager).setDeviceVolumeBehavior(any(), anyInt());
+
+ // Set starting volume behavior
+ doReturn(AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE)
+ .when(mAudioManager).getDeviceVolumeBehavior(eq(getAudioOutputDevice()));
+
+ // Audio service always plays STREAM_MUSIC on the device we need
+ doReturn(Collections.singletonList(getAudioOutputDevice())).when(mAudioManager)
+ .getDevicesForAttributes(HdmiControlService.STREAM_MUSIC_ATTRIBUTES);
+
+ // Max volume of STREAM_MUSIC
+ doReturn(25).when(mAudioManager).getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+
+ // Receive messages from devices to make sure they're registered in HdmiCecNetwork
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
+ Constants.ADDR_TV, getLogicalAddress()));
+ if (getSystemAudioDeviceType() == DEVICE_AUDIO_SYSTEM) {
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
+ Constants.ADDR_AUDIO_SYSTEM, getLogicalAddress()));
+ }
+
+ mHdmiControlService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+ mHdmiControlService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+ mTestLooper.dispatchAll();
+ }
+
+ protected int getLogicalAddress() {
+ synchronized (mHdmiCecLocalDevice.mLock) {
+ return mHdmiCecLocalDevice.getDeviceInfo().getLogicalAddress();
+ }
+ }
+
+ /**
+ * Simulates the volume behavior of {@code device} being set to {@code behavior}.
+ */
+ protected void setDeviceVolumeBehavior(AudioDeviceAttributes device,
+ @AudioManager.DeviceVolumeBehavior int behavior) {
+ doReturn(behavior).when(mAudioManager).getDeviceVolumeBehavior(eq(device));
+ mHdmiControlService.onDeviceVolumeBehaviorChanged(device, behavior);
+ mTestLooper.dispatchAll();
+ }
+
+ /**
+ * Changes the setting for CEC volume.
+ */
+ protected void setCecVolumeControlSetting(@HdmiControlManager.VolumeControl int setting) {
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE, setting);
+ mTestLooper.dispatchAll();
+ }
+
+ /**
+ * Has the device receive a <Report Features> message from the System Audio device specifying
+ * whether <Set Audio Volume Level> is supported or not.
+ */
+ protected void receiveSetAudioVolumeLevelSupport(
+ @DeviceFeatures.FeatureSupportStatus int featureSupportStatus) {
+ // <Report Features> can't specify an unknown feature support status
+ if (featureSupportStatus != DeviceFeatures.FEATURE_SUPPORT_UNKNOWN) {
+ mNativeWrapper.onCecMessage(ReportFeaturesMessage.build(
+ getSystemAudioDeviceLogicalAddress(), HdmiControlManager.HDMI_CEC_VERSION_2_0,
+ Arrays.asList(getSystemAudioDeviceType()), Constants.RC_PROFILE_SOURCE,
+ Collections.emptyList(),
+ DeviceFeatures.NO_FEATURES_SUPPORTED.toBuilder()
+ .setSetAudioVolumeLevelSupport(featureSupportStatus)
+ .build()));
+ mTestLooper.dispatchAll();
+ }
+ }
+
+ /**
+ * Enables System Audio mode if the System Audio device is an Audio System.
+ */
+ protected void enableSystemAudioModeIfNeeded() {
+ if (getSystemAudioDeviceType() == DEVICE_AUDIO_SYSTEM) {
+ receiveSetSystemAudioMode(true);
+ }
+ }
+
+ /**
+ * Sets System Audio Mode by having the device receive <Set System Audio Mode>
+ * from the Audio System.
+ */
+ protected void receiveSetSystemAudioMode(boolean status) {
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_BROADCAST, status));
+ mTestLooper.dispatchAll();
+ }
+
+ /**
+ * Has the device receive a <Report Audio Status> reporting the status in
+ * {@link #INITIAL_SYSTEM_AUDIO_DEVICE_STATUS}
+ */
+ protected void receiveInitialReportAudioStatus() {
+ receiveReportAudioStatus(
+ INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume(),
+ INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute());
+ }
+
+ /**
+ * Has the device receive a <Report Audio Status> message from the System Audio Device.
+ */
+ protected void receiveReportAudioStatus(int volume, boolean mute) {
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildReportAudioStatus(
+ getSystemAudioDeviceLogicalAddress(),
+ getLogicalAddress(),
+ volume,
+ mute));
+ mTestLooper.dispatchAll();
+ }
+
+ /**
+ * Triggers all the conditions required to enable Absolute Volume Control.
+ */
+ protected void enableAbsoluteVolumeControl() {
+ setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
+ receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
+ enableSystemAudioModeIfNeeded();
+ receiveInitialReportAudioStatus();
+
+ verifyAbsoluteVolumeEnabled();
+ }
+
+ /**
+ * Verifies that AVC was enabled - that is the audio output device's volume behavior was last
+ * set to absolute volume behavior.
+ */
+ protected void verifyAbsoluteVolumeEnabled() {
+ InOrder inOrder = inOrder(mAudioManager, mAudioDeviceVolumeManager);
+ inOrder.verify(mAudioDeviceVolumeManager, atLeastOnce()).setDeviceAbsoluteVolumeBehavior(
+ eq(getAudioOutputDevice()), any(), any(), any(), anyBoolean());
+ inOrder.verify(mAudioManager, never()).setDeviceVolumeBehavior(
+ eq(getAudioOutputDevice()), not(eq(AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE)));
+ }
+
+ /**
+ * Verifies that AVC was disabled - that is, the audio output device's volume behavior was
+ * last set to something other than absolute volume behavior.
+ */
+ protected void verifyAbsoluteVolumeDisabled() {
+ InOrder inOrder = inOrder(mAudioManager, mAudioDeviceVolumeManager);
+ inOrder.verify(mAudioManager, atLeastOnce()).setDeviceVolumeBehavior(
+ eq(getAudioOutputDevice()), not(eq(AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE)));
+ inOrder.verify(mAudioDeviceVolumeManager, never()).setDeviceAbsoluteVolumeBehavior(
+ eq(getAudioOutputDevice()), any(), any(), any(), anyBoolean());
+ }
+
+ protected void verifyGiveAudioStatusNeverSent() {
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(
+ HdmiCecMessageBuilder.buildGiveAudioStatus(
+ getLogicalAddress(), getSystemAudioDeviceLogicalAddress()));
+ }
+
+ protected void verifyGiveAudioStatusSent() {
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ HdmiCecMessageBuilder.buildGiveAudioStatus(
+ getLogicalAddress(), getSystemAudioDeviceLogicalAddress()));
+ }
+
+ @Test
+ public void allConditionsExceptSavlSupportMet_sendsSetAudioVolumeLevelAndGiveFeatures() {
+ setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
+ enableSystemAudioModeIfNeeded();
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ SetAudioVolumeLevelMessage.build(
+ getLogicalAddress(), getSystemAudioDeviceLogicalAddress(),
+ Constants.AUDIO_VOLUME_STATUS_UNKNOWN));
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ HdmiCecMessageBuilder.buildGiveFeatures(
+ getLogicalAddress(), getSystemAudioDeviceLogicalAddress()));
+ }
+
+ @Test
+ public void allConditionsMet_savlSupportLast_reportFeatures_giveAudioStatusSent() {
+ setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
+ enableSystemAudioModeIfNeeded();
+ verifyGiveAudioStatusNeverSent();
+
+ receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
+ verifyGiveAudioStatusSent();
+ }
+
+ @Test
+ public void allConditionsMet_savlSupportLast_noFeatureAbort_giveAudioStatusSent() {
+ setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
+ enableSystemAudioModeIfNeeded();
+ verifyGiveAudioStatusNeverSent();
+
+ mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+ mTestLooper.dispatchAll();
+ verifyGiveAudioStatusSent();
+ }
+
+ @Test
+ public void allConditionsMet_cecVolumeEnabledLast_giveAudioStatusSent() {
+ setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ enableSystemAudioModeIfNeeded();
+ receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
+ verifyGiveAudioStatusNeverSent();
+
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
+ verifyGiveAudioStatusSent();
+ }
+
+ @Test
+ public void allConditionsMet_fullVolumeBehaviorLast_giveAudioStatusSent() {
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
+ enableSystemAudioModeIfNeeded();
+ receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
+ verifyGiveAudioStatusNeverSent();
+
+ setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ verifyGiveAudioStatusSent();
+ }
+
+ @Test
+ public void allConditionsMet_systemAudioModeEnabledLast_giveAudioStatusSent() {
+ // Only run when the System Audio device is an Audio System.
+ assume().that(getSystemAudioDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
+
+ setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
+ receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
+ verifyGiveAudioStatusNeverSent();
+
+ receiveSetSystemAudioMode(true);
+ verifyGiveAudioStatusSent();
+ }
+
+ @Test
+ public void giveAudioStatusSent_systemAudioDeviceSendsReportAudioStatus_avcEnabled() {
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
+ enableSystemAudioModeIfNeeded();
+ receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
+ setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+
+ // Verify that AVC was never enabled
+ verify(mAudioDeviceVolumeManager, never()).setDeviceAbsoluteVolumeBehavior(
+ eq(getAudioOutputDevice()), any(), any(), any(), anyBoolean());
+ receiveInitialReportAudioStatus();
+
+ verifyAbsoluteVolumeEnabled();
+ }
+
+ @Test
+ public void avcEnabled_cecVolumeDisabled_absoluteVolumeDisabled() {
+ enableAbsoluteVolumeControl();
+
+ setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_DISABLED);
+ verifyAbsoluteVolumeDisabled();
+ }
+
+ @Test
+ public void avcEnabled_setAudioVolumeLevelNotSupported_absoluteVolumeDisabled() {
+ enableAbsoluteVolumeControl();
+
+ receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_NOT_SUPPORTED);
+ verifyAbsoluteVolumeDisabled();
+ }
+
+ @Test
+ public void avcEnabled_setAudioVolumeLevelFeatureAborted_absoluteVolumeDisabled() {
+ enableAbsoluteVolumeControl();
+
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ getSystemAudioDeviceLogicalAddress(), getLogicalAddress(),
+ Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL, Constants.ABORT_UNRECOGNIZED_OPCODE));
+ mTestLooper.dispatchAll();
+ verifyAbsoluteVolumeDisabled();
+ }
+
+ @Test
+ public void avcEnabled_systemAudioModeDisabled_absoluteVolumeDisabled() {
+ // Only run when the System Audio device is an Audio System.
+ assume().that(getSystemAudioDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
+
+ enableAbsoluteVolumeControl();
+
+ receiveSetSystemAudioMode(false);
+ verifyAbsoluteVolumeDisabled();
+ }
+
+ @Test
+ public void avcEnabled_receiveReportAudioStatus_notifiesVolumeOrMuteChanges() {
+ // Initial <Report Audio Status> has volume=50 and mute=false
+ enableAbsoluteVolumeControl();
+
+ // New volume and mute status: sets both
+ receiveReportAudioStatus(20, true);
+ verify(mAudioManager).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(5),
+ anyInt());
+ verify(mAudioManager).adjustStreamVolume(eq(AudioManager.STREAM_MUSIC),
+ eq(AudioManager.ADJUST_MUTE), anyInt());
+ clearInvocations(mAudioManager);
+
+ // New volume only: sets volume only
+ receiveReportAudioStatus(32, true);
+ verify(mAudioManager).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(8),
+ anyInt());
+ verify(mAudioManager, never()).adjustStreamVolume(eq(AudioManager.STREAM_MUSIC),
+ eq(AudioManager.ADJUST_MUTE), anyInt());
+ clearInvocations(mAudioManager);
+
+ // New mute status only: sets mute only
+ receiveReportAudioStatus(32, false);
+ verify(mAudioManager, never()).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(8),
+ anyInt());
+ verify(mAudioManager).adjustStreamVolume(eq(AudioManager.STREAM_MUSIC),
+ eq(AudioManager.ADJUST_UNMUTE), anyInt());
+ clearInvocations(mAudioManager);
+
+ // Repeat of earlier message: sets neither volume nor mute
+ receiveReportAudioStatus(32, false);
+ verify(mAudioManager, never()).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(8),
+ anyInt());
+ verify(mAudioManager, never()).adjustStreamVolume(eq(AudioManager.STREAM_MUSIC),
+ eq(AudioManager.ADJUST_UNMUTE), anyInt());
+ clearInvocations(mAudioManager);
+
+ // If AudioService causes us to send <Set Audio Volume Level>, the System Audio device's
+ // volume changes. Afterward, a duplicate of an earlier <Report Audio Status> should
+ // still cause us to call setStreamVolume()
+ mHdmiControlService.getAbsoluteVolumeChangedListener().onAudioDeviceVolumeChanged(
+ getAudioOutputDevice(),
+ new VolumeInfo.Builder(ENABLE_AVC_VOLUME_INFO)
+ .setVolumeIndex(20)
+ .build()
+ );
+ mTestLooper.dispatchAll();
+ receiveReportAudioStatus(32, false);
+ verify(mAudioManager).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(8),
+ anyInt());
+ verify(mAudioManager, never()).adjustStreamVolume(eq(AudioManager.STREAM_MUSIC),
+ eq(AudioManager.ADJUST_UNMUTE), anyInt());
+ }
+
+ @Test
+ public void avcEnabled_audioDeviceVolumeAdjusted_sendsUserControlPressedAndGiveAudioStatus() {
+ enableAbsoluteVolumeControl();
+ mNativeWrapper.clearResultMessages();
+
+ mHdmiControlService.getAbsoluteVolumeChangedListener().onAudioDeviceVolumeAdjusted(
+ getAudioOutputDevice(),
+ ENABLE_AVC_VOLUME_INFO,
+ AudioManager.ADJUST_RAISE,
+ AudioDeviceVolumeManager.ADJUST_MODE_NORMAL
+ );
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ HdmiCecMessageBuilder.buildUserControlPressed(getLogicalAddress(),
+ getSystemAudioDeviceLogicalAddress(), CEC_KEYCODE_VOLUME_UP));
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ HdmiCecMessageBuilder.buildUserControlReleased(getLogicalAddress(),
+ getSystemAudioDeviceLogicalAddress()));
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ HdmiCecMessageBuilder.buildGiveAudioStatus(getLogicalAddress(),
+ getSystemAudioDeviceLogicalAddress()));
+ }
+
+ @Test
+ public void avcEnabled_audioDeviceVolumeChanged_sendsSetAudioVolumeLevel() {
+ enableAbsoluteVolumeControl();
+ mNativeWrapper.clearResultMessages();
+
+ mHdmiControlService.getAbsoluteVolumeChangedListener().onAudioDeviceVolumeChanged(
+ getAudioOutputDevice(),
+ new VolumeInfo.Builder(ENABLE_AVC_VOLUME_INFO)
+ .setVolumeIndex(20)
+ .build()
+ );
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ SetAudioVolumeLevelMessage.build(getLogicalAddress(),
+ getSystemAudioDeviceLogicalAddress(), 20));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
index 5cec8ad1e63d..28ba4bb503f9 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
@@ -56,7 +56,7 @@ public class DetectTvSystemAudioModeSupportActionTest {
mDeviceInfoForTests = HdmiDeviceInfo.hardwarePort(1001, 1234);
HdmiControlService hdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext(),
- Collections.emptyList()) {
+ Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
void sendCecCommand(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
index 52a0b6cdc2be..545f3183ee26 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
@@ -16,6 +16,7 @@
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
@@ -78,7 +79,8 @@ public class DevicePowerStatusActionTest {
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
- mHdmiControlService = new HdmiControlService(mContextSpy, Collections.emptyList()) {
+ mHdmiControlService = new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
AudioManager getAudioManager() {
return new AudioManager() {
@@ -110,6 +112,7 @@ public class DevicePowerStatusActionTest {
mHdmiControlService.setCecController(hdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(mContextSpy);
mHdmiControlService.setPowerManager(mPowerManager);
mPhysicalAddress = 0x2000;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
index 35432edfcf16..d7fef90456ab 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
@@ -20,6 +20,7 @@ import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_ON;
import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_STANDBY;
import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_3;
@@ -100,7 +101,7 @@ public class DeviceSelectActionFromPlaybackTest {
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext(),
- Collections.emptyList()) {
+ Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
boolean isControlEnabled() {
return true;
@@ -136,6 +137,7 @@ public class DeviceSelectActionFromPlaybackTest {
mLocalDevices.add(mHdmiCecLocalDevicePlayback);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mNativeWrapper.setPhysicalAddress(0x0000);
mPowerManager = new FakePowerManagerWrapper(context);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
index e77cd91b46d8..72d36b00d73d 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
@@ -20,6 +20,7 @@ import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_ON;
import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_STANDBY;
import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2;
import static com.android.server.hdmi.Constants.ADDR_TV;
@@ -109,7 +110,7 @@ public class DeviceSelectActionFromTvTest {
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext(),
- Collections.emptyList()) {
+ Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
boolean isControlEnabled() {
return true;
@@ -145,6 +146,7 @@ public class DeviceSelectActionFromTvTest {
true, false, false);
mNativeWrapper.setPortInfo(hdmiPortInfos);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(context);
mHdmiControlService.setPowerManager(mPowerManager);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioDeviceVolumeManagerWrapper.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioDeviceVolumeManagerWrapper.java
new file mode 100644
index 000000000000..d33ef9bc8879
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioDeviceVolumeManagerWrapper.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import static android.media.AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener;
+import static android.media.AudioDeviceVolumeManager.OnDeviceVolumeBehaviorChangedListener;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceVolumeManager;
+import android.media.AudioManager;
+import android.media.VolumeInfo;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+/**
+ * Wrapper for {@link AudioDeviceVolumeManager} that stubs its methods. Useful for testing.
+ */
+public class FakeAudioDeviceVolumeManagerWrapper implements
+ AudioDeviceVolumeManagerWrapperInterface {
+
+ private final Set<OnDeviceVolumeBehaviorChangedListener> mVolumeBehaviorListeners;
+
+ public FakeAudioDeviceVolumeManagerWrapper() {
+ mVolumeBehaviorListeners = new HashSet<>();
+ }
+
+ @Override
+ public void addOnDeviceVolumeBehaviorChangedListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnDeviceVolumeBehaviorChangedListener listener)
+ throws SecurityException {
+ mVolumeBehaviorListeners.add(listener);
+ }
+
+ @Override
+ public void removeOnDeviceVolumeBehaviorChangedListener(
+ @NonNull OnDeviceVolumeBehaviorChangedListener listener) {
+ mVolumeBehaviorListeners.remove(listener);
+ }
+
+ @Override
+ public void setDeviceAbsoluteVolumeBehavior(
+ @NonNull AudioDeviceAttributes device,
+ @NonNull VolumeInfo volume,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener,
+ boolean handlesVolumeAdjustment) {
+ // Notify all volume behavior listeners that the device adopted absolute volume behavior
+ for (OnDeviceVolumeBehaviorChangedListener listener : mVolumeBehaviorListeners) {
+ listener.onDeviceVolumeBehaviorChanged(device,
+ AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
index 30bcc7e8afa1..9f744f9373ed 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
@@ -89,7 +89,8 @@ public class HdmiCecAtomLoggingTest {
mContextSpy = spy(new ContextWrapper(
InstrumentationRegistry.getInstrumentation().getTargetContext()));
- mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy, Collections.emptyList()));
+ mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()));
doNothing().when(mHdmiControlServiceSpy)
.writeStringSystemProperty(anyString(), anyString());
doReturn(mHdmiCecAtomWriterSpy).when(mHdmiControlServiceSpy).getAtomWriter();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
index 2dcc449e36a5..0cba10669c85 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
@@ -101,7 +101,8 @@ public class HdmiCecControllerTest {
mMyLooper = mTestLooper.getLooper();
mHdmiControlServiceSpy = spy(new HdmiControlService(
- InstrumentationRegistry.getTargetContext(), Collections.emptyList()));
+ InstrumentationRegistry.getTargetContext(), Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()));
doReturn(mMyLooper).when(mHdmiControlServiceSpy).getIoLooper();
doReturn(mMyLooper).when(mHdmiControlServiceSpy).getServiceLooper();
doAnswer(__ -> mCecVersion).when(mHdmiControlServiceSpy).getCecVersion();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 70bc460411c8..91d265c81083 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -88,7 +88,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext(),
- Collections.emptyList()) {
+ Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
AudioManager getAudioManager() {
return new AudioManager() {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 86130daf4aac..484b5a8dae1a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -15,6 +15,7 @@
*/
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ABORT_UNRECOGNIZED_OPCODE;
import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
@@ -92,7 +93,7 @@ public class HdmiCecLocalDevicePlaybackTest {
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext(),
- Collections.emptyList()) {
+ Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
void wakeUp() {
mWokenUp = true;
@@ -151,6 +152,7 @@ public class HdmiCecLocalDevicePlaybackTest {
mNativeWrapper.setPortInfo(hdmiPortInfos);
mNativeWrapper.setPortConnectionStatus(1, true);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(context);
mHdmiControlService.setPowerManager(mPowerManager);
mHdmiControlService.setPowerManagerInternal(mPowerManagerInternal);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
index fb8baa30e6b4..48e70fe4a60f 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -17,6 +17,7 @@ package com.android.server.hdmi;
import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
import static com.android.server.hdmi.Constants.ADDR_TV;
@@ -137,7 +138,8 @@ public class HdmiCecLocalDeviceTest {
Context context = InstrumentationRegistry.getTargetContext();
mHdmiControlService =
- new HdmiControlService(context, Collections.emptyList()) {
+ new HdmiControlService(context, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
boolean isControlEnabled() {
return isControlEnabled;
@@ -190,6 +192,7 @@ public class HdmiCecLocalDeviceTest {
mNativeWrapper.setPortInfo(hdmiPortInfos);
mNativeWrapper.setPortConnectionStatus(1, true);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mNativeWrapper.setPhysicalAddress(0x2000);
mTestLooper.dispatchAll();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index df4aa5dac9df..f27b8c2f4b3a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -15,6 +15,7 @@
*/
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ABORT_UNRECOGNIZED_OPCODE;
import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
@@ -29,8 +30,10 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.hdmi.HdmiControlManager;
@@ -125,7 +128,7 @@ public class HdmiCecLocalDeviceTvTest {
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext(),
- Collections.emptyList()) {
+ Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
void wakeUp() {
mWokenUp = true;
@@ -179,6 +182,7 @@ public class HdmiCecLocalDeviceTvTest {
new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true);
mNativeWrapper.setPortInfo(hdmiPortInfos);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(context);
mHdmiControlService.setPowerManager(mPowerManager);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
@@ -768,7 +772,7 @@ public class HdmiCecLocalDeviceTvTest {
// When the device reports its physical address, the listener eventually is invoked.
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
- ADDR_PLAYBACK_2, 0x1000, HdmiDeviceInfo.DEVICE_PLAYBACK);
+ ADDR_PLAYBACK_2, 0x1000, HdmiDeviceInfo.DEVICE_PLAYBACK);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
@@ -777,6 +781,54 @@ public class HdmiCecLocalDeviceTvTest {
assertThat(mDeviceEventListeners.size()).isEqualTo(1);
assertThat(mDeviceEventListeners.get(0).getStatus())
.isEqualTo(HdmiControlManager.DEVICE_EVENT_ADD_DEVICE);
+ }
+
+ @Test
+ public void receiveSetAudioVolumeLevel_samNotActivated_noFeatureAbort_volumeChanges() {
+ when(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)).thenReturn(25);
+
+ // Max volume of STREAM_MUSIC is retrieved on boot
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
+ mTestLooper.dispatchAll();
+ mNativeWrapper.onCecMessage(SetAudioVolumeLevelMessage.build(
+ ADDR_PLAYBACK_1,
+ ADDR_TV,
+ 20));
+ mTestLooper.dispatchAll();
+
+ // <Feature Abort>[Not in correct mode] not sent
+ HdmiCecMessage featureAbortMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ ADDR_TV,
+ ADDR_PLAYBACK_1,
+ Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL,
+ Constants.ABORT_NOT_IN_CORRECT_MODE);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbortMessage);
+
+ // <Set Audio Volume Level> uses volume range [0, 100]; STREAM_MUSIC uses range [0, 25]
+ verify(mAudioManager).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(5), anyInt());
+ }
+
+ @Test
+ public void receiveSetAudioVolumeLevel_samActivated_respondsFeatureAbort_noVolumeChange() {
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, ADDR_TV, true));
+ mTestLooper.dispatchAll();
+
+ mNativeWrapper.onCecMessage(SetAudioVolumeLevelMessage.build(
+ ADDR_PLAYBACK_1, ADDR_TV, 50));
+ mTestLooper.dispatchAll();
+
+ // <Feature Abort>[Not in correct mode] sent
+ HdmiCecMessage featureAbortMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ ADDR_TV,
+ ADDR_PLAYBACK_1,
+ Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL,
+ Constants.ABORT_NOT_IN_CORRECT_MODE);
+ assertThat(mNativeWrapper.getResultMessages()).contains(featureAbortMessage);
+
+ // AudioManager not notified of volume change
+ verify(mAudioManager, never()).setStreamVolume(eq(AudioManager.STREAM_MUSIC), anyInt(),
+ anyInt());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index 50c9f70ccb03..a446e109c921 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -51,7 +51,8 @@ public class HdmiCecMessageValidatorTest {
@Before
public void setUp() throws Exception {
HdmiControlService mHdmiControlService = new HdmiControlService(
- InstrumentationRegistry.getTargetContext(), Collections.emptyList());
+ InstrumentationRegistry.getTargetContext(), Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper());
mHdmiControlService.setIoLooper(mTestLooper.getLooper());
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
index 03532ae1cb1f..b8a1ba363373 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
@@ -67,7 +67,8 @@ public class HdmiCecNetworkTest {
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
- mHdmiControlService = new HdmiControlService(mContext, Collections.emptyList()) {
+ mHdmiControlService = new HdmiControlService(mContext, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) {
mDeviceEventListenerStatuses.add(status);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
index 7a68285bc003..b94deeddb8af 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
@@ -15,6 +15,7 @@
*/
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.google.common.truth.Truth.assertThat;
@@ -65,7 +66,8 @@ public class HdmiCecPowerStatusControllerTest {
Context contextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
Looper myLooper = mTestLooper.getLooper();
- mHdmiControlService = new HdmiControlService(contextSpy, Collections.emptyList()) {
+ mHdmiControlService = new HdmiControlService(contextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
boolean isControlEnabled() {
return true;
@@ -105,6 +107,7 @@ public class HdmiCecPowerStatusControllerTest {
mNativeWrapper.setPortInfo(hdmiPortInfos);
mNativeWrapper.setPortConnectionStatus(1, true);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(contextSpy);
mHdmiControlService.setPowerManager(mPowerManager);
mHdmiControlService.getHdmiCecNetwork().initPortInfo();
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 3987c32277cd..6266571d33d4 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -91,7 +91,8 @@ public class HdmiControlServiceTest {
HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
- mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy, Collections.emptyList()));
+ mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()));
doNothing().when(mHdmiControlServiceSpy)
.writeStringSystemProperty(anyString(), anyString());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
index 561e6a5fec41..46a4e862c300 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
@@ -16,6 +16,7 @@
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.OneTouchPlayAction.STATE_WAITING_FOR_REPORT_POWER_STATUS;
@@ -87,7 +88,8 @@ public class OneTouchPlayActionTest {
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
mHdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
- mHdmiControlService = new HdmiControlService(mContextSpy, Collections.emptyList()) {
+ mHdmiControlService = new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
AudioManager getAudioManager() {
return new AudioManager() {
@@ -120,6 +122,7 @@ public class OneTouchPlayActionTest {
mHdmiControlService.setCecController(hdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(mContextSpy);
mHdmiControlService.setPowerManager(mPowerManager);
mPhysicalAddress = 0x2000;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvcTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvcTest.java
new file mode 100644
index 000000000000..64186028e6ed
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvcTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.DeviceFeatures;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.AudioDeviceAttributes;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import com.google.android.collect.Lists;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+
+/**
+ * Tests for Absolute Volume Control where the local device is a Playback device and the
+ * System Audio device is an Audio System.
+ */
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class PlaybackDeviceToAudioSystemAvcTest extends BaseAbsoluteVolumeControlTest {
+
+ @Override
+ protected HdmiCecLocalDevice createLocalDevice(HdmiControlService hdmiControlService) {
+ return new HdmiCecLocalDevicePlayback(hdmiControlService);
+ }
+
+ @Override
+ protected int getPhysicalAddress() {
+ return 0x1100;
+ }
+
+ @Override
+ protected int getDeviceType() {
+ return HdmiDeviceInfo.DEVICE_PLAYBACK;
+ }
+
+ @Override
+ protected AudioDeviceAttributes getAudioOutputDevice() {
+ return HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI;
+ }
+
+ @Override
+ protected int getSystemAudioDeviceLogicalAddress() {
+ return Constants.ADDR_AUDIO_SYSTEM;
+ }
+
+ @Override
+ protected int getSystemAudioDeviceType() {
+ return HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
+ }
+
+ /**
+ * AVC is disabled if the Audio System disables System Audio mode, and the TV has unknown
+ * support for <Set Audio Volume Level>. It is enabled once the TV confirms support for
+ * <Set Audio Volume Level> and sends <Report Audio Status>.
+ */
+ @Test
+ public void switchToTv_absoluteVolumeControlDisabledUntilAllConditionsMet() {
+ enableAbsoluteVolumeControl();
+
+ // Audio System disables System Audio Mode. AVC should be disabled.
+ receiveSetSystemAudioMode(false);
+ verifyAbsoluteVolumeDisabled();
+
+ // TV reports support for <Set Audio Volume Level>
+ mNativeWrapper.onCecMessage(ReportFeaturesMessage.build(
+ Constants.ADDR_TV, HdmiControlManager.HDMI_CEC_VERSION_2_0,
+ Arrays.asList(HdmiDeviceInfo.DEVICE_TV), Constants.RC_PROFILE_TV,
+ Lists.newArrayList(Constants.RC_PROFILE_TV_NONE),
+ DeviceFeatures.NO_FEATURES_SUPPORTED.toBuilder()
+ .setSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED)
+ .build()));
+ mTestLooper.dispatchAll();
+
+ // TV reports its initial audio status
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildReportAudioStatus(
+ Constants.ADDR_TV,
+ getLogicalAddress(),
+ 30,
+ false));
+ mTestLooper.dispatchAll();
+
+ verifyAbsoluteVolumeEnabled();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvcTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvcTest.java
new file mode 100644
index 000000000000..504c3bc2626a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvcTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import static org.mockito.Mockito.clearInvocations;
+
+import android.hardware.hdmi.DeviceFeatures;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.AudioDeviceAttributes;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * Tests for Absolute Volume Control where the local device is a Playback device and the
+ * System Audio device is a TV.
+ */
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class PlaybackDeviceToTvAvcTest extends BaseAbsoluteVolumeControlTest {
+
+ @Override
+ protected HdmiCecLocalDevice createLocalDevice(HdmiControlService hdmiControlService) {
+ return new HdmiCecLocalDevicePlayback(hdmiControlService);
+ }
+
+ @Override
+ protected int getPhysicalAddress() {
+ return 0x1100;
+ }
+
+ @Override
+ protected int getDeviceType() {
+ return HdmiDeviceInfo.DEVICE_PLAYBACK;
+ }
+
+ @Override
+ protected AudioDeviceAttributes getAudioOutputDevice() {
+ return HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI;
+ }
+
+ @Override
+ protected int getSystemAudioDeviceLogicalAddress() {
+ return Constants.ADDR_TV;
+ }
+
+ @Override
+ protected int getSystemAudioDeviceType() {
+ return HdmiDeviceInfo.DEVICE_TV;
+ }
+
+ /**
+ * AVC is disabled when an Audio System with unknown support for <Set Audio Volume Level>
+ * becomes the System Audio device. It is enabled once the Audio System reports that it
+ * supports <Set Audio Volume Level> and sends <Report Audio Status>.
+ */
+ @Test
+ public void switchToAudioSystem_absoluteVolumeControlDisabledUntilAllConditionsMet() {
+ enableAbsoluteVolumeControl();
+
+ // Audio System enables System Audio Mode. AVC should be disabled.
+ receiveSetSystemAudioMode(true);
+ verifyAbsoluteVolumeDisabled();
+
+ clearInvocations(mAudioManager, mAudioDeviceVolumeManager);
+
+ // Audio System reports support for <Set Audio Volume Level>
+ mNativeWrapper.onCecMessage(ReportFeaturesMessage.build(
+ Constants.ADDR_AUDIO_SYSTEM, HdmiControlManager.HDMI_CEC_VERSION_2_0,
+ Arrays.asList(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM), Constants.RC_PROFILE_SOURCE,
+ Collections.emptyList(),
+ DeviceFeatures.NO_FEATURES_SUPPORTED.toBuilder()
+ .setSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED)
+ .build()));
+ mTestLooper.dispatchAll();
+
+ // Audio system reports its initial audio status
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildReportAudioStatus(
+ Constants.ADDR_AUDIO_SYSTEM,
+ getLogicalAddress(),
+ 30,
+ false));
+ mTestLooper.dispatchAll();
+
+ verifyAbsoluteVolumeEnabled();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
index c878f99f7912..e5058bea8d1b 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
@@ -16,6 +16,7 @@
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2;
@@ -68,7 +69,8 @@ public class PowerStatusMonitorActionTest {
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
mHdmiControlService = new HdmiControlService(mContextSpy,
- Collections.singletonList(HdmiDeviceInfo.DEVICE_TV)) {
+ Collections.singletonList(HdmiDeviceInfo.DEVICE_TV),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
AudioManager getAudioManager() {
return new AudioManager() {
@@ -110,6 +112,7 @@ public class PowerStatusMonitorActionTest {
new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, false);
mNativeWrapper.setPortInfo(hdmiPortInfo);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(mContextSpy);
mHdmiControlService.setPowerManager(mPowerManager);
mPhysicalAddress = 0x0000;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
index 6184c2116e1d..f7983ca21816 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
@@ -16,6 +16,7 @@
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
@@ -96,8 +97,8 @@ public class RequestSadActionTest {
mMyLooper = mTestLooper.getLooper();
mHdmiControlService =
- new HdmiControlService(context,
- Collections.emptyList()) {
+ new HdmiControlService(context, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
boolean isControlEnabled() {
return true;
@@ -125,6 +126,7 @@ public class RequestSadActionTest {
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mLocalDevices.add(mHdmiCecLocalDeviceTv);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(context);
mHdmiControlService.setPowerManager(mPowerManager);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
index 0587864eeb20..566a7e0fecce 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
@@ -16,6 +16,7 @@
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
@@ -149,7 +150,7 @@ public class RoutingControlActionTest {
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext(),
- Collections.emptyList()) {
+ Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
boolean isControlEnabled() {
return true;
@@ -186,6 +187,7 @@ public class RoutingControlActionTest {
true, false, false);
mNativeWrapper.setPortInfo(hdmiPortInfos);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(context);
mHdmiControlService.setPowerManager(mPowerManager);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
index a34b55c00308..087e407e314c 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
@@ -20,6 +20,7 @@ import static android.hardware.hdmi.DeviceFeatures.FEATURE_NOT_SUPPORTED;
import static android.hardware.hdmi.DeviceFeatures.FEATURE_SUPPORTED;
import static android.hardware.hdmi.DeviceFeatures.FEATURE_SUPPORT_UNKNOWN;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.google.common.truth.Truth.assertThat;
@@ -81,7 +82,8 @@ public class SetAudioVolumeLevelDiscoveryActionTest {
mContextSpy = spy(new ContextWrapper(
InstrumentationRegistry.getInstrumentation().getTargetContext()));
- mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy, Collections.emptyList()));
+ mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()));
doNothing().when(mHdmiControlServiceSpy)
.writeStringSystemProperty(anyString(), anyString());
@@ -98,6 +100,7 @@ public class SetAudioVolumeLevelDiscoveryActionTest {
mHdmiControlServiceSpy.setHdmiMhlController(
HdmiMhlControllerStub.create(mHdmiControlServiceSpy));
mHdmiControlServiceSpy.initService();
+ mHdmiControlServiceSpy.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(mContextSpy);
mHdmiControlServiceSpy.setPowerManager(mPowerManager);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
index 9d143418fd4c..1644252e5739 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
@@ -17,6 +17,7 @@
package com.android.server.hdmi;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.SystemAudioAutoInitiationAction.RETRIES_ON_TIMEOUT;
@@ -69,7 +70,8 @@ public class SystemAudioAutoInitiationActionTest {
Looper myLooper = mTestLooper.getLooper();
- mHdmiControlService = new HdmiControlService(mContextSpy, Collections.emptyList()) {
+ mHdmiControlService = new HdmiControlService(mContextSpy, Collections.emptyList(),
+ new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
AudioManager getAudioManager() {
return new AudioManager() {
@@ -108,6 +110,7 @@ public class SystemAudioAutoInitiationActionTest {
new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true);
mNativeWrapper.setPortInfo(hdmiPortInfos);
mHdmiControlService.initService();
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(mContextSpy);
mHdmiControlService.setPowerManager(mPowerManager);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
index 095c69c776a2..c2f706ad1220 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -69,7 +69,7 @@ public class SystemAudioInitiationActionFromAvrTest {
Context context = InstrumentationRegistry.getTargetContext();
HdmiControlService hdmiControlService = new HdmiControlService(context,
- Collections.emptyList()) {
+ Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) {
@Override
void sendCecCommand(
HdmiCecMessage command, @Nullable SendMessageCallback callback) {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/TvToAudioSystemAvcTest.java b/services/tests/servicestests/src/com/android/server/hdmi/TvToAudioSystemAvcTest.java
new file mode 100644
index 000000000000..41c0e0d29879
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/TvToAudioSystemAvcTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.AudioDeviceAttributes;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for Absolute Volume Control where the local device is a TV and the System Audio device
+ * is an Audio System. Assumes that the TV uses ARC (rather than eARC).
+ */
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class TvToAudioSystemAvcTest extends BaseAbsoluteVolumeControlTest {
+
+ @Override
+ protected HdmiCecLocalDevice createLocalDevice(HdmiControlService hdmiControlService) {
+ return new HdmiCecLocalDeviceTv(hdmiControlService);
+ }
+
+ @Override
+ protected int getPhysicalAddress() {
+ return 0x0000;
+ }
+
+ @Override
+ protected int getDeviceType() {
+ return HdmiDeviceInfo.DEVICE_TV;
+ }
+
+ @Override
+ protected AudioDeviceAttributes getAudioOutputDevice() {
+ return HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_ARC;
+ }
+
+ @Override
+ protected int getSystemAudioDeviceLogicalAddress() {
+ return Constants.ADDR_AUDIO_SYSTEM;
+ }
+
+ @Override
+ protected int getSystemAudioDeviceType() {
+ return HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
index bd35be4d0f3e..c735d1868a62 100644
--- a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
@@ -22,7 +22,6 @@ import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
@@ -39,7 +38,6 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.HandlerThread;
import android.os.LocaleList;
@@ -102,8 +100,6 @@ public class LocaleManagerBackupRestoreTest {
@Mock
private Context mMockContext;
@Mock
- private PackageManagerInternal mMockPackageManagerInternal;
- @Mock
private PackageManager mMockPackageManager;
@Mock
private LocaleManagerService mMockLocaleManagerService;
@@ -129,7 +125,6 @@ public class LocaleManagerBackupRestoreTest {
@Before
public void setUp() throws Exception {
mMockContext = mock(Context.class);
- mMockPackageManagerInternal = mock(PackageManagerInternal.class);
mMockPackageManager = mock(PackageManager.class);
mMockLocaleManagerService = mock(LocaleManagerService.class);
SystemAppUpdateTracker systemAppUpdateTracker = mock(SystemAppUpdateTracker.class);
@@ -141,7 +136,7 @@ public class LocaleManagerBackupRestoreTest {
broadcastHandlerThread.start();
mBackupHelper = spy(new ShadowLocaleManagerBackupHelper(mMockContext,
- mMockLocaleManagerService, mMockPackageManagerInternal, mClock, STAGE_DATA,
+ mMockLocaleManagerService, mMockPackageManager, mClock, STAGE_DATA,
broadcastHandlerThread));
doNothing().when(mBackupHelper).notifyBackupManager();
@@ -158,8 +153,8 @@ public class LocaleManagerBackupRestoreTest {
@Test
public void testBackupPayload_noAppsInstalled_returnsNull() throws Exception {
- doReturn(List.of()).when(mMockPackageManagerInternal)
- .getInstalledApplications(anyLong(), anyInt(), anyInt());
+ doReturn(List.of()).when(mMockPackageManager)
+ .getInstalledApplicationsAsUser(any(), anyInt());
assertNull(mBackupHelper.getBackupPayload(DEFAULT_USER_ID));
}
@@ -198,8 +193,8 @@ public class LocaleManagerBackupRestoreTest {
ApplicationInfo anotherAppInfo = new ApplicationInfo();
defaultAppInfo.packageName = DEFAULT_PACKAGE_NAME;
anotherAppInfo.packageName = "com.android.anotherapp";
- doReturn(List.of(defaultAppInfo, anotherAppInfo)).when(mMockPackageManagerInternal)
- .getInstalledApplications(anyLong(), anyInt(), anyInt());
+ doReturn(List.of(defaultAppInfo, anotherAppInfo)).when(mMockPackageManager)
+ .getInstalledApplicationsAsUser(any(), anyInt());
setUpLocalesForPackage(DEFAULT_PACKAGE_NAME, DEFAULT_LOCALES);
// Exception when getting locales for anotherApp.
@@ -447,8 +442,8 @@ public class LocaleManagerBackupRestoreTest {
// Retention period has not elapsed.
setCurrentTimeMillis(
DEFAULT_CREATION_TIME_MILLIS + RETENTION_PERIOD.minusHours(1).toMillis());
- doReturn(List.of()).when(mMockPackageManagerInternal)
- .getInstalledApplications(anyLong(), anyInt(), anyInt());
+ doReturn(List.of()).when(mMockPackageManager)
+ .getInstalledApplicationsAsUser(any(), anyInt());
assertNull(mBackupHelper.getBackupPayload(DEFAULT_USER_ID));
checkStageDataExists(DEFAULT_USER_ID);
@@ -456,8 +451,8 @@ public class LocaleManagerBackupRestoreTest {
// Exactly RETENTION_PERIOD amount of time has passed so stage data should still not be
// removed.
setCurrentTimeMillis(DEFAULT_CREATION_TIME_MILLIS + RETENTION_PERIOD.toMillis());
- doReturn(List.of()).when(mMockPackageManagerInternal)
- .getInstalledApplications(anyLong(), anyInt(), anyInt());
+ doReturn(List.of()).when(mMockPackageManager)
+ .getInstalledApplicationsAsUser(any(), anyInt());
assertNull(mBackupHelper.getBackupPayload(DEFAULT_USER_ID));
checkStageDataExists(DEFAULT_USER_ID);
@@ -465,8 +460,8 @@ public class LocaleManagerBackupRestoreTest {
// Retention period has now expired, stage data should be deleted.
setCurrentTimeMillis(
DEFAULT_CREATION_TIME_MILLIS + RETENTION_PERIOD.plusSeconds(1).toMillis());
- doReturn(List.of()).when(mMockPackageManagerInternal)
- .getInstalledApplications(anyLong(), anyInt(), anyInt());
+ doReturn(List.of()).when(mMockPackageManager)
+ .getInstalledApplicationsAsUser(any(), anyInt());
assertNull(mBackupHelper.getBackupPayload(DEFAULT_USER_ID));
checkStageDataDoesNotExist(DEFAULT_USER_ID);
@@ -577,8 +572,8 @@ public class LocaleManagerBackupRestoreTest {
private void setUpDummyAppForPackageManager(String packageName) {
ApplicationInfo dummyApp = new ApplicationInfo();
dummyApp.packageName = packageName;
- doReturn(List.of(dummyApp)).when(mMockPackageManagerInternal)
- .getInstalledApplications(anyLong(), anyInt(), anyInt());
+ doReturn(List.of(dummyApp)).when(mMockPackageManager)
+ .getInstalledApplicationsAsUser(any(), anyInt());
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
index 0b3ef4542cbf..1dcdbac8a7c2 100644
--- a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
@@ -23,7 +23,6 @@ import static junit.framework.Assert.fail;
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.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
@@ -40,7 +39,6 @@ import android.content.Context;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.LocaleList;
@@ -80,7 +78,7 @@ public class LocaleManagerServiceTest {
@Mock
private Context mMockContext;
@Mock
- private PackageManagerInternal mMockPackageManagerInternal;
+ private PackageManager mMockPackageManager;
@Mock
private FakePackageConfigurationUpdater mFakePackageConfigurationUpdater;
@Mock
@@ -95,14 +93,13 @@ public class LocaleManagerServiceTest {
mMockContext = mock(Context.class);
mMockActivityTaskManager = mock(ActivityTaskManagerInternal.class);
mMockActivityManager = mock(ActivityManagerInternal.class);
- mMockPackageManagerInternal = mock(PackageManagerInternal.class);
+ mMockPackageManager = mock(PackageManager.class);
mMockPackageMonitor = mock(PackageMonitor.class);
// For unit tests, set the default installer info
- PackageManager mockPackageManager = mock(PackageManager.class);
- doReturn(DEFAULT_INSTALL_SOURCE_INFO).when(mockPackageManager)
+ doReturn(DEFAULT_INSTALL_SOURCE_INFO).when(mMockPackageManager)
.getInstallSourceInfo(anyString());
- doReturn(mockPackageManager).when(mMockContext).getPackageManager();
+ doReturn(mMockPackageManager).when(mMockContext).getPackageManager();
mFakePackageConfigurationUpdater = new FakePackageConfigurationUpdater();
doReturn(mFakePackageConfigurationUpdater)
@@ -117,14 +114,14 @@ public class LocaleManagerServiceTest {
mMockBackupHelper = mock(ShadowLocaleManagerBackupHelper.class);
mLocaleManagerService = new LocaleManagerService(mMockContext, mMockActivityTaskManager,
- mMockActivityManager, mMockPackageManagerInternal,
+ mMockActivityManager, mMockPackageManager,
mMockBackupHelper, mMockPackageMonitor);
}
@Test(expected = SecurityException.class)
public void testSetApplicationLocales_arbitraryAppWithoutPermissions_fails() throws Exception {
doReturn(DEFAULT_UID)
- .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
+ .when(mMockPackageManager).getPackageUidAsUser(anyString(), any(), anyInt());
setUpFailingPermissionCheckFor(Manifest.permission.CHANGE_CONFIGURATION);
try {
@@ -170,7 +167,7 @@ public class LocaleManagerServiceTest {
@Test
public void testSetApplicationLocales_arbitraryAppWithPermission_succeeds() throws Exception {
doReturn(DEFAULT_UID)
- .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
+ .when(mMockPackageManager).getPackageUidAsUser(anyString(), any(), anyInt());
// if package is not owned by the caller, the calling app should have the following
// permission. We will mock this to succeed to imitate that.
setUpPassingPermissionCheckFor(Manifest.permission.CHANGE_CONFIGURATION);
@@ -186,7 +183,7 @@ public class LocaleManagerServiceTest {
@Test
public void testSetApplicationLocales_callerOwnsPackage_succeeds() throws Exception {
doReturn(Binder.getCallingUid())
- .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
+ .when(mMockPackageManager).getPackageUidAsUser(anyString(), any(), anyInt());
mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID,
DEFAULT_LOCALES);
@@ -197,8 +194,8 @@ public class LocaleManagerServiceTest {
@Test(expected = IllegalArgumentException.class)
public void testSetApplicationLocales_invalidPackageOrUserId_fails() throws Exception {
- doReturn(INVALID_UID)
- .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
+ doThrow(new PackageManager.NameNotFoundException("Mock"))
+ .when(mMockPackageManager).getPackageUidAsUser(anyString(), any(), anyInt());
try {
mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID,
LocaleList.getEmptyLocaleList());
@@ -211,8 +208,8 @@ public class LocaleManagerServiceTest {
@Test(expected = SecurityException.class)
public void testGetApplicationLocales_arbitraryAppWithoutPermission_fails() throws Exception {
- doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
- .getPackageUid(anyString(), anyLong(), anyInt());
+ doReturn(DEFAULT_UID).when(mMockPackageManager)
+ .getPackageUidAsUser(anyString(), any(), anyInt());
setUpFailingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
try {
@@ -229,8 +226,8 @@ public class LocaleManagerServiceTest {
public void testGetApplicationLocales_appSpecificConfigAbsent_returnsEmptyList()
throws Exception {
// any valid app calling for its own package or having appropriate permission
- doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
- .getPackageUid(anyString(), anyLong(), anyInt());
+ doReturn(DEFAULT_UID).when(mMockPackageManager)
+ .getPackageUidAsUser(anyString(), any(), anyInt());
setUpPassingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
doReturn(null)
.when(mMockActivityTaskManager).getApplicationConfig(anyString(), anyInt());
@@ -244,8 +241,8 @@ public class LocaleManagerServiceTest {
@Test
public void testGetApplicationLocales_appSpecificLocalesAbsent_returnsEmptyList()
throws Exception {
- doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
- .getPackageUid(anyString(), anyLong(), anyInt());
+ doReturn(DEFAULT_UID).when(mMockPackageManager)
+ .getPackageUidAsUser(anyString(), any(), anyInt());
setUpPassingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
doReturn(new PackageConfig(/* nightMode = */ 0, /* locales = */ null))
.when(mMockActivityTaskManager).getApplicationConfig(any(), anyInt());
@@ -259,8 +256,8 @@ public class LocaleManagerServiceTest {
@Test
public void testGetApplicationLocales_callerOwnsAppAndConfigPresent_returnsLocales()
throws Exception {
- doReturn(Binder.getCallingUid()).when(mMockPackageManagerInternal)
- .getPackageUid(anyString(), anyLong(), anyInt());
+ doReturn(Binder.getCallingUid()).when(mMockPackageManager)
+ .getPackageUidAsUser(anyString(), any(), anyInt());
doReturn(new PackageConfig(/* nightMode = */ 0, DEFAULT_LOCALES))
.when(mMockActivityTaskManager).getApplicationConfig(anyString(), anyInt());
@@ -273,8 +270,8 @@ public class LocaleManagerServiceTest {
@Test
public void testGetApplicationLocales_arbitraryCallerWithPermissions_returnsLocales()
throws Exception {
- doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
- .getPackageUid(anyString(), anyLong(), anyInt());
+ doReturn(DEFAULT_UID).when(mMockPackageManager)
+ .getPackageUidAsUser(anyString(), any(), anyInt());
setUpPassingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
doReturn(new PackageConfig(/* nightMode = */ 0, DEFAULT_LOCALES))
.when(mMockActivityTaskManager).getApplicationConfig(anyString(), anyInt());
@@ -288,10 +285,10 @@ public class LocaleManagerServiceTest {
@Test
public void testGetApplicationLocales_callerIsInstaller_returnsLocales()
throws Exception {
- doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
- .getPackageUid(eq(DEFAULT_PACKAGE_NAME), anyLong(), anyInt());
- doReturn(Binder.getCallingUid()).when(mMockPackageManagerInternal)
- .getPackageUid(eq(DEFAULT_INSTALLER_PACKAGE_NAME), anyLong(), anyInt());
+ doReturn(DEFAULT_UID).when(mMockPackageManager)
+ .getPackageUidAsUser(eq(DEFAULT_PACKAGE_NAME), any(), anyInt());
+ doReturn(Binder.getCallingUid()).when(mMockPackageManager)
+ .getPackageUidAsUser(eq(DEFAULT_INSTALLER_PACKAGE_NAME), any(), anyInt());
doReturn(new PackageConfig(/* nightMode = */ 0, DEFAULT_LOCALES))
.when(mMockActivityTaskManager).getApplicationConfig(anyString(), anyInt());
diff --git a/services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java b/services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java
index ad9be0d5fe8d..e403c87f65d9 100644
--- a/services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java
+++ b/services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java
@@ -17,7 +17,7 @@
package com.android.server.locales;
import android.content.Context;
-import android.content.pm.PackageManagerInternal;
+import android.content.pm.PackageManager;
import android.os.HandlerThread;
import android.util.SparseArray;
@@ -31,9 +31,10 @@ import java.time.Clock;
public class ShadowLocaleManagerBackupHelper extends LocaleManagerBackupHelper {
ShadowLocaleManagerBackupHelper(Context context,
LocaleManagerService localeManagerService,
- PackageManagerInternal pmInternal, Clock clock,
+ PackageManager packageManager, Clock clock,
SparseArray<LocaleManagerBackupHelper.StagedData> stagedData,
HandlerThread broadcastHandlerThread) {
- super(context, localeManagerService, pmInternal, clock, stagedData, broadcastHandlerThread);
+ super(context, localeManagerService, packageManager, clock, stagedData,
+ broadcastHandlerThread);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
index db602ca83f30..808b74e31029 100644
--- a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
@@ -38,7 +38,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.Environment;
import android.os.LocaleList;
@@ -93,8 +92,6 @@ public class SystemAppUpdateTrackerTest {
@Mock
PackageManager mMockPackageManager;
@Mock
- private PackageManagerInternal mMockPackageManagerInternal;
- @Mock
private ActivityTaskManagerInternal mMockActivityTaskManager;
@Mock
private ActivityManagerInternal mMockActivityManager;
@@ -110,21 +107,20 @@ public class SystemAppUpdateTrackerTest {
mMockContext = mock(Context.class);
mMockActivityTaskManager = mock(ActivityTaskManagerInternal.class);
mMockActivityManager = mock(ActivityManagerInternal.class);
- mMockPackageManagerInternal = mock(PackageManagerInternal.class);
+ mMockPackageManager = mock(PackageManager.class);
LocaleManagerBackupHelper mockLocaleManagerBackupHelper =
mock(ShadowLocaleManagerBackupHelper.class);
// PackageMonitor is not needed in LocaleManagerService for these tests hence it is
// passed as null.
mLocaleManagerService = new LocaleManagerService(mMockContext,
mMockActivityTaskManager, mMockActivityManager,
- mMockPackageManagerInternal, mockLocaleManagerBackupHelper,
+ mMockPackageManager, mockLocaleManagerBackupHelper,
/* mPackageMonitor= */ null);
doReturn(DEFAULT_USER_ID).when(mMockActivityManager)
.handleIncomingUser(anyInt(), anyInt(), eq(DEFAULT_USER_ID), anyBoolean(), anyInt(),
anyString(), anyString());
- mMockPackageManager = mock(PackageManager.class);
doReturn(DEFAULT_INSTALL_SOURCE_INFO).when(mMockPackageManager)
.getInstallSourceInfo(anyString());
doReturn(mMockPackageManager).when(mMockContext).getPackageManager();
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 7634b09b4dc6..6c7f87244cfe 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -441,14 +441,14 @@ public class NetworkPolicyManagerServiceTest {
setNetpolicyXml(context);
doAnswer(new Answer<Void>() {
-
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
mUidObserver = (IUidObserver) invocation.getArguments()[0];
Log.d(TAG, "set mUidObserver to " + mUidObserver);
return null;
}
- }).when(mActivityManager).registerUidObserver(any(), anyInt(), anyInt(), any(String.class));
+ }).when(mActivityManagerInternal).registerNetworkPolicyUidObserver(any(),
+ anyInt(), anyInt(), any(String.class));
mFutureIntent = newRestrictBackgroundChangedFuture();
mDeps = new TestDependencies(mServiceContext);
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index d8f4349b95bf..b72b8d2ec6e8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -77,7 +77,7 @@ import java.util.concurrent.Executor;
@Presubmit
@RunWith(JUnit4.class)
-public class AppsFilterImplTest {
+public class AppsFilterTest {
private static final int DUMMY_CALLING_APPID = 10345;
private static final int DUMMY_TARGET_APPID = 10556;
@@ -98,9 +98,9 @@ public class AppsFilterImplTest {
}
@Mock
- AppsFilterImpl.FeatureConfig mFeatureConfigMock;
+ AppsFilter.FeatureConfig mFeatureConfigMock;
@Mock
- AppsFilterImpl.StateProvider mStateProvider;
+ AppsFilter.StateProvider mStateProvider;
@Mock
Executor mMockExecutor;
@Mock
@@ -204,11 +204,11 @@ public class AppsFilterImplTest {
MockitoAnnotations.initMocks(this);
doAnswer(invocation -> {
- ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0))
+ ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0))
.currentState(mExisting, USER_INFO_LIST);
return new Object();
}).when(mStateProvider)
- .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class));
+ .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class));
doAnswer(invocation -> {
((Runnable) invocation.getArgument(0)).run();
@@ -218,14 +218,14 @@ public class AppsFilterImplTest {
when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true);
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer(
(Answer<Boolean>) invocation ->
- ((AndroidPackage) invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion()
+ ((AndroidPackage)invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion()
>= Build.VERSION_CODES.R);
}
@Test
public void testSystemReadyPropogates() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -236,8 +236,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_FilterMatches() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -259,8 +259,8 @@ public class AppsFilterImplTest {
}
@Test
public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -308,8 +308,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesProvider_FilterMatches() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -333,8 +333,8 @@ public class AppsFilterImplTest {
@Test
public void testOnUserUpdated_FilterMatches() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
@@ -356,11 +356,11 @@ public class AppsFilterImplTest {
// adds new user
doAnswer(invocation -> {
- ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0))
+ ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0))
.currentState(mExisting, USER_INFO_LIST_WITH_ADDED);
return new Object();
}).when(mStateProvider)
- .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class));
+ .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class));
appsFilter.onUserCreated(ADDED_USER);
for (int subjectUserId : USER_ARRAY_WITH_ADDED) {
@@ -373,11 +373,11 @@ public class AppsFilterImplTest {
// delete user
doAnswer(invocation -> {
- ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0))
+ ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0))
.currentState(mExisting, USER_INFO_LIST);
return new Object();
}).when(mStateProvider)
- .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class));
+ .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class));
appsFilter.onUserDeleted(ADDED_USER);
for (int subjectUserId : USER_ARRAY) {
@@ -391,8 +391,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesDifferentProvider_Filters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -416,8 +416,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -435,8 +435,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -452,8 +452,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -473,8 +473,8 @@ public class AppsFilterImplTest {
@Test
public void testNoQueries_Filters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -490,7 +490,7 @@ public class AppsFilterImplTest {
@Test
public void testNoUsesLibrary_Filters() throws Exception {
- final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+ final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockExecutor, mMockPmInternal);
@@ -516,7 +516,7 @@ public class AppsFilterImplTest {
@Test
public void testUsesLibrary_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+ final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockExecutor, mMockPmInternal);
@@ -543,7 +543,7 @@ public class AppsFilterImplTest {
@Test
public void testUsesOptionalLibrary_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+ final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockExecutor, mMockPmInternal);
@@ -570,7 +570,7 @@ public class AppsFilterImplTest {
@Test
public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+ final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockExecutor, mMockPmInternal);
@@ -602,8 +602,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryable_SystemDoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -621,8 +621,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryable_NonSystemFilters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -638,10 +638,9 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
- new String[]{"com.some.package"}, false, null,
- mMockExecutor, mMockPmInternal);
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"},
+ false, null, mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -658,8 +657,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
appsFilter.onSystemReady();
@@ -687,10 +686,9 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
- new String[]{"com.some.package"}, false, null,
- mMockExecutor, mMockPmInternal);
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"},
+ false, null, mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -706,8 +704,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemQueryable_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{},
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{},
true /* system force queryable */, null, mMockExecutor,
mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
@@ -725,8 +723,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesPackage_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -744,8 +742,8 @@ public class AppsFilterImplTest {
public void testNoQueries_FeatureOff_DoesntFilter() throws Exception {
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
.thenReturn(false);
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -761,8 +759,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemUid_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -777,8 +775,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemUidSecondaryUser_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -794,8 +792,8 @@ public class AppsFilterImplTest {
@Test
public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -809,8 +807,8 @@ public class AppsFilterImplTest {
@Test
public void testNoTargetPackage_filters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -840,7 +838,7 @@ public class AppsFilterImplTest {
.setOverlayTargetOverlayableName("overlayableName");
ParsingPackage actor = pkg("com.some.package.actor");
- final AppsFilterImpl appsFilter = new AppsFilterImpl(
+ final AppsFilter appsFilter = new AppsFilter(
mStateProvider,
mFeatureConfigMock,
new String[]{},
@@ -935,7 +933,7 @@ public class AppsFilterImplTest {
when(mMockPmInternal.getSharedUserPackages(any(Integer.class))).thenReturn(
actorSharedSettingPackages
);
- final AppsFilterImpl appsFilter = new AppsFilterImpl(
+ final AppsFilter appsFilter = new AppsFilter(
mStateProvider,
mFeatureConfigMock,
new String[]{},
@@ -987,8 +985,8 @@ public class AppsFilterImplTest {
@Test
public void testInitiatingApp_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -1005,8 +1003,8 @@ public class AppsFilterImplTest {
@Test
public void testUninstalledInitiatingApp_Filters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -1023,8 +1021,8 @@ public class AppsFilterImplTest {
@Test
public void testOriginatingApp_Filters() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -1048,8 +1046,8 @@ public class AppsFilterImplTest {
@Test
public void testInstallingApp_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -1073,8 +1071,8 @@ public class AppsFilterImplTest {
@Test
public void testInstrumentation_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -1102,8 +1100,8 @@ public class AppsFilterImplTest {
@Test
public void testWhoCanSee() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -1175,8 +1173,8 @@ public class AppsFilterImplTest {
@Test
public void testOnChangeReport() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
@@ -1248,8 +1246,8 @@ public class AppsFilterImplTest {
@Test
public void testOnChangeReportedFilter() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor, mMockPmInternal);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -1272,53 +1270,6 @@ public class AppsFilterImplTest {
watcher.verifyNoChangeReported("shouldFilterApplication");
}
- @Test
- public void testAppsFilterRead() throws Exception {
- final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
- mMockExecutor, mMockPmInternal);
- simulateAddBasicAndroid(appsFilter);
- appsFilter.onSystemReady();
-
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
- DUMMY_TARGET_APPID);
- PackageSetting instrumentation = simulateAddPackage(appsFilter,
- pkgWithInstrumentation("com.some.other.package", "com.some.package"),
- DUMMY_CALLING_APPID);
-
- final int hasProviderAppId = Process.FIRST_APPLICATION_UID + 1;
- final int queriesProviderAppId = Process.FIRST_APPLICATION_UID + 2;
- PackageSetting queriesProvider = simulateAddPackage(appsFilter,
- pkgQueriesProvider("com.yet.some.other.package", "com.some.authority"),
- queriesProviderAppId);
- appsFilter.grantImplicitAccess(
- hasProviderAppId, queriesProviderAppId, false /* retainOnUpdate */);
-
- AppsFilterSnapshot snapshot = appsFilter.snapshot();
- assertFalse(
- snapshot.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
- SYSTEM_USER));
- assertFalse(
- snapshot.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation,
- SYSTEM_USER));
-
- SparseArray<int[]> queriesProviderFilter =
- snapshot.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
- assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)), contains(queriesProviderAppId));
- assertTrue(snapshot.canQueryPackage(instrumentation.getPkg(),
- target.getPackageName()));
-
- // New changes don't affect the snapshot
- appsFilter.removePackage(target, false);
- assertTrue(
- appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
- SYSTEM_USER));
- assertFalse(
- snapshot.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
- SYSTEM_USER));
-
- }
-
private List<Integer> toList(int[] array) {
ArrayList<Integer> ret = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {
@@ -1331,7 +1282,7 @@ public class AppsFilterImplTest {
PackageSettingBuilder withBuilder(PackageSettingBuilder builder);
}
- private void simulateAddBasicAndroid(AppsFilterImpl appsFilter) throws Exception {
+ private void simulateAddBasicAndroid(AppsFilter appsFilter) throws Exception {
final Signature frameworkSignature = Mockito.mock(Signature.class);
final SigningDetails frameworkSigningDetails =
new SigningDetails(new Signature[]{frameworkSignature}, 1);
@@ -1340,17 +1291,17 @@ public class AppsFilterImplTest {
b -> b.setSigningDetails(frameworkSigningDetails));
}
- private PackageSetting simulateAddPackage(AppsFilterImpl filter,
+ private PackageSetting simulateAddPackage(AppsFilter filter,
ParsingPackage newPkgBuilder, int appId) {
return simulateAddPackage(filter, newPkgBuilder, appId, null /*settingBuilder*/);
}
- private PackageSetting simulateAddPackage(AppsFilterImpl filter,
+ private PackageSetting simulateAddPackage(AppsFilter filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action) {
return simulateAddPackage(filter, newPkgBuilder, appId, action, null /*sharedUserSetting*/);
}
- private PackageSetting simulateAddPackage(AppsFilterImpl filter,
+ private PackageSetting simulateAddPackage(AppsFilter filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action,
@Nullable SharedUserSetting sharedUserSetting) {
final PackageSetting setting =
@@ -1373,7 +1324,7 @@ public class AppsFilterImplTest {
return setting;
}
- private void simulateAddPackage(PackageSetting setting, AppsFilterImpl filter,
+ private void simulateAddPackage(PackageSetting setting, AppsFilter filter,
@Nullable SharedUserSetting sharedUserSetting) {
mExisting.put(setting.getPackageName(), setting);
if (sharedUserSetting != null) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
index 004d7bc2707c..07cca0ca6ba0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
@@ -84,15 +84,15 @@ import java.util.function.Function;
@RunWith(AndroidJUnit4.class)
public class PackageParserLegacyCoreTest {
private static final String RELEASED = null;
- private static final String OLDER_PRE_RELEASE = "A";
- private static final String PRE_RELEASE = "B";
- private static final String NEWER_PRE_RELEASE = "C";
+ private static final String OLDER_PRE_RELEASE = "Q";
+ private static final String PRE_RELEASE = "R";
+ private static final String NEWER_PRE_RELEASE = "Z";
// Codenames with a fingerprint attached to them. These may only be present in the apps
// declared min SDK and not as platform codenames.
- private static final String OLDER_PRE_RELEASE_WITH_FINGERPRINT = "A.fingerprint";
- private static final String PRE_RELEASE_WITH_FINGERPRINT = "B.fingerprint";
- private static final String NEWER_PRE_RELEASE_WITH_FINGERPRINT = "C.fingerprint";
+ private static final String OLDER_PRE_RELEASE_WITH_FINGERPRINT = "Q.fingerprint";
+ private static final String PRE_RELEASE_WITH_FINGERPRINT = "R.fingerprint";
+ private static final String NEWER_PRE_RELEASE_WITH_FINGERPRINT = "Z.fingerprint";
private static final String[] CODENAMES_RELEASED = { /* empty */};
private static final String[] CODENAMES_PRE_RELEASE = {PRE_RELEASE};
@@ -199,13 +199,14 @@ public class PackageParserLegacyCoreTest {
}
private void verifyComputeTargetSdkVersion(int targetSdkVersion, String targetSdkCodename,
- boolean isPlatformReleased, int expectedTargetSdk) {
+ boolean isPlatformReleased, boolean allowUnknownCodenames, int expectedTargetSdk) {
final ParseTypeImpl input = ParseTypeImpl.forParsingWithoutPlatformCompat();
final ParseResult<Integer> result = FrameworkParsingPackageUtils.computeTargetSdkVersion(
targetSdkVersion,
targetSdkCodename,
isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
- input);
+ input,
+ allowUnknownCodenames);
if (expectedTargetSdk == -1) {
assertTrue(result.isError());
@@ -220,40 +221,61 @@ public class PackageParserLegacyCoreTest {
// Do allow older release targetSdkVersion on pre-release platform.
// APP: Released API 10
// DEV: Pre-release API 20
- verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION);
+ verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, false, false, OLDER_VERSION);
// Do allow same release targetSdkVersion on pre-release platform.
// APP: Released API 20
// DEV: Pre-release API 20
- verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION);
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, false, false, PLATFORM_VERSION);
// Do allow newer release targetSdkVersion on pre-release platform.
// APP: Released API 30
// DEV: Pre-release API 20
- verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, false, NEWER_VERSION);
+ verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, false, false, NEWER_VERSION);
// Don't allow older pre-release targetSdkVersion on pre-release platform.
// APP: Pre-release API 10
// DEV: Pre-release API 20
- verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1);
- verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);
+ verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, false, -1);
+ verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false,
+ false, -1
+ );
+ // Don't allow older pre-release targetSdkVersion on pre-release platform when
+ // allowUnknownCodenames is true.
+ // APP: Pre-release API 10
+ // DEV: Pre-release API 20
+ verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false,
+ true, -1);
+ verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false,
+ true, -1);
// Do allow same pre-release targetSdkVersion on pre-release platform,
// but overwrite the specified version with CUR_DEVELOPMENT.
// APP: Pre-release API 20
// DEV: Pre-release API 20
verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
- Build.VERSION_CODES.CUR_DEVELOPMENT);
+ false, Build.VERSION_CODES.CUR_DEVELOPMENT);
verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, false,
- Build.VERSION_CODES.CUR_DEVELOPMENT);
-
+ false, Build.VERSION_CODES.CUR_DEVELOPMENT);
// Don't allow newer pre-release targetSdkVersion on pre-release platform.
// APP: Pre-release API 30
// DEV: Pre-release API 20
- verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1);
- verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, false, -1);
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false,
+ false, -1
+ );
+
+ // Do allow newer pre-release targetSdkVersion on pre-release platform when
+ // allowUnknownCodenames is true.
+ // APP: Pre-release API 30
+ // DEV: Pre-release API 20
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false,
+ true, Build.VERSION_CODES.CUR_DEVELOPMENT);
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false,
+ true, Build.VERSION_CODES.CUR_DEVELOPMENT);
+
}
@Test
@@ -261,36 +283,58 @@ public class PackageParserLegacyCoreTest {
// Do allow older release targetSdkVersion on released platform.
// APP: Released API 10
// DEV: Released API 20
- verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION);
+ verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, true, false, OLDER_VERSION);
// Do allow same release targetSdkVersion on released platform.
// APP: Released API 20
// DEV: Released API 20
- verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION);
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, true, false, PLATFORM_VERSION);
// Do allow newer release targetSdkVersion on released platform.
// APP: Released API 30
// DEV: Released API 20
- verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, true, NEWER_VERSION);
+ verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, true, false, NEWER_VERSION);
// Don't allow older pre-release targetSdkVersion on released platform.
// APP: Pre-release API 10
// DEV: Released API 20
- verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1);
- verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);
+ verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, false, -1);
+ verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, true,
+ false, -1
+ );
// Don't allow same pre-release targetSdkVersion on released platform.
// APP: Pre-release API 20
// DEV: Released API 20
- verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1);
- verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, -1);
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, false, -1);
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, false,
+ -1
+ );
+ // Don't allow same pre-release targetSdkVersion on released platform when
+ // allowUnknownCodenames is true.
+ // APP: Pre-release API 20
+ // DEV: Released API 20
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, true,
+ -1);
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, true,
+ -1);
// Don't allow newer pre-release targetSdkVersion on released platform.
// APP: Pre-release API 30
// DEV: Released API 20
- verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1);
- verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, false, -1);
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true,
+ false, -1
+ );
+ // Do allow newer pre-release targetSdkVersion on released platform when
+ // allowUnknownCodenames is true.
+ // APP: Pre-release API 30
+ // DEV: Released API 20
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, true,
+ Build.VERSION_CODES.CUR_DEVELOPMENT);
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true,
+ true, Build.VERSION_CODES.CUR_DEVELOPMENT);
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
index 6bdd88c6a712..2d0755d00ba8 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
@@ -20,18 +20,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
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.atLeast;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -56,32 +53,20 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.ArgumentCaptor;
-import java.util.LinkedList;
-import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@RunWith(Parameterized.class)
public class SoundHw2CompatTest {
- @Parameterized.Parameter(0) public String mVersion;
- @Parameterized.Parameter(1) public boolean mSupportConcurrentCapture;
+ @Parameterized.Parameter public String mVersion;
private final Runnable mRebootRunnable = mock(Runnable.class);
private ISoundTriggerHal mCanonical;
- private CaptureStateNotifier mCaptureStateNotifier;
private android.hardware.soundtrigger.V2_0.ISoundTriggerHw mHalDriver;
// We run the test once for every version of the underlying driver.
- @Parameterized.Parameters(name = "{0}, concurrent={1}")
- public static Iterable<Object[]> data() {
- List<Object[]> result = new LinkedList<>();
-
- for (String version : new String[]{"V2_0", "V2_1", "V2_2", "V2_3",}) {
- for (boolean concurrentCapture : new boolean[]{false, true}) {
- result.add(new Object[]{version, concurrentCapture});
- }
- }
-
- return result;
+ @Parameterized.Parameters
+ public static Object[] data() {
+ return new String[]{"V2_0", "V2_1", "V2_2", "V2_3"};
}
@Before
@@ -139,7 +124,7 @@ public class SoundHw2CompatTest {
when(mHalDriver.asBinder()).thenReturn(binder);
android.hardware.soundtrigger.V2_3.Properties halProperties =
- TestUtil.createDefaultProperties_2_3(mSupportConcurrentCapture);
+ TestUtil.createDefaultProperties_2_3();
doAnswer(invocation -> {
((android.hardware.soundtrigger.V2_0.ISoundTriggerHw.getPropertiesCallback) invocation.getArgument(
0)).onValues(0, halProperties.base);
@@ -156,10 +141,7 @@ public class SoundHw2CompatTest {
}).when(driver).getProperties_2_3(any());
}
- mCaptureStateNotifier = spy(new CaptureStateNotifier());
-
- mCanonical = SoundTriggerHw2Compat.create(mHalDriver, mRebootRunnable,
- mCaptureStateNotifier);
+ mCanonical = SoundTriggerHw2Compat.create(mHalDriver, mRebootRunnable, null);
// During initialization any method can be called, but after we're starting to enforce that
// no additional methods are called.
@@ -171,7 +153,6 @@ public class SoundHw2CompatTest {
mCanonical.detach();
verifyNoMoreInteractions(mHalDriver);
verifyNoMoreInteractions(mRebootRunnable);
- mCaptureStateNotifier.verifyNoMoreListeners();
}
@Test
@@ -194,12 +175,12 @@ public class SoundHw2CompatTest {
// It is OK for the SUT to cache the properties, so the underlying method doesn't
// need to be called every single time.
verify(driver, atMost(1)).getProperties_2_3(any());
- TestUtil.validateDefaultProperties(properties, mSupportConcurrentCapture);
+ TestUtil.validateDefaultProperties(properties);
} else {
// It is OK for the SUT to cache the properties, so the underlying method doesn't
// need to be called every single time.
verify(mHalDriver, atMost(1)).getProperties(any());
- TestUtil.validateDefaultProperties(properties, mSupportConcurrentCapture, 0, "");
+ TestUtil.validateDefaultProperties(properties, 0, "");
}
}
@@ -291,7 +272,7 @@ public class SoundHw2CompatTest {
ISoundTriggerHal.ModelCallback canonicalCallback = mock(
ISoundTriggerHal.ModelCallback.class);
- final int maxModels = TestUtil.createDefaultProperties_2_0(false).maxSoundModels;
+ final int maxModels = TestUtil.createDefaultProperties_2_0().maxSoundModels;
int[] modelHandles = new int[maxModels];
// Load as many models as we're allowed.
@@ -318,7 +299,7 @@ public class SoundHw2CompatTest {
verify(globalCallback).onResourcesAvailable();
}
- private int loadPhraseModel_2_0(ISoundTriggerHal.ModelCallback canonicalCallback)
+ private void loadPhraseModel_2_0(ISoundTriggerHal.ModelCallback canonicalCallback)
throws Exception {
final int handle = 29;
ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel>
@@ -345,10 +326,9 @@ public class SoundHw2CompatTest {
TestUtil.validatePhraseSoundModel_2_0(modelCaptor.getValue());
validateCallback_2_0(callbackCaptor.getValue(), canonicalCallback);
- return handle;
}
- private int loadPhraseModel_2_1(ISoundTriggerHal.ModelCallback canonicalCallback)
+ private void loadPhraseModel_2_1(ISoundTriggerHal.ModelCallback canonicalCallback)
throws Exception {
final android.hardware.soundtrigger.V2_1.ISoundTriggerHw driver_2_1 =
(android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver;
@@ -380,14 +360,13 @@ public class SoundHw2CompatTest {
TestUtil.validatePhraseSoundModel_2_1(model.get());
validateCallback_2_1(callbackCaptor.getValue(), canonicalCallback);
- return handle;
}
- public int loadPhraseModel(ISoundTriggerHal.ModelCallback canonicalCallback) throws Exception {
+ public void loadPhraseModel(ISoundTriggerHal.ModelCallback canonicalCallback) throws Exception {
if (mHalDriver instanceof android.hardware.soundtrigger.V2_1.ISoundTriggerHw) {
- return loadPhraseModel_2_1(canonicalCallback);
+ loadPhraseModel_2_1(canonicalCallback);
} else {
- return loadPhraseModel_2_0(canonicalCallback);
+ loadPhraseModel_2_0(canonicalCallback);
}
}
@@ -484,80 +463,6 @@ public class SoundHw2CompatTest {
}
@Test
- public void testConcurrentCaptureAbort() throws Exception {
- assumeFalse(mSupportConcurrentCapture);
- verify(mCaptureStateNotifier, atLeast(1)).registerListener(any());
-
- // Register global callback.
- ISoundTriggerHal.GlobalCallback globalCallback = mock(
- ISoundTriggerHal.GlobalCallback.class);
- mCanonical.registerCallback(globalCallback);
-
- // Load.
- ISoundTriggerHal.ModelCallback canonicalCallback = mock(
- ISoundTriggerHal.ModelCallback.class);
- final int handle = loadGenericModel(canonicalCallback);
-
- // Then start.
- startRecognition(handle, canonicalCallback);
-
- // Now activate external capture.
- mCaptureStateNotifier.setState(true);
-
- // Expect hardware to have been stopped.
- verify(mHalDriver).stopRecognition(handle);
-
- // Expect an abort event (async).
- ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
- RecognitionEvent.class);
- mCanonical.flushCallbacks();
- verify(canonicalCallback).recognitionCallback(eq(handle), eventCaptor.capture());
- assertEquals(RecognitionStatus.ABORTED, eventCaptor.getValue().status);
-
- // Deactivate external capture.
- mCaptureStateNotifier.setState(false);
-
- // Expect a onResourcesAvailable().
- mCanonical.flushCallbacks();
- verify(globalCallback).onResourcesAvailable();
- }
-
- @Test
- public void testConcurrentCaptureReject() throws Exception {
- assumeFalse(mSupportConcurrentCapture);
- verify(mCaptureStateNotifier, atLeast(1)).registerListener(any());
-
- // Register global callback.
- ISoundTriggerHal.GlobalCallback globalCallback = mock(
- ISoundTriggerHal.GlobalCallback.class);
- mCanonical.registerCallback(globalCallback);
-
- // Load (this registers the callback).
- ISoundTriggerHal.ModelCallback canonicalCallback = mock(
- ISoundTriggerHal.ModelCallback.class);
- final int handle = loadGenericModel(canonicalCallback);
-
- // Report external capture active.
- mCaptureStateNotifier.setState(true);
-
- // Then start.
- RecognitionConfig config = TestUtil.createRecognitionConfig();
- try {
- mCanonical.startRecognition(handle, 203, 204, config);
- fail("Expected an exception");
- } catch (RecoverableException e) {
- assertEquals(Status.RESOURCE_CONTENTION, e.errorCode);
- }
-
- // Deactivate external capture.
- mCaptureStateNotifier.setState(false);
-
- // Expect a onResourcesAvailable().
- mCanonical.flushCallbacks();
- verify(globalCallback).onResourcesAvailable();
- }
-
- @Test
public void testStopRecognition() throws Exception {
mCanonical.stopRecognition(17);
verify(mHalDriver).stopRecognition(17);
@@ -675,7 +580,7 @@ public class SoundHw2CompatTest {
}
@Test
- public void testGlobalCallback() throws Exception {
+ public void testGlobalCallback() {
testGlobalCallback_2_0();
}
@@ -803,29 +708,4 @@ public class SoundHw2CompatTest {
verifyNoMoreInteractions(canonicalCallback);
clearInvocations(canonicalCallback);
}
-
- public static class CaptureStateNotifier implements ICaptureStateNotifier {
- private final List<Listener> mListeners = new LinkedList<>();
-
- @Override
- public boolean registerListener(Listener listener) {
- mListeners.add(listener);
- return false;
- }
-
- @Override
- public void unregisterListener(Listener listener) {
- mListeners.remove(listener);
- }
-
- public void setState(boolean state) {
- for (Listener listener : mListeners) {
- listener.onCaptureStateChange(state);
- }
- }
-
- public void verifyNoMoreListeners() {
- assertEquals(0, mListeners.size());
- }
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java
new file mode 100644
index 000000000000..61989252d04d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.soundtrigger_middleware;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.media.soundtrigger.RecognitionEvent;
+import android.media.soundtrigger.RecognitionStatus;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+
+@RunWith(JUnit4.class)
+public class SoundTriggerHalConcurrentCaptureHandlerTest {
+ private ISoundTriggerHal mUnderlying;
+ private CaptureStateNotifier mNotifier;
+ private ISoundTriggerHal.GlobalCallback mGlobalCallback;
+ private SoundTriggerHalConcurrentCaptureHandler mHandler;
+
+ @Before
+ public void setUp() {
+ mNotifier = new CaptureStateNotifier();
+ mUnderlying = mock(ISoundTriggerHal.class);
+ mGlobalCallback = mock(ISoundTriggerHal.GlobalCallback.class);
+ mHandler = new SoundTriggerHalConcurrentCaptureHandler(mUnderlying, mNotifier);
+ mHandler.registerCallback(mGlobalCallback);
+ }
+
+ @Test
+ public void testBasic() throws Exception {
+ ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class);
+ int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback);
+ verify(mUnderlying).loadSoundModel(any(), any());
+
+ mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig());
+ verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any());
+
+ mNotifier.setActive(true);
+ verify(mUnderlying).stopRecognition(handle);
+ ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+ RecognitionEvent.class);
+ Thread.sleep(50);
+ verify(callback).recognitionCallback(eq(handle), eventCaptor.capture());
+ RecognitionEvent event = eventCaptor.getValue();
+ assertEquals(event.status, RecognitionStatus.ABORTED);
+ assertFalse(event.recognitionStillActive);
+ verifyZeroInteractions(mGlobalCallback);
+ clearInvocations(callback, mUnderlying);
+
+ mNotifier.setActive(false);
+ Thread.sleep(50);
+ verify(mGlobalCallback).onResourcesAvailable();
+ verifyNoMoreInteractions(callback, mUnderlying);
+
+ mNotifier.setActive(true);
+ verifyNoMoreInteractions(callback, mUnderlying);
+ }
+
+ @Test
+ public void testStopBeforeActive() throws Exception {
+ ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class);
+ int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback);
+ verify(mUnderlying).loadSoundModel(any(), any());
+
+ mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig());
+ verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any());
+ mHandler.stopRecognition(handle);
+ verify(mUnderlying).stopRecognition(handle);
+ clearInvocations(mUnderlying);
+
+ mNotifier.setActive(true);
+ Thread.sleep(50);
+ verifyNoMoreInteractions(mUnderlying);
+ verifyNoMoreInteractions(callback);
+ }
+
+ @Test
+ public void testStopAfterActive() {
+ ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class);
+ int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback);
+ verify(mUnderlying).loadSoundModel(any(), any());
+
+ mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig());
+ verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any());
+
+ mNotifier.setActive(true);
+ verify(mUnderlying, times(1)).stopRecognition(handle);
+ mHandler.stopRecognition(handle);
+ verify(callback, times(1)).recognitionCallback(eq(handle), any());
+ }
+
+ @Test(timeout = 200)
+ public void testAbortWhileStop() {
+ ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class);
+ int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback);
+ ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor =
+ ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class);
+ verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture());
+ ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue();
+
+ mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig());
+ verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any());
+
+ doAnswer(invocation -> {
+ RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.ABORTED,
+ false);
+ // Call the callback from a different thread to detect deadlocks by preventing recursive
+ // locking from working.
+ runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event));
+ return null;
+ }).when(mUnderlying).stopRecognition(handle);
+ mHandler.stopRecognition(handle);
+ verify(mUnderlying, times(1)).stopRecognition(handle);
+
+ ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+ RecognitionEvent.class);
+ verify(callback, atMost(1)).recognitionCallback(eq(handle), eventCaptor.capture());
+ }
+
+ @Test(timeout = 200)
+ public void testActiveWhileStop() {
+ ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class);
+ int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback);
+ ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor =
+ ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class);
+ verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture());
+ ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue();
+
+ mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig());
+ verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any());
+
+ doAnswer(invocation -> {
+ // The stop request causes a callback to be flushed.
+ RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.FORCED,
+ true);
+ // Call the callback from a different thread to detect deadlocks by preventing recursive
+ // locking from working.
+ runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event));
+ // While the HAL is processing the stop request, capture state becomes active.
+ new Thread(() -> mNotifier.setActive(true)).start();
+ Thread.sleep(50);
+ return null;
+ }).when(mUnderlying).stopRecognition(handle);
+ mHandler.stopRecognition(handle);
+ // We only expect one underlying invocation of stop().
+ verify(mUnderlying, times(1)).stopRecognition(handle);
+
+ // The callback shouldn't be invoked in this case.
+ verify(callback, never()).recognitionCallback(eq(handle), any());
+ }
+
+ @Test(timeout = 200)
+ public void testStopWhileActive() {
+ ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class);
+ int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback);
+ ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor =
+ ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class);
+ verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture());
+ ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue();
+
+ mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig());
+ verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any());
+
+ doAnswer(invocation -> {
+ // The stop request causes a callback to be flushed.
+ RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.FORCED,
+ true);
+ // Call the callback from a different thread to detect deadlocks by preventing recursive
+ // locking from working.
+ runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event));
+ // While the HAL is processing the stop request, client requests stop.
+ new Thread(() -> mHandler.stopRecognition(handle)).start();
+ Thread.sleep(50);
+ return null;
+ }).when(mUnderlying).stopRecognition(handle);
+ mNotifier.setActive(true);
+ // We only expect one underlying invocation of stop().
+ verify(mUnderlying, times(1)).stopRecognition(handle);
+ verify(callback, atMost(1)).recognitionCallback(eq(handle), any());
+ }
+
+ @Test(timeout = 200)
+ public void testEventWhileActive() throws Exception {
+ ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class);
+ int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback);
+ ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor =
+ ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class);
+ verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture());
+ ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue();
+
+ mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig());
+ verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any());
+
+ doAnswer(invocation -> {
+ RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.SUCCESS,
+ false);
+ // Call the callback from a different thread to detect deadlocks by preventing recursive
+ // locking from working.
+ runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event));
+ return null;
+ }).when(mUnderlying).stopRecognition(handle);
+ mNotifier.setActive(true);
+ verify(mUnderlying, times(1)).stopRecognition(handle);
+ Thread.sleep(50);
+
+ ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+ RecognitionEvent.class);
+ verify(callback, atMost(2)).recognitionCallback(eq(handle), eventCaptor.capture());
+ RecognitionEvent lastEvent = eventCaptor.getValue();
+ assertEquals(lastEvent.status, RecognitionStatus.ABORTED);
+ assertFalse(lastEvent.recognitionStillActive);
+ }
+
+
+ @Test(timeout = 200)
+ public void testNonFinalEventWhileActive() throws Exception {
+ ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class);
+ int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback);
+ ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor =
+ ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class);
+ verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture());
+ ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue();
+
+ mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig());
+ verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any());
+
+ doAnswer(invocation -> {
+ RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.FORCED,
+ true);
+ // Call the callback from a different thread to detect deadlocks by preventing recursive
+ // locking from working.
+ runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event));
+
+ return null;
+ }).when(mUnderlying).stopRecognition(handle);
+ mNotifier.setActive(true);
+ verify(mUnderlying, times(1)).stopRecognition(handle);
+
+ Thread.sleep(50);
+ ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+ RecognitionEvent.class);
+ verify(callback, atMost(2)).recognitionCallback(eq(handle), eventCaptor.capture());
+ RecognitionEvent lastEvent = eventCaptor.getValue();
+ assertEquals(lastEvent.status, RecognitionStatus.ABORTED);
+ assertFalse(lastEvent.recognitionStillActive);
+ }
+
+ private static void runOnSeparateThread(Runnable runnable) {
+ Thread thread = new Thread(runnable);
+ thread.start();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static class CaptureStateNotifier implements ICaptureStateNotifier {
+ boolean mActive = false;
+ Listener mListener;
+
+ @Override
+ public boolean registerListener(@NonNull Listener listener) {
+ mListener = listener;
+ return mActive;
+ }
+
+ @Override
+ public void unregisterListener(@NonNull Listener listener) {
+ mListener = null;
+ }
+
+ public void setActive(boolean active) {
+ mActive = active;
+ if (mListener != null) {
+ // Call the callback from a different thread to detect deadlocks by preventing
+ // recursive locking from working.
+ runOnSeparateThread(() -> mListener.onCaptureStateChange(mActive));
+ }
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java
index 0187e34cbc5f..3bebc94fe0ed 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java
@@ -134,7 +134,7 @@ public class SoundTriggerMiddlewareImplTest {
public void setUp() throws Exception {
clearInvocations(mHalDriver);
clearInvocations(mAudioSessionProvider);
- when(mHalDriver.getProperties()).thenReturn(TestUtil.createDefaultProperties(false));
+ when(mHalDriver.getProperties()).thenReturn(TestUtil.createDefaultProperties());
mService = new SoundTriggerMiddlewareImpl(() -> mHalDriver, mAudioSessionProvider);
}
@@ -156,7 +156,7 @@ public class SoundTriggerMiddlewareImplTest {
assertEquals(1, allDescriptors.length);
Properties properties = allDescriptors[0].properties;
- assertEquals(TestUtil.createDefaultProperties(false), properties);
+ assertEquals(TestUtil.createDefaultProperties(), properties);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
index 30b4a59b32b1..39561f74d7ed 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
@@ -162,8 +162,8 @@ class TestUtil {
phrases.get(0).recognitionModes);
}
- static android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties createDefaultProperties_2_0(
- boolean supportConcurrentCapture) {
+ static android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties
+ createDefaultProperties_2_0() {
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties properties =
new android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties();
properties.implementor = "implementor";
@@ -185,17 +185,16 @@ class TestUtil {
| android.hardware.soundtrigger.V2_0.RecognitionMode.GENERIC_TRIGGER;
properties.captureTransition = true;
properties.maxBufferMs = 321;
- properties.concurrentCapture = supportConcurrentCapture;
+ properties.concurrentCapture = true;
properties.triggerInEvent = true;
properties.powerConsumptionMw = 432;
return properties;
}
- static android.hardware.soundtrigger.V2_3.Properties createDefaultProperties_2_3(
- boolean supportConcurrentCapture) {
+ static android.hardware.soundtrigger.V2_3.Properties createDefaultProperties_2_3() {
android.hardware.soundtrigger.V2_3.Properties properties =
new android.hardware.soundtrigger.V2_3.Properties();
- properties.base = createDefaultProperties_2_0(supportConcurrentCapture);
+ properties.base = createDefaultProperties_2_0();
properties.supportedModelArch = "supportedModelArch";
properties.audioCapabilities =
android.hardware.soundtrigger.V2_3.AudioCapabilities.ECHO_CANCELLATION
@@ -203,7 +202,7 @@ class TestUtil {
return properties;
}
- static Properties createDefaultProperties(boolean supportConcurrentCapture) {
+ static Properties createDefaultProperties() {
Properties properties = new Properties();
properties.implementor = "implementor";
properties.description = "description";
@@ -217,7 +216,7 @@ class TestUtil {
| RecognitionMode.USER_AUTHENTICATION | RecognitionMode.GENERIC_TRIGGER;
properties.captureTransition = true;
properties.maxBufferMs = 321;
- properties.concurrentCapture = supportConcurrentCapture;
+ properties.concurrentCapture = true;
properties.triggerInEvent = true;
properties.powerConsumptionMw = 432;
properties.supportedModelArch = "supportedModelArch";
@@ -226,13 +225,13 @@ class TestUtil {
return properties;
}
- static void validateDefaultProperties(Properties properties, boolean supportConcurrentCapture) {
- validateDefaultProperties(properties, supportConcurrentCapture,
+ static void validateDefaultProperties(Properties properties) {
+ validateDefaultProperties(properties,
AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION,
"supportedModelArch");
}
- static void validateDefaultProperties(Properties properties, boolean supportConcurrentCapture,
+ static void validateDefaultProperties(Properties properties,
@AudioCapabilities int audioCapabilities, @NonNull String supportedModelArch) {
assertEquals("implementor", properties.implementor);
assertEquals("description", properties.description);
@@ -246,7 +245,7 @@ class TestUtil {
properties.recognitionModes);
assertTrue(properties.captureTransition);
assertEquals(321, properties.maxBufferMs);
- assertEquals(supportConcurrentCapture, properties.concurrentCapture);
+ assertEquals(true, properties.concurrentCapture);
assertTrue(properties.triggerInEvent);
assertEquals(432, properties.powerConsumptionMw);
assertEquals(supportedModelArch, properties.supportedModelArch);
diff --git a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
index 37c95f735d89..4ed4c236535f 100644
--- a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
@@ -17,7 +17,6 @@
package com.android.server.utils;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -861,54 +860,6 @@ public class WatcherTest {
}
}
- @Test
- public void testWatchedSparseSetArray() {
- final String name = "WatchedSparseSetArray";
- WatchableTester tester;
-
- // Test WatchedSparseSetArray
- WatchedSparseSetArray array = new WatchedSparseSetArray();
- tester = new WatchableTester(array, name);
- tester.verify(0, "Initial array - no registration");
- array.add(INDEX_A, 1);
- tester.verify(0, "Updates with no registration");
- tester.register();
- tester.verify(0, "Updates with no registration");
- array.add(INDEX_B, 2);
- tester.verify(1, "Updates with registration");
- array.add(INDEX_B, 4);
- array.add(INDEX_C, 5);
- tester.verify(3, "Updates with registration");
- // Special methods
- assertTrue(array.remove(INDEX_C, 5));
- tester.verify(4, "Removed 5 from key 3");
- array.remove(INDEX_B);
- tester.verify(5, "Removed everything for key 2");
-
- // Snapshot
- {
- WatchedSparseSetArray arraySnap = (WatchedSparseSetArray) array.snapshot();
- tester.verify(5, "Generate snapshot");
- // Verify that the snapshot is a proper copy of the source.
- assertEquals("WatchedSparseSetArray snap same size",
- array.size(), arraySnap.size());
- for (int i = 0; i < array.size(); i++) {
- ArraySet set = array.get(array.keyAt(i));
- ArraySet setSnap = arraySnap.get(arraySnap.keyAt(i));
- assertNotNull(set);
- assertTrue(set.equals(setSnap));
- }
- array.add(INDEX_D, 9);
- tester.verify(6, "Tick after snapshot");
- // Verify that the array is sealed
- verifySealed(name, ()->arraySnap.add(INDEX_D, 10));
- assertTrue(!array.isSealed());
- assertTrue(arraySnap.isSealed());
- }
- array.clear();
- tester.verify(7, "Cleared all entries");
- }
-
private static class IndexGenerator {
private final int mSeed;
private final Random mRandom;
@@ -1133,18 +1084,6 @@ public class WatcherTest {
assertEquals(a.equals(s), true);
a.put(rowIndex, colIndex, !a.get(rowIndex, colIndex));
assertEquals(a.equals(s), false);
-
- // Verify copy-in/out
- {
- final String msg = name + " copy";
- WatchedSparseBooleanMatrix copy = new WatchedSparseBooleanMatrix();
- copy.copyFrom(matrix);
- final int end = copy.size();
- assertTrue(msg + " size mismatch " + end + " " + matrix.size(), end == matrix.size());
- for (int i = 0; i < end; i++) {
- assertEquals(copy.keyAt(i), keys[i]);
- }
- }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index 9f135918daa2..de5f6ed2ae5d 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -276,7 +276,7 @@ public class VibrationThreadTest {
}
@Test
- public void vibrate_singleVibratorRepeatingShortAlwaysOnWaveform_turnsVibratorOnForASecond()
+ public void vibrate_singleVibratorRepeatingShortAlwaysOnWaveform_turnsVibratorOnForLonger()
throws Exception {
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
@@ -293,11 +293,71 @@ public class VibrationThreadTest {
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_USER);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(expectedOneShot(1000)),
+ assertEquals(Arrays.asList(expectedOneShot(5000)),
fakeVibrator.getEffectSegments(vibrationId));
}
@Test
+ public void vibrate_singleVibratorRepeatingPwle_generatesLargestPwles() throws Exception {
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ fakeVibrator.setMinFrequency(100);
+ fakeVibrator.setResonantFrequency(150);
+ fakeVibrator.setFrequencyResolution(50);
+ fakeVibrator.setMaxAmplitudes(1, 1, 1);
+ fakeVibrator.setPwleSizeMax(10);
+
+ long vibrationId = 1;
+ VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
+ // Very long segment so thread will be cancelled after first PWLE is triggered.
+ .addTransition(Duration.ofMillis(100), targetFrequency(100))
+ .build();
+ VibrationEffect repeatingEffect = VibrationEffect.startComposition()
+ .repeatEffectIndefinitely(effect)
+ .compose();
+ VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, repeatingEffect);
+
+ assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
+ TEST_TIMEOUT_MILLIS));
+ conductor.notifyCancelled(Vibration.Status.CANCELLED_BY_USER, /* immediate= */ false);
+ waitForCompletion();
+
+ // PWLE size max was used to generate a single vibrate call with 10 segments.
+ verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_USER);
+ assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertEquals(10, fakeVibrator.getEffectSegments(vibrationId).size());
+ }
+
+ @Test
+ public void vibrate_singleVibratorRepeatingPrimitives_generatesLargestComposition()
+ throws Exception {
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+ fakeVibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK);
+ fakeVibrator.setCompositionSizeMax(10);
+
+ long vibrationId = 1;
+ VibrationEffect effect = VibrationEffect.startComposition()
+ // Very long delay so thread will be cancelled after first PWLE is triggered.
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
+ .compose();
+ VibrationEffect repeatingEffect = VibrationEffect.startComposition()
+ .repeatEffectIndefinitely(effect)
+ .compose();
+ VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, repeatingEffect);
+
+ assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
+ TEST_TIMEOUT_MILLIS));
+ conductor.notifyCancelled(Vibration.Status.CANCELLED_SUPERSEDED, /* immediate= */ false);
+ waitForCompletion();
+
+ // Composition size max was used to generate a single vibrate call with 10 primitives.
+ verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_SUPERSEDED);
+ assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertEquals(10, fakeVibrator.getEffectSegments(vibrationId).size());
+ }
+
+ @Test
public void vibrate_singleVibratorRepeatingLongAlwaysOnWaveform_turnsVibratorOnForACycle()
throws Exception {
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
@@ -319,7 +379,7 @@ public class VibrationThreadTest {
fakeVibrator.getEffectSegments(vibrationId));
}
-
+ @LargeTest
@Test
public void vibrate_singleVibratorRepeatingAlwaysOnWaveform_turnsVibratorBackOn()
throws Exception {
@@ -329,22 +389,21 @@ public class VibrationThreadTest {
long vibrationId = 1;
int[] amplitudes = new int[]{1, 2};
VibrationEffect effect = VibrationEffect.createWaveform(
- new long[]{900, 50}, amplitudes, 0);
+ new long[]{4900, 50}, amplitudes, 0);
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
- assertTrue(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
- 1000 + TEST_TIMEOUT_MILLIS));
+ assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibrationId).size() > 1,
+ 5000 + TEST_TIMEOUT_MILLIS));
conductor.notifyCancelled(Vibration.Status.CANCELLED_BY_USER, /* immediate= */ false);
waitForCompletion();
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_USER);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(2, fakeVibrator.getEffectSegments(vibrationId).size());
- // First time turn vibrator ON for minimum of 1s.
- assertEquals(1000L, fakeVibrator.getEffectSegments(vibrationId).get(0).getDuration());
+ // First time turn vibrator ON for minimum of 5s.
+ assertEquals(5000L, fakeVibrator.getEffectSegments(vibrationId).get(0).getDuration());
// Vibrator turns off in the middle of the second execution of first step, turn it back ON
- // for another 1s + remaining of 850ms.
- assertEquals(1850,
+ // for another 5s + remaining of 850ms.
+ assertEquals(4900 + 50 + 4900,
fakeVibrator.getEffectSegments(vibrationId).get(1).getDuration(), /* delta= */ 20);
// Set amplitudes for a cycle {1, 2}, start second loop then turn it back on to same value.
assertEquals(expectedAmplitudes(1, 2, 1, 1),
@@ -530,12 +589,18 @@ public class VibrationThreadTest {
@Test
public void vibrate_singleVibratorComposedEffects_runsDifferentVibrations() throws Exception {
- mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
- mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ fakeVibrator.setSupportedPrimitives(
VibrationEffect.Composition.PRIMITIVE_CLICK,
VibrationEffect.Composition.PRIMITIVE_TICK);
- mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS,
- IVibrator.CAP_AMPLITUDE_CONTROL);
+ fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS,
+ IVibrator.CAP_COMPOSE_PWLE_EFFECTS, IVibrator.CAP_AMPLITUDE_CONTROL);
+ fakeVibrator.setMinFrequency(100);
+ fakeVibrator.setResonantFrequency(150);
+ fakeVibrator.setFrequencyResolution(50);
+ fakeVibrator.setMaxAmplitudes(
+ 0.5f /* 100Hz*/, 1 /* 150Hz */, 0.6f /* 200Hz */);
long vibrationId = 1;
VibrationEffect effect = VibrationEffect.startComposition()
@@ -543,7 +608,11 @@ public class VibrationThreadTest {
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
.addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
- .addOffDuration(Duration.ofMillis(100))
+ .addEffect(VibrationEffect.startWaveform()
+ .addTransition(Duration.ofMillis(10),
+ targetAmplitude(1), targetFrequency(100))
+ .addTransition(Duration.ofMillis(20), targetFrequency(120))
+ .build())
.addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.compose();
startThreadAndDispatcher(vibrationId, effect);
@@ -552,7 +621,7 @@ public class VibrationThreadTest {
// Use first duration the vibrator is turned on since we cannot estimate the clicks.
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks, times(4)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+ verify(mControllerCallbacks, times(5)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(
@@ -560,6 +629,10 @@ public class VibrationThreadTest {
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0),
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f, 0),
expectedPrebaked(VibrationEffect.EFFECT_CLICK),
+ expectedRamp(/* startAmplitude= */ 0, /* endAmplitude= */ 0.5f,
+ /* startFrequencyHz= */ 150, /* endFrequencyHz= */ 100, /* duration= */ 10),
+ expectedRamp(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.7f,
+ /* startFrequencyHz= */ 100, /* endFrequencyHz= */ 120, /* duration= */ 20),
expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
@@ -605,30 +678,36 @@ public class VibrationThreadTest {
}
@Test
- public void vibrate_singleVibratorLargePwle_splitsVibratorComposeCalls() {
+ public void vibrate_singleVibratorLargePwle_splitsComposeCallWhenAmplitudeIsLowest() {
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
fakeVibrator.setMinFrequency(100);
fakeVibrator.setResonantFrequency(150);
fakeVibrator.setFrequencyResolution(50);
fakeVibrator.setMaxAmplitudes(1, 1, 1);
- fakeVibrator.setPwleSizeMax(2);
+ fakeVibrator.setPwleSizeMax(3);
long vibrationId = 1;
VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
.addSustain(Duration.ofMillis(10))
.addTransition(Duration.ofMillis(20), targetAmplitude(0))
+ // Waveform will be split here, after vibration goes to zero amplitude
.addTransition(Duration.ZERO, targetAmplitude(0.8f), targetFrequency(100))
.addSustain(Duration.ofMillis(30))
.addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
+ // Waveform will be split here at lowest amplitude.
+ .addTransition(Duration.ofMillis(40), targetAmplitude(0.7f), targetFrequency(200))
+ .addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
.build();
startThreadAndDispatcher(vibrationId, effect);
waitForCompletion();
verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
- // Vibrator compose called twice.
- verify(mControllerCallbacks, times(2)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- assertEquals(4, fakeVibrator.getEffectSegments(vibrationId).size());
+
+ // Vibrator compose called 3 times with 2 segments instead of 2 times with 3 segments.
+ // Using best split points instead of max-packing PWLEs.
+ verify(mControllerCallbacks, times(3)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+ assertEquals(6, fakeVibrator.getEffectSegments(vibrationId).size());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index 9c72ce22c857..f3d494d160f2 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -1315,6 +1315,24 @@ public class VibratorManagerServiceTest {
assertNotEquals(IExternalVibratorService.SCALE_MUTE, scale);
}
+ @Test
+ public void onExternalVibration_withUnknownUsage_appliesMediaSettings() {
+ mockVibrators(1);
+ mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
+ setUserSetting(Settings.System.MEDIA_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_OFF);
+ AudioAttributes flaggedAudioAttrs = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_UNKNOWN)
+ .setFlags(AudioAttributes.FLAG_BYPASS_MUTE)
+ .build();
+ createSystemReadyService();
+
+ int scale = mExternalVibratorService.onExternalVibrationStart(
+ new ExternalVibration(/* uid= */ 123, PACKAGE_NAME, flaggedAudioAttrs,
+ mock(IExternalVibrationController.class)));
+ assertEquals(IExternalVibratorService.SCALE_MUTE, scale);
+ }
+
private VibrationEffectSegment expectedPrebaked(int effectId) {
return expectedPrebaked(effectId, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
}
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 67382bfacab4..1cf96972c225 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -20,7 +20,6 @@ import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREG
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.Notification.FLAG_AUTO_CANCEL;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_CAN_COLORIZE;
@@ -9161,4 +9160,39 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
}
}
+
+ @Test
+ public void testUngroupingOngoingAutoSummary() throws Exception {
+ NotificationRecord nr0 =
+ generateNotificationRecord(mTestNotificationChannel, 0);
+ NotificationRecord nr1 =
+ generateNotificationRecord(mTestNotificationChannel, 0);
+ nr1.getSbn().getNotification().flags |= FLAG_ONGOING_EVENT;
+
+ mService.addNotification(nr0);
+ mService.addNotification(nr1);
+
+ // grouphelper is a mock here, so make the calls it would make
+
+ // add summary; wait for it to be posted
+ mService.addAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(), nr1.getKey(),
+ true);
+ waitForIdle();
+
+ // cancel both children
+ mBinderService.cancelNotificationWithTag(PKG, PKG, nr0.getSbn().getTag(),
+ nr0.getSbn().getId(), nr0.getSbn().getUserId());
+ mBinderService.cancelNotificationWithTag(PKG, PKG, nr1.getSbn().getTag(),
+ nr1.getSbn().getId(), nr1.getSbn().getUserId());
+ waitForIdle();
+
+ // group helper would send 'remove flag' and then 'remove summary' events
+ mService.updateAutobundledSummaryFlags(nr1.getUserId(), nr1.getSbn().getPackageName(),
+ false, false);
+ mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName());
+ waitForIdle();
+
+ // make sure the summary was removed and not re-posted
+ assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 97d477f2bae9..33b70249dabe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -861,13 +861,13 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testOverrideTaskFragmentAdapter_overrideWithEmbeddedActivity() {
+ final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
// Create a TaskFragment with embedded activity.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(
- createTask(mDisplayContent), organizer);
+ final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
final ActivityRecord activity = taskFragment.getTopMostActivity();
prepareActivityForAppTransition(activity);
spyOn(mDisplayContent.mAppTransition);
@@ -882,11 +882,11 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testOverrideTaskFragmentAdapter_overrideWithNonEmbeddedActivity() {
+ final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
- final Task task = createTask(mDisplayContent);
// Closing non-embedded activity.
final ActivityRecord closingActivity = createActivityRecord(task);
prepareActivityForAppTransition(closingActivity);
@@ -907,11 +907,11 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testOverrideTaskFragmentAdapter_overrideEmbeddedActivityWithDiffUid() {
+ final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
- final Task task = createTask(mDisplayContent);
// Closing TaskFragment with embedded activity.
final TaskFragment taskFragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
final ActivityRecord closingActivity = taskFragment1.getTopMostActivity();
@@ -934,16 +934,16 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testOverrideTaskFragmentAdapter_noOverrideWithTwoApps() {
+ final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
// Closing activity in Task1.
final ActivityRecord closingActivity = createActivityRecord(mDisplayContent);
prepareActivityForAppTransition(closingActivity);
// Opening TaskFragment with embedded activity in Task2.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(
- createTask(mDisplayContent), organizer);
+ final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
final ActivityRecord openingActivity = taskFragment.getTopMostActivity();
prepareActivityForAppTransition(openingActivity);
spyOn(mDisplayContent.mAppTransition);
@@ -958,11 +958,11 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testOverrideTaskFragmentAdapter_noOverrideNonEmbeddedActivityWithDiffUid() {
+ final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
- final Task task = createTask(mDisplayContent);
// Closing TaskFragment with embedded activity.
final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
final ActivityRecord closingActivity = taskFragment.getTopMostActivity();
@@ -986,13 +986,13 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testOverrideTaskFragmentAdapter_noOverrideWithWallpaper() {
+ final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
// Create a TaskFragment with embedded activity.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(
- createTask(mDisplayContent), organizer);
+ final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
final ActivityRecord activity = taskFragment.getTopMostActivity();
prepareActivityForAppTransition(activity);
// Set wallpaper as visible.
@@ -1012,13 +1012,13 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testOverrideTaskFragmentAdapter_inputProtectedForUntrustedAnimation() {
+ final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
// Create a TaskFragment with embedded activities, one is trusted embedded, and the other
// one is untrusted embedded.
- final Task task = createTask(mDisplayContent);
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
.setParentTask(task)
.createActivityCount(2)
@@ -1071,12 +1071,12 @@ public class AppTransitionControllerTest extends WindowTestsBase {
*/
@Test
public void testOverrideTaskFragmentAdapter_inputProtectedForTrustedAnimation() {
+ final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+ setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
// Create a TaskFragment with only trusted embedded activity
- final Task task = createTask(mDisplayContent);
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
.setParentTask(task)
.createActivityCount(1)
@@ -1170,7 +1170,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
}
/** Registers remote animation for the organizer. */
- private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer,
+ private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer, int taskId,
TestRemoteAnimationRunner remoteAnimationRunner) {
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
remoteAnimationRunner, 10, 1);
@@ -1181,7 +1181,8 @@ public class AppTransitionControllerTest extends WindowTestsBase {
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, adapter);
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, adapter);
mAtm.mTaskFragmentOrganizerController.registerOrganizer(iOrganizer);
- mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, definition);
+ mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, taskId,
+ definition);
}
private void prepareAndTriggerAppTransition(@Nullable ActivityRecord openingActivity,
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index f44de1e46c0f..a4a62a4254ad 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -23,8 +23,13 @@ import static android.window.BackNavigationInfo.typeToString;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -32,13 +37,16 @@ import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.HardwareBuffer;
+import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.view.WindowManager;
import android.window.BackEvent;
import android.window.BackNavigationInfo;
import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
import android.window.TaskSnapshot;
+import android.window.WindowOnBackInvokedDispatcher;
import com.android.server.LocalServices;
@@ -46,6 +54,9 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
@Presubmit
@RunWith(WindowTestRunner.class)
public class BackNavigationControllerTests extends WindowTestsBase {
@@ -148,6 +159,61 @@ public class BackNavigationControllerTests extends WindowTestsBase {
assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(appCallback);
}
+ @Test
+ public void testUnregisterCallbacksWithSystemCallback()
+ throws InterruptedException, RemoteException {
+ CountDownLatch systemLatch = new CountDownLatch(1);
+ CountDownLatch appLatch = new CountDownLatch(1);
+
+ Task task = createTopTaskWithActivity();
+ WindowState appWindow = task.getTopVisibleAppMainWindow();
+ WindowOnBackInvokedDispatcher dispatcher = new WindowOnBackInvokedDispatcher();
+ doAnswer(invocation -> {
+ appWindow.setOnBackInvokedCallback(invocation.getArgument(1),
+ invocation.getArgument(2));
+ return null;
+ }).when(appWindow.mSession).setOnBackInvokedCallback(eq(appWindow.mClient), any(),
+ anyInt());
+
+ addToWindowMap(appWindow, true);
+ dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient);
+
+
+ OnBackInvokedCallback appCallback = createBackCallback(appLatch);
+ OnBackInvokedCallback systemCallback = createBackCallback(systemLatch);
+
+ // Register both a system callback and an application callback
+ dispatcher.registerSystemOnBackInvokedCallback(systemCallback);
+ dispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+ appCallback);
+
+ // Check that the top callback is the app callback
+ assertEquals(appCallback, dispatcher.getTopCallback());
+
+ // Now unregister the app callback and check that the top callback is the system callback
+ dispatcher.unregisterOnBackInvokedCallback(appCallback);
+ assertEquals(systemCallback, dispatcher.getTopCallback());
+
+ // Verify that this has correctly been propagated to the server and that the
+ // BackNavigationInfo object will contain the system callback
+ BackNavigationInfo backNavigationInfo = startBackNavigation();
+ assertWithMessage("BackNavigationInfo").that(backNavigationInfo).isNotNull();
+ IOnBackInvokedCallback callback = backNavigationInfo.getOnBackInvokedCallback();
+ assertThat(callback).isNotNull();
+
+ try {
+ callback.onBackInvoked();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Check that the system callback has been call
+ assertTrue("System callback has not been called",
+ systemLatch.await(500, TimeUnit.MILLISECONDS));
+ assertEquals("App callback should not have been called",
+ 1, appLatch.getCount());
+ }
+
private IOnBackInvokedCallback withSystemCallback(Task task) {
IOnBackInvokedCallback callback = createOnBackInvokedCallback();
task.getTopMostActivity().getTopChild().setOnBackInvokedCallback(callback,
@@ -188,6 +254,17 @@ public class BackNavigationControllerTests extends WindowTestsBase {
};
}
+ private OnBackInvokedCallback createBackCallback(CountDownLatch latch) {
+ return new OnBackInvokedCallback() {
+ @Override
+ public void onBackInvoked() {
+ if (latch != null) {
+ latch.countDown();
+ }
+ }
+ };
+ }
+
@NonNull
private TaskSnapshotController createMockTaskSnapshotController() {
TaskSnapshotController taskSnapshotController = mock(TaskSnapshotController.class);
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 7b38a955f822..76fb7ff2e6f8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1529,6 +1529,27 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
+ public void testDisplayIgnoreOrientationRequest_orientationChangedToUnspecified() {
+ // Set up a display in landscape and ignoring orientation request.
+ setUpDisplaySizeWithApp(2800, 1400);
+ final DisplayContent display = mActivity.mDisplayContent;
+ display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+ // Portrait fixed app without max aspect.
+ prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
+
+ assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(mActivity.inSizeCompatMode());
+
+ mActivity.setRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
+
+ assertTrue(mActivity.inSizeCompatMode());
+ // We should remember the original orientation.
+ assertEquals(mActivity.getResolvedOverrideConfiguration().orientation,
+ Configuration.ORIENTATION_PORTRAIT);
+ }
+
+ @Test
public void testDisplayIgnoreOrientationRequest_newLaunchedMaxAspectApp() {
// Set up a display in landscape and ignoring orientation request.
setUpDisplaySizeWithApp(2800, 1400);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index ce861595535c..dc9a62554fdb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -52,6 +52,7 @@ import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManagerInternal;
import android.database.ContentObserver;
+import android.hardware.devicestate.DeviceStateManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
import android.net.Uri;
@@ -229,6 +230,10 @@ public class SystemServicesTestRule implements TestRule {
final AppOpsManager aom = mock(AppOpsManager.class);
doReturn(aom).when(mContext).getSystemService(eq(Context.APP_OPS_SERVICE));
+ // DeviceStateManager
+ final DeviceStateManager dsm = mock(DeviceStateManager.class);
+ doReturn(dsm).when(mContext).getSystemService(eq(Context.DEVICE_STATE_SERVICE));
+
// Prevent "WakeLock finalized while still held: SCREEN_FROZEN".
final PowerManager pm = mock(PowerManager.class);
doReturn(pm).when(mContext).getSystemService(eq(Context.POWER_SERVICE));
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index b1c9d3de304b..37719fecd7e4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -67,6 +67,7 @@ import org.junit.runner.RunWith;
@Presubmit
@RunWith(WindowTestRunner.class)
public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
+ private static final int TASK_ID = 10;
private TaskFragmentOrganizerController mController;
private TaskFragmentOrganizer mOrganizer;
@@ -219,13 +220,13 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
@Test
public void testRegisterRemoteAnimations() {
mController.registerOrganizer(mIOrganizer);
- mController.registerRemoteAnimations(mIOrganizer, mDefinition);
+ mController.registerRemoteAnimations(mIOrganizer, TASK_ID, mDefinition);
- assertEquals(mDefinition, mController.getRemoteAnimationDefinition(mIOrganizer));
+ assertEquals(mDefinition, mController.getRemoteAnimationDefinition(mIOrganizer, TASK_ID));
- mController.unregisterRemoteAnimations(mIOrganizer);
+ mController.unregisterRemoteAnimations(mIOrganizer, TASK_ID);
- assertNull(mController.getRemoteAnimationDefinition(mIOrganizer));
+ assertNull(mController.getRemoteAnimationDefinition(mIOrganizer, TASK_ID));
}
@Test
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 bcab4a5cde27..c672b9173570 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -87,6 +87,7 @@ import android.view.IDisplayWindowInsetsController;
import android.view.IWindow;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.view.InsetsVisibilities;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -793,7 +794,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
}
@Override
- public void topFocusedWindowChanged(String packageName) {
+ public void topFocusedWindowChanged(String packageName,
+ InsetsVisibilities requestedVisibilities) {
}
};
}
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index f07a4061d717..5e633ab3aef5 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -508,7 +508,7 @@ public class UsbPortManager {
*
* @param portId port identifier.
*/
- public boolean resetUsbPort(@NonNull String portId, int transactionId,
+ public void resetUsbPort(@NonNull String portId, int transactionId,
@NonNull IUsbOperationInternal callback, IndentingPrintWriter pw) {
synchronized (mLock) {
Objects.requireNonNull(callback);
@@ -525,12 +525,11 @@ public class UsbPortManager {
"resetUsbPort: Failed to call OperationComplete. opId:"
+ transactionId, e);
}
- return false;
}
try {
try {
- return mUsbPortHal.resetUsbPort(portId, transactionId, callback);
+ mUsbPortHal.resetUsbPort(portId, transactionId, callback);
} catch (Exception e) {
logAndPrintException(pw,
"reseetUsbPort: Failed to resetUsbPort. opId:"
@@ -542,7 +541,6 @@ public class UsbPortManager {
"resetUsbPort: Failed to call onOperationComplete. opId:"
+ transactionId, e);
}
- return false;
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index e06ab022688f..86f877fcd531 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -685,7 +685,7 @@ public class UsbService extends IUsbManager.Stub {
}
@Override
- public boolean resetUsbPort(String portId, int operationId,
+ public void resetUsbPort(String portId, int operationId,
IUsbOperationInternal callback) {
Objects.requireNonNull(portId, "resetUsbPort: portId must not be null. opId:"
+ operationId);
@@ -694,13 +694,11 @@ public class UsbService extends IUsbManager.Stub {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
final long ident = Binder.clearCallingIdentity();
- boolean wait;
try {
if (mPortManager != null) {
- wait = mPortManager.resetUsbPort(portId, operationId, callback, null);
+ mPortManager.resetUsbPort(portId, operationId, callback, null);
} else {
- wait = false;
try {
callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
} catch (RemoteException e) {
@@ -710,7 +708,6 @@ public class UsbService extends IUsbManager.Stub {
} finally {
Binder.restoreCallingIdentity(ident);
}
- return wait;
}
@Override
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
index 8c9e80f7e04d..600fc27f5103 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
@@ -274,7 +274,7 @@ public final class UsbPortAidl implements UsbPortHal {
}
@Override
- public boolean resetUsbPort(String portName, long operationID,
+ public void resetUsbPort(String portName, long operationID,
IUsbOperationInternal callback) {
Objects.requireNonNull(portName);
Objects.requireNonNull(callback);
@@ -286,7 +286,6 @@ public final class UsbPortAidl implements UsbPortHal {
"resetUsbPort: Proxy is null. Retry !opID:"
+ operationID);
callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
- return false;
}
while (sCallbacks.get(key) != null) {
key = ThreadLocalRandom.current().nextInt();
@@ -304,16 +303,13 @@ public final class UsbPortAidl implements UsbPortHal {
+ portName + "opId:" + operationID, e);
callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
sCallbacks.remove(key);
- return false;
}
} catch (RemoteException e) {
logAndPrintException(mPw,
"resetUsbPort: Failed to call onOperationComplete portID="
+ portName + "opID:" + operationID, e);
sCallbacks.remove(key);
- return false;
}
- return true;
}
}
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
index 4fa296da7267..f98c598d4190 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
@@ -202,9 +202,7 @@ public interface UsbPortHal {
* implementation as needed.
* @param callback callback object to be invoked to invoke the status of the operation upon
* completion.
- * @param callback callback object to be invoked to invoke the status of the operation upon
- * completion.
*/
- public boolean resetUsbPort(String portName, long transactionId,
+ public void resetUsbPort(String portName, long transactionId,
IUsbOperationInternal callback);
}
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
index c7f077564fd1..23d913cba733 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
@@ -318,7 +318,7 @@ public final class UsbPortHidl implements UsbPortHal {
}
@Override
- public boolean resetUsbPort(String portName, long transactionId,
+ public void resetUsbPort(String portName, long transactionId,
IUsbOperationInternal callback) {
try {
callback.onOperationComplete(USB_OPERATION_ERROR_NOT_SUPPORTED);
@@ -327,7 +327,6 @@ public final class UsbPortHidl implements UsbPortHal {
+ transactionId
+ " portId:" + portName, e);
}
- return false;
}
@Override
diff --git a/telecomm/OWNERS b/telecomm/OWNERS
index 9969ee965fbd..eb0c4327ec46 100644
--- a/telecomm/OWNERS
+++ b/telecomm/OWNERS
@@ -1,8 +1,6 @@
set noparent
breadley@google.com
-hallliu@google.com
tgunn@google.com
xiaotonj@google.com
-shuoq@google.com
rgreenwalt@google.com
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 6a283df5b480..49ad58550db8 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -45,6 +45,7 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
import android.telephony.CallQuality;
+import android.telephony.CellIdentity;
import android.telephony.ims.ImsStreamMediaProfile;
import android.util.ArraySet;
import android.view.Surface;
@@ -837,10 +838,10 @@ public abstract class Connection extends Conferenceable {
"android.telecom.extra.AUDIO_CODEC_BANDWIDTH_KHZ";
/**
- * Last known cell identity key to be used to fill geo location header in case of an emergency
- * call. This entry will not be filled if call is not identified as an emergency call.
- * {@link Connection}. Only provided to the {@link ConnectionService} for the purpose
- * of placing an emergency call; will not be present in the {@link InCallService} layer.
+ * Last known cell identity key {@link CellIdentity} to be used to fill geo location header
+ * in case of an emergency call. This entry will not be filled if call is not identified as
+ * an emergency call. Only provided to the {@link ConnectionService} for the purpose of
+ * placing an emergency call; will not be present in the {@link InCallService} layer.
* The {@link ConnectionService}'s implementation will be logged for fine location access
* when an outgoing call is placed in this case.
*/
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index df114dbabe5b..e0f5b2095190 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -2601,6 +2601,33 @@ public class TelecomManager {
}
/**
+ * Determines whether there are any ongoing {@link PhoneAccount#CAPABILITY_SELF_MANAGED}
+ * calls for a given {@code packageName} and {@code userHandle}.
+ *
+ * @param packageName the package name of the app to check calls for.
+ * @param userHandle the user handle on which to check for calls.
+ * @return {@code true} if there are ongoing calls, {@code false} otherwise.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public boolean isInSelfManagedCall(@NonNull String packageName,
+ @NonNull UserHandle userHandle) {
+ ITelecomService service = getTelecomService();
+ if (service != null) {
+ try {
+ return service.isInSelfManagedCall(packageName, userHandle,
+ mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException isInSelfManagedCall: " + e);
+ e.rethrowFromSystemServer();
+ return false;
+ }
+ } else {
+ throw new IllegalStateException("Telecom service is not present");
+ }
+ }
+
+ /**
* Handles {@link Intent#ACTION_CALL} intents trampolined from UserCallActivity.
* @param intent The {@link Intent#ACTION_CALL} intent to handle.
* @param callingPackageProxy The original package that called this before it was trampolined.
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 9999c897d1b6..07e18d524701 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -22,6 +22,7 @@ import android.telecom.TelecomAnalytics;
import android.telecom.PhoneAccountHandle;
import android.net.Uri;
import android.os.Bundle;
+import android.os.UserHandle;
import android.telecom.PhoneAccount;
/**
@@ -374,4 +375,10 @@ interface ITelecomService {
* @see TelecomServiceImpl#setTestCallDiagnosticService
*/
void setTestCallDiagnosticService(in String packageName);
+
+ /**
+ * @see TelecomServiceImpl#isInSelfManagedCall
+ */
+ boolean isInSelfManagedCall(String packageName, in UserHandle userHandle,
+ String callingPackage);
}
diff --git a/telephony/OWNERS b/telephony/OWNERS
index f248fd52db83..9681ee8b6c75 100644
--- a/telephony/OWNERS
+++ b/telephony/OWNERS
@@ -1,15 +1,10 @@
set noparent
-amitmahajan@google.com
breadley@google.com
fionaxu@google.com
jackyu@google.com
rgreenwalt@google.com
tgunn@google.com
-jminjie@google.com
-shuoq@google.com
-sarahchin@google.com
-xiaotonj@google.com
huiwang@google.com
jayachandranc@google.com
chinmayd@google.com
diff --git a/telephony/java/android/service/euicc/OWNERS b/telephony/java/android/service/euicc/OWNERS
index 6aa399d9ebfb..fbeb6daff769 100644
--- a/telephony/java/android/service/euicc/OWNERS
+++ b/telephony/java/android/service/euicc/OWNERS
@@ -1,5 +1,5 @@
-# Bug component: 20868
+set noparent
+fionaxu@google.com
rgreenwalt@google.com
-tgunn@google.com
-amitmahajan@google.com
+amruthr@google.com
diff --git a/telephony/java/android/service/sms/OWNERS b/telephony/java/android/service/sms/OWNERS
deleted file mode 100644
index 6aa399d9ebfb..000000000000
--- a/telephony/java/android/service/sms/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-amitmahajan@google.com
diff --git a/telephony/java/android/telephony/OWNERS b/telephony/java/android/telephony/OWNERS
deleted file mode 100644
index 6aa399d9ebfb..000000000000
--- a/telephony/java/android/telephony/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-amitmahajan@google.com
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ade5543e938a..8a75ae45c3a5 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8979,7 +8979,7 @@ public class TelephonyManager {
public NetworkScan requestNetworkScan(
NetworkScanRequest request, Executor executor,
TelephonyScanManager.NetworkScanCallback callback) {
- return requestNetworkScan(false, request, executor, callback);
+ return requestNetworkScan(INCLUDE_LOCATION_DATA_FINE, request, executor, callback);
}
/**
@@ -9004,9 +9004,8 @@ public class TelephonyManager {
* and MCC/MNC info.</li>
* </ol>
*
- * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
- * location related information which will be sent if the caller already possess
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permission
+ * @param includeLocationData Specifies if the caller would like to receive
+ * location related information.
* @param request Contains all the RAT with bands/channels that need to be scanned.
* @param executor The executor through which the callback should be invoked. Since the scan
* request may trigger multiple callbacks and they must be invoked in the same order as
@@ -9021,7 +9020,8 @@ public class TelephonyManager {
Manifest.permission.ACCESS_FINE_LOCATION
})
public @Nullable NetworkScan requestNetworkScan(
- boolean renounceFineLocationAccess, @NonNull NetworkScanRequest request,
+ @IncludeLocationData int includeLocationData,
+ @NonNull NetworkScanRequest request,
@NonNull Executor executor,
@NonNull TelephonyScanManager.NetworkScanCallback callback) {
synchronized (sCacheLock) {
@@ -9029,7 +9029,8 @@ public class TelephonyManager {
mTelephonyScanManager = new TelephonyScanManager();
}
}
- return mTelephonyScanManager.requestNetworkScan(getSubId(), renounceFineLocationAccess,
+ return mTelephonyScanManager.requestNetworkScan(getSubId(),
+ includeLocationData != INCLUDE_LOCATION_DATA_FINE,
request, executor, callback,
getOpPackageName(), getAttributionTag());
}
@@ -10555,7 +10556,7 @@ public class TelephonyManager {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.enableDataConnectivity();
+ return telephony.enableDataConnectivity(getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#enableDataConnectivity", e);
}
@@ -10570,7 +10571,7 @@ public class TelephonyManager {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.disableDataConnectivity();
+ return telephony.disableDataConnectivity(getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#disableDataConnectivity", e);
}
@@ -11767,7 +11768,25 @@ public class TelephonyManager {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
List<String> newList = updateTelephonyProperty(
TelephonyProperties.operator_alpha(), phoneId, name);
- TelephonyProperties.operator_alpha(newList);
+ try {
+ TelephonyProperties.operator_alpha(newList);
+ } catch (IllegalArgumentException e) { //property value is longer than the byte limit
+ Log.e(TAG, "setNetworkOperatorNameForPhone: ", e);
+
+ int numberOfEntries = newList.size();
+ int maxOperatorLength = //save 1 byte for joiner " , "
+ (SystemProperties.PROP_VALUE_MAX - numberOfEntries) / numberOfEntries;
+
+ //examine and truncate every operator and retry
+ for (int i = 0; i < newList.size(); i++) {
+ if (newList.get(i) != null) {
+ newList.set(i, TextUtils
+ .truncateStringForUtf8Storage(newList.get(i), maxOperatorLength));
+ }
+ }
+ TelephonyProperties.operator_alpha(newList);
+ Log.e(TAG, "successfully truncated operator_alpha: " + newList);
+ }
}
}
@@ -11930,7 +11949,7 @@ public class TelephonyManager {
Log.d(TAG, "factoryReset: subId=" + subId);
ITelephony telephony = getITelephony();
if (telephony != null) {
- telephony.factoryReset(subId);
+ telephony.factoryReset(subId, getOpPackageName());
}
} catch (RemoteException e) {
}
@@ -11950,7 +11969,7 @@ public class TelephonyManager {
Log.d(TAG, "resetSettings: subId=" + getSubId());
ITelephony telephony = getITelephony();
if (telephony != null) {
- telephony.factoryReset(getSubId());
+ telephony.factoryReset(getSubId(), getOpPackageName());
}
} catch (RemoteException e) {
}
@@ -12171,10 +12190,7 @@ public class TelephonyManager {
})
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
public @Nullable ServiceState getServiceState() {
- return getServiceState(getRenouncedPermissions()
- .contains(Manifest.permission.ACCESS_FINE_LOCATION),
- getRenouncedPermissions()
- .contains(Manifest.permission.ACCESS_COARSE_LOCATION));
+ return getServiceState(getLocationData());
}
/**
@@ -12194,12 +12210,8 @@ public class TelephonyManager {
* <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
* or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges})
* and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
- * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
- * location related information which will be sent if the caller already possess
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permission
- * @param renounceCoarseLocationAccess Set this to true if the caller would not like to
- * receive location related information which will be sent if the caller already possess
- * {@link Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the permissions.
+ * @param includeLocationData Specifies if the caller would like to receive
+ * location related information.
* May return {@code null} when the subscription is inactive or when there was an error
* communicating with the phone process.
*/
@@ -12208,10 +12220,10 @@ public class TelephonyManager {
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_COARSE_LOCATION
})
- public @Nullable ServiceState getServiceState(boolean renounceFineLocationAccess,
- boolean renounceCoarseLocationAccess) {
- return getServiceStateForSubscriber(getSubId(), renounceFineLocationAccess,
- renounceCoarseLocationAccess);
+ public @Nullable ServiceState getServiceState(@IncludeLocationData int includeLocationData) {
+ return getServiceStateForSubscriber(getSubId(),
+ includeLocationData != INCLUDE_LOCATION_DATA_FINE,
+ includeLocationData == INCLUDE_LOCATION_DATA_NONE);
}
/**
@@ -13217,7 +13229,7 @@ public class TelephonyManager {
try {
ITelephony service = getITelephony();
if (service != null) {
- service.setDataEnabledForReason(subId, reason, enabled);
+ service.setDataEnabledForReason(subId, reason, enabled, getOpPackageName());
} else {
throw new IllegalStateException("telephony service is null.");
}
@@ -16169,12 +16181,61 @@ public class TelephonyManager {
*/
public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull TelephonyCallback callback) {
- registerTelephonyCallback(
- getRenouncedPermissions().contains(Manifest.permission.ACCESS_FINE_LOCATION),
- getRenouncedPermissions().contains(Manifest.permission.ACCESS_COARSE_LOCATION),
- executor, callback);
+ registerTelephonyCallback(getLocationData(), executor, callback);
+ }
+
+ private int getLocationData() {
+ boolean renounceCoarseLocation =
+ getRenouncedPermissions().contains(Manifest.permission.ACCESS_COARSE_LOCATION);
+ boolean renounceFineLocation =
+ getRenouncedPermissions().contains(Manifest.permission.ACCESS_FINE_LOCATION);
+ if (renounceCoarseLocation) {
+ return INCLUDE_LOCATION_DATA_NONE;
+ } else if (renounceFineLocation) {
+ return INCLUDE_LOCATION_DATA_COARSE;
+ } else {
+ return INCLUDE_LOCATION_DATA_FINE;
+ }
}
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"INCLUDE_LOCATION_DATA_"}, value = {
+ INCLUDE_LOCATION_DATA_NONE,
+ INCLUDE_LOCATION_DATA_COARSE,
+ INCLUDE_LOCATION_DATA_FINE})
+ public @interface IncludeLocationData {}
+
+ /**
+ * Specifies to not include any location related data.
+ *
+ * Indicates whether the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the
+ * permissions.
+ */
+ public static final int INCLUDE_LOCATION_DATA_NONE = 0;
+
+ /**
+ * Include coarse location data.
+ *
+ * Indicates whether the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the
+ * permissions.
+ */
+ public static final int INCLUDE_LOCATION_DATA_COARSE = 1;
+
+ /**
+ * Include fine location data.
+ *
+ * Indicates whether the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the
+ * permissions.
+ */
+ public static final int INCLUDE_LOCATION_DATA_FINE = 2;
+
/**
* Registers a callback object to receive notification of changes in specified telephony states.
* <p>
@@ -16208,17 +16269,12 @@ public class TelephonyManager {
* apps. To avoid confusion, calling this method supersede renouncing permissions with a
* custom context.
*
- * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
- * location related information which will be sent if the caller already possess
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permissions.
- * @param renounceCoarseLocationAccess Set this to true if the caller would not like to
- * receive location related information which will be sent if the caller already possess
- * {@link Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the permissions.
+ * @param includeLocationData Specifies if the caller would like to receive
+ * location related information.
* @param executor The executor of where the callback will execute.
* @param callback The {@link TelephonyCallback} object to register.
*/
- public void registerTelephonyCallback(boolean renounceFineLocationAccess,
- boolean renounceCoarseLocationAccess,
+ public void registerTelephonyCallback(@IncludeLocationData int includeLocationData,
@NonNull @CallbackExecutor Executor executor,
@NonNull TelephonyCallback callback) {
if (mContext == null) {
@@ -16231,8 +16287,10 @@ public class TelephonyManager {
mTelephonyRegistryMgr = (TelephonyRegistryManager)
mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
if (mTelephonyRegistryMgr != null) {
- mTelephonyRegistryMgr.registerTelephonyCallback(renounceFineLocationAccess,
- renounceCoarseLocationAccess, executor, mSubId, getOpPackageName(),
+ mTelephonyRegistryMgr.registerTelephonyCallback(
+ includeLocationData != INCLUDE_LOCATION_DATA_FINE,
+ includeLocationData == INCLUDE_LOCATION_DATA_NONE,
+ executor, mSubId, getOpPackageName(),
getAttributionTag(), callback, getITelephony() != null);
} else {
throw new IllegalStateException("telephony service is null.");
diff --git a/telephony/java/android/telephony/cdma/OWNERS b/telephony/java/android/telephony/cdma/OWNERS
deleted file mode 100644
index 6aa399d9ebfb..000000000000
--- a/telephony/java/android/telephony/cdma/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-amitmahajan@google.com
diff --git a/telephony/java/android/telephony/data/OWNERS b/telephony/java/android/telephony/data/OWNERS
index 932b35cbdff7..9dce36640cb5 100644
--- a/telephony/java/android/telephony/data/OWNERS
+++ b/telephony/java/android/telephony/data/OWNERS
@@ -1,5 +1,6 @@
-# Bug component: 20868
+set noparent
-rgreenwalt@google.com
-tgunn@google.com
jackyu@google.com
+amruthr@google.com
+rgreenwalt@google.com
+
diff --git a/telephony/java/android/telephony/emergency/OWNERS b/telephony/java/android/telephony/emergency/OWNERS
index fa07dce5f615..1d8de5d9f895 100644
--- a/telephony/java/android/telephony/emergency/OWNERS
+++ b/telephony/java/android/telephony/emergency/OWNERS
@@ -1,5 +1,3 @@
-# Bug component: 20868
+set noparent
-rgreenwalt@google.com
-tgunn@google.com
-shuoq@google.com
+file:platform/frameworks/base:/telecomm/OWNERS
diff --git a/telephony/java/android/telephony/euicc/OWNERS b/telephony/java/android/telephony/euicc/OWNERS
index 9e51a4b30516..781550cd871d 100644
--- a/telephony/java/android/telephony/euicc/OWNERS
+++ b/telephony/java/android/telephony/euicc/OWNERS
@@ -1,6 +1,4 @@
-# Bug component: 20868
+set noparent
+
+file:platform/frameworks/base:/telephony/java/android/service/euicc/OWNERS
-rgreenwalt@google.com
-tgunn@google.com
-refuhoo@google.com
-amitmahajan@google.com
diff --git a/telephony/java/android/telephony/gsm/OWNERS b/telephony/java/android/telephony/gsm/OWNERS
deleted file mode 100644
index 6aa399d9ebfb..000000000000
--- a/telephony/java/android/telephony/gsm/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-amitmahajan@google.com
diff --git a/telephony/java/android/telephony/ims/OWNERS b/telephony/java/android/telephony/ims/OWNERS
index 0854c5d45603..3c726807fb88 100644
--- a/telephony/java/android/telephony/ims/OWNERS
+++ b/telephony/java/android/telephony/ims/OWNERS
@@ -1,5 +1,6 @@
-# Bug component: 20868
+set noparent
rgreenwalt@google.com
tgunn@google.com
breadley@google.com
+amruthr@google.com
diff --git a/telephony/java/android/telephony/ims/aidl/OWNERS b/telephony/java/android/telephony/ims/aidl/OWNERS
deleted file mode 100644
index 0854c5d45603..000000000000
--- a/telephony/java/android/telephony/ims/aidl/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-breadley@google.com
diff --git a/telephony/java/android/telephony/ims/compat/OWNERS b/telephony/java/android/telephony/ims/compat/OWNERS
deleted file mode 100644
index 0854c5d45603..000000000000
--- a/telephony/java/android/telephony/ims/compat/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-breadley@google.com
diff --git a/telephony/java/android/telephony/ims/compat/feature/OWNERS b/telephony/java/android/telephony/ims/compat/feature/OWNERS
deleted file mode 100644
index 0854c5d45603..000000000000
--- a/telephony/java/android/telephony/ims/compat/feature/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-breadley@google.com
diff --git a/telephony/java/android/telephony/ims/compat/stub/OWNERS b/telephony/java/android/telephony/ims/compat/stub/OWNERS
deleted file mode 100644
index 0854c5d45603..000000000000
--- a/telephony/java/android/telephony/ims/compat/stub/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-breadley@google.com
diff --git a/telephony/java/android/telephony/ims/feature/OWNERS b/telephony/java/android/telephony/ims/feature/OWNERS
deleted file mode 100644
index 0854c5d45603..000000000000
--- a/telephony/java/android/telephony/ims/feature/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-breadley@google.com
diff --git a/telephony/java/android/telephony/ims/stub/OWNERS b/telephony/java/android/telephony/ims/stub/OWNERS
deleted file mode 100644
index 0854c5d45603..000000000000
--- a/telephony/java/android/telephony/ims/stub/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-breadley@google.com
diff --git a/telephony/java/android/telephony/mbms/OWNERS b/telephony/java/android/telephony/mbms/OWNERS
index 718e0a292605..1d8de5d9f895 100644
--- a/telephony/java/android/telephony/mbms/OWNERS
+++ b/telephony/java/android/telephony/mbms/OWNERS
@@ -1,5 +1,3 @@
-# Bug component: 20868
+set noparent
-rgreenwalt@google.com
-tgunn@google.com
-hallliu@google.com
+file:platform/frameworks/base:/telecomm/OWNERS
diff --git a/telephony/java/android/telephony/mbms/vendor/OWNERS b/telephony/java/android/telephony/mbms/vendor/OWNERS
deleted file mode 100644
index 718e0a292605..000000000000
--- a/telephony/java/android/telephony/mbms/vendor/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-
-rgreenwalt@google.com
-tgunn@google.com
-hallliu@google.com
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index cfd940dac750..7d116f9d5063 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -270,13 +270,13 @@ interface ITelephony {
* Allow mobile data connections.
*/
@UnsupportedAppUsage
- boolean enableDataConnectivity();
+ boolean enableDataConnectivity(String callingPackage);
/**
* Disallow mobile data connections.
*/
@UnsupportedAppUsage
- boolean disableDataConnectivity();
+ boolean disableDataConnectivity(String callingPackage);
/**
* Report whether data connectivity is possible.
@@ -959,8 +959,9 @@ interface ITelephony {
* @param subId user preferred subId.
* @param reason the reason the data enable change is taking place
* @param enable true to turn on, else false
+ * @param callingPackage the package that changed the data enabled state
*/
- void setDataEnabledForReason(int subId, int reason, boolean enable);
+ void setDataEnabledForReason(int subId, int reason, boolean enable, String callingPackage);
/**
* Return whether data is enabled for certain reason
@@ -1327,7 +1328,7 @@ interface ITelephony {
*/
PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId);
- void factoryReset(int subId);
+ void factoryReset(int subId, String callingPackage);
/**
* Returns users's current locale based on the SIM.
diff --git a/test-legacy/Android.mk b/test-legacy/Android.mk
index 284008c5be71..da9dc2505805 100644
--- a/test-legacy/Android.mk
+++ b/test-legacy/Android.mk
@@ -40,6 +40,10 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
include $(BUILD_STATIC_JAVA_LIBRARY)
+$(call declare-license-metadata,$(full_classes_jar),\
+ SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-MIT SPDX-license-identifier-Unicode-DFS,\
+ notice,$(LOCAL_PATH)/../NOTICE,Android,frameworks/base)
+
# Archive a copy of the classes.jar in SDK build.
$(call dist-for-goals,sdk,$(full_classes_jar):android.test.legacy.jar)
diff --git a/tests/FlickerTests/OWNERS b/tests/FlickerTests/OWNERS
index c1221e3940d2..d40ff5659708 100644
--- a/tests/FlickerTests/OWNERS
+++ b/tests/FlickerTests/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 909476
+# Bug component: 1157642
include /services/core/java/com/android/server/wm/OWNERS
natanieljr@google.com
pablogamito@google.com
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
index db2e645fd245..e2e1ae8b90a0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
@@ -114,7 +114,7 @@ class OpenImeWindowToOverViewTest(private val testSpec: FlickerTestParameter) {
}
}
- @Presubmit
+ @FlakyTest(bugId = 228011606)
@Test
fun imeLayerIsVisibleAndAssociatedWithAppWidow() {
testSpec.assertLayersStart {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
index 7e3ed8252f4c..4b268a871fa0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
@@ -32,12 +32,15 @@ import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
import com.android.server.wm.traces.common.WindowManagerConditionsFactory
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
+import org.junit.Assume
+import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
@@ -55,11 +58,16 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
@Presubmit
-class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestParameter) {
+open class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestParameter) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val testApp = SimpleAppHelper(instrumentation)
private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
+ @Before
+ open fun before() {
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ }
+
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTestShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt
index 2252a949ba00..edd52b76cd5c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTestShellTransit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.flicker.pip
+package com.android.server.wm.flicker.ime
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
@@ -24,22 +24,26 @@ import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import org.junit.Assume
import org.junit.Before
+
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
+/**
+ * Test IME windows switching with 2-Buttons or gestural navigation.
+ * To run this test: `atest FlickerTests:SwitchImeWindowsFromGestureNavTest`
+ */
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
-class PipRotationTestShellTransit(testSpec: FlickerTestParameter) : PipRotationTest(testSpec) {
+@FlakyTest(bugId = 228012334)
+class SwitchImeWindowsFromGestureNavTest_ShellTransit(testSpec: FlickerTestParameter)
+ : SwitchImeWindowsFromGestureNavTest(testSpec) {
@Before
override fun before() {
Assume.assumeTrue(isShellTransitionsEnabled)
}
-
- @FlakyTest(bugId = 227214914)
- override fun pipLayerRotates_StartingBounds() = super.pipLayerRotates_StartingBounds()
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index ee0f3d8cd945..6e33f66d111d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -26,12 +26,9 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.LAUNCHER_COMPONENT
import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.helpers.reopenAppFromOverview
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.traces.common.WindowManagerConditionsFactory
-import org.junit.Assume.assumeFalse
-import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -64,10 +61,6 @@ import org.junit.runners.Parameterized
@Group1
open class OpenAppFromOverviewTest(testSpec: FlickerTestParameter)
: OpenAppFromLauncherTransition(testSpec) {
- @Before
- open fun before() {
- assumeFalse(isShellTransitionsEnabled)
- }
/**
* Defines the transition used to run the test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest_ShellTransit.kt
deleted file mode 100644
index 55e1e9ba8557..000000000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest_ShellTransit.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.server.wm.flicker.launch
-
-import androidx.test.filters.FlakyTest
-import android.platform.test.annotations.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.annotation.Group1
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import org.junit.Assume.assumeTrue
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test launching an app from the recents app view (the overview)
- *
- * To run this test: `atest FlickerTests:OpenAppFromOverviewTest`
- *
- * Actions:
- * Launch [testApp]
- * Press recents
- * Relaunch an app [testApp] by selecting it in the overview screen, and wait animation to
- * complete (only this action is traced)
- *
- * Notes:
- * 1. Some default assertions (e.g., nav bar, status bar and screen covered)
- * are inherited [OpenAppTransition]
- * 2. Part of the test setup occurs automatically via
- * [com.android.server.wm.flicker.TransitionRunnerWithRules],
- * including configuring navigation mode, initial orientation and ensuring no
- * apps are running before setup
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group1
-class OpenAppFromOverviewTest_ShellTransit(testSpec: FlickerTestParameter)
- : OpenAppFromOverviewTest(testSpec) {
- @Before
- override fun before() {
- assumeTrue(isShellTransitionsEnabled)
- }
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 216266712)
- @Test
- override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 216266712)
- @Test
- override fun appWindowReplacesLauncherAsTopWindow() =
- super.appWindowReplacesLauncherAsTopWindow()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 218470989)
- @Test
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index fbd611a37d0a..f357177aade2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -27,10 +27,7 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.traces.common.FlickerComponentName
-import org.junit.Assume
-import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -64,11 +61,6 @@ open class OpenAppNonResizeableTest(testSpec: FlickerTestParameter)
override val testApp = NonResizeableAppHelper(instrumentation)
private val colorFadComponent = FlickerComponentName("", "ColorFade BLAST#")
- @Before
- open fun before() {
- Assume.assumeFalse(isShellTransitionsEnabled)
- }
-
/**
* Checks that the nav bar layer starts invisible, becomes visible during unlocking animation
* and remains visible at the end
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
index 4313b8dbc883..02c1a105949b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
@@ -17,7 +17,6 @@
package com.android.server.wm.flicker.launch
import android.app.Instrumentation
-import androidx.test.filters.FlakyTest
import android.platform.test.annotations.Presubmit
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
@@ -216,7 +215,7 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
* Checks that [testApp] window is not on top at the start of the transition, and then becomes
* the top visible window until the end of the transition.
*/
- @FlakyTest(bugId = 203538234)
+ @Presubmit
@Test
open fun appWindowBecomesTopWindow() {
testSpec.assertWm {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index 1eb3d8da9f1e..c89e6a44ab6c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -33,12 +33,15 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.navBarLayerIsVisible
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.statusBarLayerIsVisible
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
+import org.junit.Assume
+import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -70,6 +73,11 @@ open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestPa
private val startDisplayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
+ @Before
+ open fun before() {
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ }
+
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt
index 8a08d07e654e..b9fef085da29 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest_ShellTransit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package com.android.server.wm.flicker.launch
+package com.android.server.wm.flicker.quickswitch
-import androidx.test.filters.FlakyTest
import android.platform.test.annotations.RequiresDevice
+import androidx.test.filters.FlakyTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group1
@@ -30,30 +30,24 @@ import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
/**
- * Test launching an app while the device is locked
+ * Test quick switching back to previous app from last opened app
*
- * To run this test: `atest FlickerTests:OpenAppNonResizeableTest`
+ * To run this test: `atest FlickerTests:QuickSwitchBetweenTwoAppsBackTest`
*
* Actions:
- * Lock the device.
- * Launch an app on top of the lock screen [testApp] and wait animation to complete
+ * Launch an app [testApp1]
+ * Launch another app [testApp2]
+ * Swipe right from the bottom of the screen to quick switch back to the first app [testApp1]
*
- * Notes:
- * 1. Some default assertions (e.g., nav bar, status bar and screen covered)
- * are inherited [OpenAppTransition]
- * 2. Part of the test setup occurs automatically via
- * [com.android.server.wm.flicker.TransitionRunnerWithRules],
- * including configuring navigation mode, initial orientation and ensuring no
- * apps are running before setup
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-@FlakyTest(bugId = 219688533)
-class OpenAppNonResizeableTest_ShellTransit(testSpec: FlickerTestParameter)
- : OpenAppNonResizeableTest(testSpec) {
+@FlakyTest(bugId = 228009808)
+open class QuickSwitchBetweenTwoAppsBackTest_ShellTransit(testSpec: FlickerTestParameter)
+ : QuickSwitchBetweenTwoAppsBackTest(testSpec) {
@Before
override fun before() {
Assume.assumeTrue(isShellTransitionsEnabled)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 5474a42ccf52..725d2c3d818c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -32,6 +32,7 @@ import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.navBarLayerIsVisible
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
import com.android.server.wm.flicker.navBarWindowIsVisible
@@ -39,6 +40,8 @@ import com.android.server.wm.flicker.statusBarLayerIsVisible
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
import com.android.server.wm.traces.common.Rect
+import org.junit.Assume
+import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -68,6 +71,11 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
private val testApp1 = SimpleAppHelper(instrumentation)
private val testApp2 = NonResizeableAppHelper(instrumentation)
+ @Before
+ open fun before() {
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ }
+
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt
new file mode 100644
index 000000000000..9c9dedc23ff9
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.quickswitch
+
+import android.platform.test.annotations.RequiresDevice
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.annotation.Group1
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test quick switching back to previous app from last opened app
+ *
+ * To run this test: `atest FlickerTests:QuickSwitchBetweenTwoAppsForwardTest`
+ *
+ * Actions:
+ * Launch an app [testApp1]
+ * Launch another app [testApp2]
+ * Swipe right from the bottom of the screen to quick switch back to the first app [testApp1]
+ * Swipe left from the bottom of the screen to quick switch forward to the second app [testApp2]
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Group1
+open class QuickSwitchBetweenTwoAppsForwardTest_ShellTransit(testSpec: FlickerTestParameter)
+ : QuickSwitchBetweenTwoAppsForwardTest(testSpec) {
+ @Before
+ override fun before() {
+ Assume.assumeTrue(isShellTransitionsEnabled)
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index f83ae8707e43..cc4a4b2d38aa 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -28,7 +28,7 @@ import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.LAUNCHER_COMPONENT
-import com.android.server.wm.flicker.annotation.Group4
+import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.SimpleAppHelper
@@ -60,7 +60,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group4
+@Group1
class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val taplInstrumentation = LauncherInstrumentation()
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 2b944c666782..8b851e5cfc2b 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
@@ -25,13 +25,11 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.rules.WMFlickerServiceRuleForTestSpec
import com.android.server.wm.flicker.statusBarLayerIsVisible
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
-import org.junit.Assume
import org.junit.FixMethodOrder
import org.junit.Rule
import org.junit.Test
@@ -100,7 +98,7 @@ class ChangeAppRotationTest(
* Windows maybe recreated when rotated. Checks that the focus does not change or if it does,
* focus returns to [testApp]
*/
- @FlakyTest(bugId = 190185577)
+ @Presubmit
@Test
fun focusChanges() {
testSpec.assertEventLog {
@@ -130,18 +128,6 @@ class ChangeAppRotationTest(
@Presubmit
@Test
fun rotationLayerAppearsAndVanishes() {
- Assume.assumeFalse(isShellTransitionsEnabled)
- rotationLayerAppearsAndVanishesAssertion()
- }
-
- /**
- * Checks that the [FlickerComponentName.ROTATION] layer appears during the transition,
- * doesn't flicker, and disappears before the transition is complete
- */
- @FlakyTest(bugId = 218484127)
- @Test
- fun rotationLayerAppearsAndVanishes_shellTransit() {
- Assume.assumeTrue(isShellTransitionsEnabled)
rotationLayerAppearsAndVanishesAssertion()
}
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 15fd5e18b233..fac5baf7a2f9 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
@@ -26,11 +26,8 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.testapp.ActivityOptions
import com.android.server.wm.traces.common.FlickerComponentName
-import org.junit.Assume
-import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -84,11 +81,6 @@ open class SeamlessAppRotationTest(
) : RotationTransition(testSpec) {
override val testApp = SeamlessRotationAppHelper(instrumentation)
- @Before
- open fun before() {
- Assume.assumeFalse(isShellTransitionsEnabled)
- }
-
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest_ShellTransit.kt
deleted file mode 100644
index d397d5979803..000000000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest_ShellTransit.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.server.wm.flicker.rotation
-
-import androidx.test.filters.FlakyTest
-import android.platform.test.annotations.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.annotation.Group3
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import org.junit.Assume
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test opening an app and cycling through app rotations using seamless rotations
- *
- * Currently runs:
- * 0 -> 90 degrees
- * 0 -> 90 degrees (with starved UI thread)
- * 90 -> 0 degrees
- * 90 -> 0 degrees (with starved UI thread)
- *
- * Actions:
- * Launch an app in fullscreen and supporting seamless rotation (via intent)
- * Set initial device orientation
- * Start tracing
- * Change device orientation
- * Stop tracing
- *
- * To run this test: `atest FlickerTests:SeamlessAppRotationTest`
- *
- * To run only the presubmit assertions add: `--
- * --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
- * --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Presubmit`
- *
- * To run only the postsubmit assertions add: `--
- * --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
- * --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Postsubmit`
- *
- * To run only the flaky assertions add: `--
- * --module-arg FlickerTests:include-annotation:androidx.test.filters.FlakyTest`
- *
- * Notes:
- * 1. Some default assertions (e.g., nav bar, status bar and screen covered)
- * are inherited [RotationTransition]
- * 2. Part of the test setup occurs automatically via
- * [com.android.server.wm.flicker.TransitionRunnerWithRules],
- * including configuring navigation mode, initial orientation and ensuring no
- * apps are running before setup
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group3
-@FlakyTest(bugId = 219689723)
-class SeamlessAppRotationTest_ShellTransit(
- testSpec: FlickerTestParameter
-) : SeamlessAppRotationTest(testSpec) {
- @Before
- override fun before() {
- Assume.assumeTrue(isShellTransitionsEnabled)
- }
-}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 4cfa93b4ecf9..841b81c2a282 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -252,6 +252,9 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
&& TEST_TCP_BUFFER_SIZES_2.equals(lp.getTcpBufferSizes())));
verify(mNetworkAgent)
.setUnderlyingNetworks(eq(singletonList(TEST_UNDERLYING_NETWORK_RECORD_2.network)));
+
+ // Verify revalidation is triggered on VCN network
+ verify(mConnMgr).reportNetworkConnectivity(eq(mNetworkAgent.getNetwork()), eq(false));
}
private void triggerChildOpened() {
@@ -425,6 +428,9 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
triggerValidation(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
mTestLooper.dispatchAll();
+ verify(mConnMgr)
+ .reportNetworkConnectivity(eq(TEST_UNDERLYING_NETWORK_RECORD_1.network), eq(false));
+
final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
verify(mDeps, times(2))
.newWakeupMessage(
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index b165c6bed220..7b94e718fd0e 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -15,6 +15,8 @@ $(aapt2_results): .KATI_IMPLICIT_OUTPUTS := $(aapt2_results)-nocache
$(aapt2_results): $(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests
-$(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests --gtest_output=xml:$@ > /dev/null 2>&1
+$(call declare-0p-target,$(aapt2_results))
+
aapt2_results :=
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index a266b476bc0d..3285d8bafa4d 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -349,7 +349,7 @@ std::optional<std::vector<std::string>> FindFiles(const android::StringPiece& pa
const std::string root_dir = path.to_string();
std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()), closedir);
if (!d) {
- diag->Error(DiagMessage() << SystemErrorCodeToString(errno));
+ diag->Error(DiagMessage() << SystemErrorCodeToString(errno) << ": " << root_dir);
return {};
}