summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/core/Android.bp1
-rw-r--r--apct-tests/perftests/core/AndroidManifest.xml10
-rw-r--r--apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml21
-rw-r--r--apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java21
-rw-r--r--apct-tests/perftests/rubidium/Android.bp3
-rw-r--r--apct-tests/perftests/rubidium/assets/generate_bid.wasmbin0 -> 1308806 bytes
-rw-r--r--apct-tests/perftests/rubidium/assets/generate_bid_using_wasm.js24
-rw-r--r--apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java91
-rw-r--r--apct-tests/perftests/surfaceflinger/Android.bp40
-rw-r--r--apct-tests/perftests/surfaceflinger/AndroidManifest.xml33
-rw-r--r--apct-tests/perftests/surfaceflinger/AndroidTest.xml63
-rw-r--r--apct-tests/perftests/surfaceflinger/OWNERS1
-rw-r--r--apct-tests/perftests/surfaceflinger/README.md34
-rw-r--r--apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java53
-rw-r--r--apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java44
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java4
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/Ledger.java241
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/Scribe.java111
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java11
-rw-r--r--cmds/incidentd/src/IncidentService.cpp10
-rw-r--r--core/api/current.txt8
-rw-r--r--core/api/test-current.txt3
-rw-r--r--core/java/android/accounts/AbstractAccountAuthenticator.java27
-rw-r--r--core/java/android/accounts/IAccountAuthenticator.aidl8
-rw-r--r--core/java/android/app/ActivityThread.java45
-rw-r--r--core/java/android/app/ClientTransactionHandler.java4
-rw-r--r--core/java/android/app/IApplicationThread.aidl5
-rw-r--r--core/java/android/app/NotificationChannelGroup.java21
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java7
-rw-r--r--core/java/android/app/servertransaction/LaunchActivityItem.java19
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java8
-rw-r--r--core/java/android/content/pm/VerifierDeviceIdentity.java4
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java7
-rw-r--r--core/java/android/hardware/camera2/params/MandatoryStreamCombination.java6
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java1
-rw-r--r--core/java/android/os/INetworkManagementService.aidl3
-rw-r--r--core/java/android/os/OutcomeReceiver.java2
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java4
-rw-r--r--core/java/android/util/FeatureFlagUtils.java10
-rw-r--r--core/java/android/util/NtpTrustedTime.java210
-rw-r--r--core/java/android/util/SafetyProtectionUtils.java53
-rw-r--r--core/java/android/view/AttachedSurfaceControl.java13
-rw-r--r--core/java/android/view/SurfaceView.java70
-rw-r--r--core/java/android/view/ViewRootImpl.java46
-rw-r--r--core/java/android/view/WindowManager.java8
-rw-r--r--core/java/android/view/contentcapture/MainContentCaptureSession.java7
-rw-r--r--core/java/android/view/inputmethod/EditorInfo.java37
-rw-r--r--core/java/android/view/inputmethod/IInputMethodManagerInvoker.java18
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java154
-rw-r--r--core/java/android/view/inputmethod/InputMethodSubtype.java4
-rw-r--r--core/java/android/view/inputmethod/SurroundingText.java10
-rw-r--r--core/java/android/view/inputmethod/ViewFocusParameterInfo.java64
-rw-r--r--core/java/android/widget/Toast.java37
-rw-r--r--core/java/android/widget/ToastPresenter.java21
-rw-r--r--core/java/android/window/ITaskFragmentOrganizer.aidl7
-rw-r--r--core/java/android/window/ImeOnBackInvokedDispatcher.java2
-rw-r--r--core/java/android/window/SurfaceSyncGroup.java392
-rw-r--r--core/java/android/window/SurfaceSyncGroup.md86
-rw-r--r--core/java/android/window/SurfaceSyncer.java472
-rw-r--r--core/java/android/window/SurfaceSyncer.md80
-rw-r--r--core/java/android/window/TaskFragmentOrganizer.java41
-rw-r--r--core/java/com/android/internal/app/procstats/IProcessStats.aidl3
-rw-r--r--core/java/com/android/internal/inputmethod/ImeTracing.java3
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl27
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java2
-rw-r--r--core/java/com/android/internal/widget/LockscreenCredential.java12
-rw-r--r--core/proto/android/providers/settings/secure.proto9
-rw-r--r--core/res/AndroidManifest.xml10
-rw-r--r--core/res/res/layout/transient_notification_with_icon.xml46
-rw-r--r--core/res/res/values-af/strings.xml5
-rw-r--r--core/res/res/values-am/strings.xml5
-rw-r--r--core/res/res/values-ar/strings.xml5
-rw-r--r--core/res/res/values-as/strings.xml5
-rw-r--r--core/res/res/values-az/strings.xml5
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml5
-rw-r--r--core/res/res/values-be/strings.xml5
-rw-r--r--core/res/res/values-bg/strings.xml5
-rw-r--r--core/res/res/values-bn/strings.xml5
-rw-r--r--core/res/res/values-bs/strings.xml5
-rw-r--r--core/res/res/values-ca/strings.xml5
-rw-r--r--core/res/res/values-cs/strings.xml5
-rw-r--r--core/res/res/values-da/strings.xml5
-rw-r--r--core/res/res/values-de/strings.xml5
-rw-r--r--core/res/res/values-el/strings.xml5
-rw-r--r--core/res/res/values-en-rAU/strings.xml5
-rw-r--r--core/res/res/values-en-rCA/strings.xml5
-rw-r--r--core/res/res/values-en-rGB/strings.xml5
-rw-r--r--core/res/res/values-en-rIN/strings.xml5
-rw-r--r--core/res/res/values-en-rXC/strings.xml2
-rw-r--r--core/res/res/values-es-rUS/strings.xml5
-rw-r--r--core/res/res/values-es/strings.xml5
-rw-r--r--core/res/res/values-et/strings.xml5
-rw-r--r--core/res/res/values-eu/strings.xml9
-rw-r--r--core/res/res/values-fa/strings.xml5
-rw-r--r--core/res/res/values-fi/strings.xml5
-rw-r--r--core/res/res/values-fr-rCA/strings.xml5
-rw-r--r--core/res/res/values-fr/strings.xml5
-rw-r--r--core/res/res/values-gl/strings.xml7
-rw-r--r--core/res/res/values-gu/strings.xml5
-rw-r--r--core/res/res/values-hi/strings.xml9
-rw-r--r--core/res/res/values-hr/strings.xml5
-rw-r--r--core/res/res/values-hu/strings.xml5
-rw-r--r--core/res/res/values-hy/strings.xml5
-rw-r--r--core/res/res/values-in/strings.xml5
-rw-r--r--core/res/res/values-is/strings.xml5
-rw-r--r--core/res/res/values-it/strings.xml9
-rw-r--r--core/res/res/values-iw/strings.xml5
-rw-r--r--core/res/res/values-ja/strings.xml5
-rw-r--r--core/res/res/values-ka/strings.xml5
-rw-r--r--core/res/res/values-kk/strings.xml5
-rw-r--r--core/res/res/values-km/strings.xml5
-rw-r--r--core/res/res/values-kn/strings.xml11
-rw-r--r--core/res/res/values-ko/strings.xml5
-rw-r--r--core/res/res/values-ky/strings.xml7
-rw-r--r--core/res/res/values-lo/strings.xml5
-rw-r--r--core/res/res/values-lt/strings.xml5
-rw-r--r--core/res/res/values-lv/strings.xml5
-rw-r--r--core/res/res/values-mcc334-mnc020-pa/strings.xml2
-rw-r--r--core/res/res/values-mk/strings.xml5
-rw-r--r--core/res/res/values-ml/strings.xml5
-rw-r--r--core/res/res/values-mn/strings.xml5
-rw-r--r--core/res/res/values-mr/strings.xml7
-rw-r--r--core/res/res/values-ms/strings.xml5
-rw-r--r--core/res/res/values-my/strings.xml5
-rw-r--r--core/res/res/values-nb/strings.xml5
-rw-r--r--core/res/res/values-ne/strings.xml5
-rw-r--r--core/res/res/values-nl/strings.xml7
-rw-r--r--core/res/res/values-or/strings.xml13
-rw-r--r--core/res/res/values-pa/strings.xml5
-rw-r--r--core/res/res/values-pl/strings.xml5
-rw-r--r--core/res/res/values-pt-rBR/strings.xml5
-rw-r--r--core/res/res/values-pt-rPT/strings.xml5
-rw-r--r--core/res/res/values-pt/strings.xml5
-rw-r--r--core/res/res/values-ro/strings.xml5
-rw-r--r--core/res/res/values-ru/strings.xml13
-rw-r--r--core/res/res/values-si/strings.xml5
-rw-r--r--core/res/res/values-sk/strings.xml5
-rw-r--r--core/res/res/values-sl/strings.xml5
-rw-r--r--core/res/res/values-sq/strings.xml5
-rw-r--r--core/res/res/values-sr/strings.xml5
-rw-r--r--core/res/res/values-sv/strings.xml5
-rw-r--r--core/res/res/values-sw/strings.xml5
-rw-r--r--core/res/res/values-ta/strings.xml5
-rw-r--r--core/res/res/values-te/strings.xml41
-rw-r--r--core/res/res/values-th/strings.xml5
-rw-r--r--core/res/res/values-tl/strings.xml5
-rw-r--r--core/res/res/values-tr/strings.xml5
-rw-r--r--core/res/res/values-uk/strings.xml9
-rw-r--r--core/res/res/values-ur/strings.xml5
-rw-r--r--core/res/res/values-uz/strings.xml5
-rw-r--r--core/res/res/values-vi/strings.xml7
-rw-r--r--core/res/res/values-zh-rCN/strings.xml5
-rw-r--r--core/res/res/values-zh-rHK/strings.xml5
-rw-r--r--core/res/res/values-zh-rTW/strings.xml5
-rw-r--r--core/res/res/values-zu/strings.xml5
-rw-r--r--core/res/res/values/config.xml9
-rw-r--r--core/res/res/values/strings.xml4
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml1
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java4
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TestUtils.java9
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java7
-rw-r--r--core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java13
-rw-r--r--core/tests/coretests/src/android/net/NetworkPolicyTest.kt3
-rw-r--r--core/tests/coretests/src/android/util/NtpTrustedTimeTest.java164
-rw-r--r--core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java66
-rw-r--r--core/tests/coretests/src/android/view/inputmethod/SurroundingTextTest.java10
-rw-r--r--core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java4
-rw-r--r--data/etc/com.android.settings.xml1
-rw-r--r--data/etc/services.core.protolog.json24
-rw-r--r--data/keyboards/Vendor_1038_Product_1434.kl58
-rw-r--r--graphics/java/android/graphics/Typeface.java36
-rw-r--r--graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java177
-rw-r--r--identity/java/android/security/identity/Util.java55
-rw-r--r--keystore/java/android/security/keystore/KeyProtection.java35
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java6
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java15
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java33
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java5
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rXC/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java141
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java141
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java56
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt6
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java17
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java154
-rw-r--r--libs/hwui/jni/Typeface.cpp28
-rw-r--r--location/java/com/android/internal/location/GpsNetInitiatedHandler.java14
-rw-r--r--media/java/android/media/MediaRouter2.java10
-rw-r--r--media/java/android/media/MediaRouter2Manager.java168
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java12
-rw-r--r--packages/CompanionDeviceManager/res/values-am/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ar/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-as/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-be/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-bg/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-bn/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ca/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-cs/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-de/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-es-rUS/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-es/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-et/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-eu/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fa/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fi/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-gl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-gu/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hi/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hu/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hy/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-in/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-is/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-it/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ja/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ka/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-kk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-km/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-kn/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ko/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ky/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lo/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lt/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lv/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-mk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ml/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-mr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ms/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-nb/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ne/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-or/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pa/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ru/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sq/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sv/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sw/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ta/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-te/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-th/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-tr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-uk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ur/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-uz/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zu/strings.xml6
-rw-r--r--packages/PackageInstaller/res/values-hi/strings.xml2
-rw-r--r--packages/PackageInstaller/res/values-te/strings.xml2
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java36
-rw-r--r--packages/PrintSpooler/res/values-te/strings.xml2
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp1
-rw-r--r--packages/SettingsLib/MainSwitchPreference/Android.bp1
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml6
-rw-r--r--packages/SettingsLib/SettingsTransition/Android.bp1
-rw-r--r--packages/SettingsLib/Utils/Android.bp1
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java14
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java11
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java88
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java125
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java6
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt15
-rw-r--r--packages/SystemUI/checks/Android.bp6
-rw-r--r--packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt2
-rw-r--r--packages/SystemUI/compose/gallery/Android.bp1
-rw-r--r--packages/SystemUI/compose/gallery/AndroidManifest.xml33
-rw-r--r--packages/SystemUI/compose/gallery/app/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/compose/gallery/res/values-night/themes.xml26
-rw-r--r--packages/SystemUI/compose/gallery/res/values/themes.xml7
-rw-r--r--packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt30
-rw-r--r--packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryActivity.kt38
-rw-r--r--packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt44
-rw-r--r--packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/HomeScreen.kt59
-rw-r--r--packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/Screen.kt95
-rw-r--r--packages/SystemUI/res/layout/people_space_activity_no_conversations.xml1
-rw-r--r--packages/SystemUI/res/values-af/strings.xml12
-rw-r--r--packages/SystemUI/res/values-am/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml12
-rw-r--r--packages/SystemUI/res/values-as/strings.xml12
-rw-r--r--packages/SystemUI/res/values-az/strings.xml8
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml12
-rw-r--r--packages/SystemUI/res/values-be/strings.xml12
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml12
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml12
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml12
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml12
-rw-r--r--packages/SystemUI/res/values-da/strings.xml12
-rw-r--r--packages/SystemUI/res/values-de/strings.xml12
-rw-r--r--packages/SystemUI/res/values-el/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml9
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml9
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml9
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml9
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml5
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml12
-rw-r--r--packages/SystemUI/res/values-es/strings.xml12
-rw-r--r--packages/SystemUI/res/values-et/strings.xml12
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml12
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml12
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml12
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml12
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml12
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml12
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml12
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml12
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml12
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml12
-rw-r--r--packages/SystemUI/res/values-in/strings.xml12
-rw-r--r--packages/SystemUI/res/values-is/strings.xml12
-rw-r--r--packages/SystemUI/res/values-it/strings.xml21
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml12
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml12
-rw-r--r--packages/SystemUI/res/values-km/strings.xml12
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml12
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml12
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml12
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml12
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml12
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml12
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml12
-rw-r--r--packages/SystemUI/res/values-my/strings.xml12
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml12
-rw-r--r--packages/SystemUI/res/values-night/styles.xml1
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml12
-rw-r--r--packages/SystemUI/res/values-or/strings.xml12
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml12
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml12
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml12
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml12
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml12
-rw-r--r--packages/SystemUI/res/values-si/strings.xml12
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml12
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml12
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml12
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml12
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml12
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml12
-rw-r--r--packages/SystemUI/res/values-te/strings.xml26
-rw-r--r--packages/SystemUI/res/values-th/strings.xml12
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml12
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml12
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml12
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml12
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml12
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml12
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml12
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml12
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml12
-rw-r--r--packages/SystemUI/res/values/dimens.xml7
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java132
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/OWNERS1
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/PanelView.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/PanelViewController.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java)11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt227
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt158
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt (renamed from apct-tests/perftests/core/src/android/view/HandwritingImeService.java)26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/UserCreator.java85
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/UserCreator.kt81
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt84
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java205
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java71
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt205
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt250
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt73
-rw-r--r--proto/src/system_messages.proto4
-rw-r--r--sax/tests/saxtests/src/android/sax/SafeSaxTest.java10
-rw-r--r--services/core/java/android/content/pm/PackageManagerInternal.java2
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java6
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java7
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java2
-rw-r--r--services/core/java/com/android/server/am/ProcessStatsService.java9
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java34
-rw-r--r--services/core/java/com/android/server/audio/SpatializerHelper.java254
-rw-r--r--services/core/java/com/android/server/clipboard/ClipboardService.java18
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java17
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java276
-rw-r--r--services/core/java/com/android/server/display/brightness/BrightnessEvent.java262
-rw-r--r--services/core/java/com/android/server/display/brightness/BrightnessReason.java200
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java11
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java186
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java2
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodUtils.java90
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java5
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssConfiguration.java57
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssLocationProvider.java42
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java9
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java323
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsStorage.java25
-rw-r--r--services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java71
-rw-r--r--services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java662
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyLogger.java55
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java12
-rw-r--r--services/core/java/com/android/server/notification/NotificationHistoryDatabase.java97
-rw-r--r--services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java2
-rw-r--r--services/core/java/com/android/server/notification/NotificationHistoryJobService.java81
-rw-r--r--services/core/java/com/android/server/notification/NotificationHistoryManager.java24
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerInternal.java2
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java21
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java50
-rw-r--r--services/core/java/com/android/server/pm/ApexPackageInfo.java205
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java70
-rw-r--r--services/core/java/com/android/server/pm/InitAppsHelper.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java9
-rw-r--r--services/core/java/com/android/server/pm/ScanPackageUtils.java4
-rw-r--r--services/core/java/com/android/server/pm/Settings.java3
-rw-r--r--services/core/java/com/android/server/pm/UserSystemPackageInstaller.java45
-rw-r--r--services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java8
-rw-r--r--services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java4
-rw-r--r--services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java2
-rw-r--r--services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java8
-rw-r--r--services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java1
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java2
-rw-r--r--services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java63
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java28
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java3
-rw-r--r--services/core/java/com/android/server/wm/AnrController.java6
-rw-r--r--services/core/java/com/android/server/wm/AsyncRotationController.java7
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java65
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java19
-rw-r--r--services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java6
-rw-r--r--services/core/java/com/android/server/wm/LaunchParamsUtil.java129
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java69
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java20
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java35
-rw-r--r--services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java97
-rw-r--r--services/core/java/com/android/server/wm/Transition.java29
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java104
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java14
-rw-r--r--services/tests/PackageManagerServiceTests/appenumeration/Android.bp1
-rw-r--r--services/tests/PackageManagerServiceTests/appenumeration/AndroidTest.xml2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java87
-rw-r--r--services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java78
-rw-r--r--services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java92
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java34
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java68
-rw-r--r--services/tests/servicestests/src/com/android/server/tare/LedgerTest.java280
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java21
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java108
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java46
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java25
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java (renamed from services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerContinuousTest.java)8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java (renamed from services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java)95
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java (renamed from services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java)29
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java3
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java19
-rw-r--r--tests/Camera2Tests/CameraToo/Android.bp28
-rw-r--r--tests/Camera2Tests/CameraToo/Android.mk26
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt38
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt49
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt60
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt13
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt20
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt15
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt7
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt8
-rw-r--r--tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java26
-rw-r--r--tests/UpdatableSystemFontTest/Android.bp1
-rw-r--r--tests/backup/Android.bp54
-rw-r--r--tests/backup/Android.mk53
-rw-r--r--tools/lint/Android.bp6
722 files changed, 10647 insertions, 5239 deletions
diff --git a/apct-tests/perftests/core/Android.bp b/apct-tests/perftests/core/Android.bp
index ab20fdbde1e5..23464f879518 100644
--- a/apct-tests/perftests/core/Android.bp
+++ b/apct-tests/perftests/core/Android.bp
@@ -43,7 +43,6 @@ android_test {
"apct-perftests-resources-manager-apps",
"apct-perftests-utils",
"collector-device-lib",
- "compatibility-device-util-axt",
"core-tests-support",
"guava",
],
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml
index c153201cd475..bb57161b4f6b 100644
--- a/apct-tests/perftests/core/AndroidManifest.xml
+++ b/apct-tests/perftests/core/AndroidManifest.xml
@@ -55,16 +55,6 @@
</intent-filter>
</service>
- <service android:name="android.view.HandwritingImeService"
- android:label="Handwriting IME"
- android:permission="android.permission.BIND_INPUT_METHOD"
- android:exported="true">
- <intent-filter>
- <action android:name="android.view.InputMethod"/>
- </intent-filter>
- <meta-data android:name="android.view.im"
- android:resource="@xml/ime_meta_handwriting"/>
- </service>
</application>
<instrumentation android:name="androidx.benchmark.junit4.AndroidBenchmarkRunner"
diff --git a/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml b/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml
deleted file mode 100644
index 24c0c255c2f3..000000000000
--- a/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<input-method
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:settingsActivity="com.android.inputmethod.latin.settings.SettingsActivity"
- android:supportsStylusHandwriting="true"/>
diff --git a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
index cf76334ceb10..123b2eeba5dd 100644
--- a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
@@ -22,6 +22,7 @@ import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.TOOL_TYPE_FINGER;
import static android.view.MotionEvent.TOOL_TYPE_STYLUS;
+
import android.app.Instrumentation;
import android.content.Context;
import android.perftests.utils.BenchmarkState;
@@ -33,15 +34,11 @@ import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
-import com.android.compatibility.common.util.PollingCheck;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.concurrent.TimeUnit;
-
/**
* Benchmark tests for {@link HandwritingInitiator}
*
@@ -59,21 +56,11 @@ public class HandwritingInitiatorPerfTest {
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Before
- public void setup() throws Exception {
- final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
- mContext = instrumentation.getTargetContext();
-
- String imeId = HandwritingImeService.getImeId();
- instrumentation.getUiAutomation().executeShellCommand("ime enable " + imeId);
- instrumentation.getUiAutomation().executeShellCommand("ime set " + imeId);
- PollingCheck.check("Check that stylus handwriting is available",
- TimeUnit.SECONDS.toMillis(10),
- () -> mContext.getSystemService(InputMethodManager.class)
- .isStylusHandwritingAvailable());
-
+ public void setup() {
+ final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mContext = mInstrumentation.getTargetContext();
final ViewConfiguration viewConfiguration = ViewConfiguration.get(mContext);
mTouchSlop = viewConfiguration.getScaledTouchSlop();
-
final InputMethodManager inputMethodManager =
mContext.getSystemService(InputMethodManager.class);
mHandwritingInitiator = new HandwritingInitiator(viewConfiguration, inputMethodManager);
diff --git a/apct-tests/perftests/rubidium/Android.bp b/apct-tests/perftests/rubidium/Android.bp
index 1f764d69f61a..ba2b44241c5a 100644
--- a/apct-tests/perftests/rubidium/Android.bp
+++ b/apct-tests/perftests/rubidium/Android.bp
@@ -29,10 +29,11 @@ android_test {
"androidx.test.rules",
"androidx.annotation_annotation",
"apct-perftests-utils",
- "collector-device-lib",
+ "collector-device-lib-platform",
"compatibility-device-util-axt",
"platform-test-annotations",
"adservices-service-core",
+ "androidx.core_core",
],
test_suites: ["device-tests"],
data: [":perfetto_artifacts"],
diff --git a/apct-tests/perftests/rubidium/assets/generate_bid.wasm b/apct-tests/perftests/rubidium/assets/generate_bid.wasm
new file mode 100644
index 000000000000..5e7fe9ee5fe7
--- /dev/null
+++ b/apct-tests/perftests/rubidium/assets/generate_bid.wasm
Binary files differ
diff --git a/apct-tests/perftests/rubidium/assets/generate_bid_using_wasm.js b/apct-tests/perftests/rubidium/assets/generate_bid_using_wasm.js
new file mode 100644
index 000000000000..bc50d0af0954
--- /dev/null
+++ b/apct-tests/perftests/rubidium/assets/generate_bid_using_wasm.js
@@ -0,0 +1,24 @@
+function generateBid(ad, wasmModule) {
+ let input = ad.metadata.input;
+
+ const instance = new WebAssembly.Instance(wasmModule);
+
+ const memory = instance.exports.memory;
+ const input_in_memory = new Float32Array(memory.buffer, 0, 200);
+ for (let i = 0; i < input.length; ++i) {
+ input_in_memory[i] = input[i];
+ }
+ const results = [
+ instance.exports.nn_forward_model0(input_in_memory.length, input_in_memory),
+ instance.exports.nn_forward_model1(input_in_memory.length, input_in_memory),
+ instance.exports.nn_forward_model2(input_in_memory.length, input_in_memory),
+ instance.exports.nn_forward_model3(input_in_memory.length, input_in_memory),
+ instance.exports.nn_forward_model4(input_in_memory.length, input_in_memory),
+ ];
+ const bid = results.map(x => Math.max(x, 1)).reduce((x, y) => x * y);
+ return {
+ ad: 'example',
+ bid: bid,
+ render: ad.renderUrl
+ }
+} \ No newline at end of file
diff --git a/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java b/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
index bf9ff3a47c40..81685cbbd594 100644
--- a/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
+++ b/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
@@ -24,6 +24,9 @@ import static com.android.adservices.service.js.JSScriptArgument.stringArrayArg;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
+
+import android.annotation.SuppressLint;
import android.content.Context;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
@@ -51,32 +54,34 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
/** To run the unit tests for this class, run "atest RubidiumPerfTests:JSScriptEnginePerfTests" */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class JSScriptEnginePerfTests {
- private static final String TAG = JSScriptEnginePerfTests.class.getSimpleName();
+ private static final String TAG = JSScriptEngine.TAG;
private static final Context sContext = ApplicationProvider.getApplicationContext();
private static final ExecutorService sExecutorService = Executors.newFixedThreadPool(10);
- private static JSScriptEngine sJSScriptEngine;
+ private static final JSScriptEngine sJSScriptEngine =
+ JSScriptEngine.getInstanceForTesting(
+ sContext, Profiler.createInstance(JSScriptEngine.TAG));
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Before
public void before() throws Exception {
- Profiler profiler = Profiler.createInstance(JSScriptEngine.TAG);
- sJSScriptEngine = JSScriptEngine.getInstanceForTesting(sContext, profiler);
-
// Warm up the sandbox env.
callJSEngine(
"function test() { return \"hello world\";" + " }", ImmutableList.of(), "test");
@@ -156,6 +161,7 @@ public class JSScriptEnginePerfTests {
runParametrizedTurtledoveScript(75);
}
+ @SuppressLint("DefaultLocale")
private void runParametrizedTurtledoveScript(int numAds) throws Exception {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
state.pauseTiming();
@@ -220,7 +226,34 @@ public class JSScriptEnginePerfTests {
return arrayArg("foo", Collections.nCopies(numCustomAudiences, interestGroupArg));
}
- private static String callJSEngine(
+ @Test
+ public void evaluate_turtledoveWasm() throws Exception {
+ assumeTrue(sJSScriptEngine.isWasmSupported().get(3, TimeUnit.SECONDS));
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ state.pauseTiming();
+
+ String jsTestFile = readAsset("generate_bid_using_wasm.js");
+ byte[] wasmTestFile = readBinaryAsset("generate_bid.wasm");
+ JSScriptArgument[] inputBytes = new JSScriptArgument[200];
+ Random rand = new Random();
+ for (int i = 0; i < inputBytes.length; i++) {
+ byte value = (byte) (rand.nextInt(2 * Byte.MAX_VALUE) - Byte.MIN_VALUE);
+ inputBytes[i] = JSScriptArgument.numericArg("_", value);
+ }
+ JSScriptArgument adDataArgument =
+ recordArg(
+ "ad",
+ stringArg("render_url", "http://google.com"),
+ recordArg("metadata", JSScriptArgument.arrayArg("input", inputBytes)));
+
+ state.resumeTiming();
+ while (state.keepRunning()) {
+ callJSEngine(jsTestFile, wasmTestFile, ImmutableList.of(adDataArgument), "generateBid");
+ }
+ }
+
+ private String callJSEngine(
@NonNull String jsScript,
@NonNull List<JSScriptArgument> args,
@NonNull String functionName)
@@ -228,6 +261,15 @@ public class JSScriptEnginePerfTests {
return callJSEngine(sJSScriptEngine, jsScript, args, functionName);
}
+ private String callJSEngine(
+ @NonNull String jsScript,
+ @NonNull byte[] wasmScript,
+ @NonNull List<JSScriptArgument> args,
+ @NonNull String functionName)
+ throws Exception {
+ return callJSEngine(sJSScriptEngine, jsScript, wasmScript, args, functionName);
+ }
+
private static String callJSEngine(
@NonNull JSScriptEngine jsScriptEngine,
@NonNull String jsScript,
@@ -241,6 +283,21 @@ public class JSScriptEnginePerfTests {
return futureResult.get();
}
+ private String callJSEngine(
+ @NonNull JSScriptEngine jsScriptEngine,
+ @NonNull String jsScript,
+ @NonNull byte[] wasmScript,
+ @NonNull List<JSScriptArgument> args,
+ @NonNull String functionName)
+ throws Exception {
+ CountDownLatch resultLatch = new CountDownLatch(1);
+ ListenableFuture<String> futureResult =
+ callJSEngineAsync(
+ jsScriptEngine, jsScript, wasmScript, args, functionName, resultLatch);
+ resultLatch.await();
+ return futureResult.get();
+ }
+
private static ListenableFuture<String> callJSEngineAsync(
@NonNull String jsScript,
@NonNull List<JSScriptArgument> args,
@@ -261,4 +318,26 @@ public class JSScriptEnginePerfTests {
result.addListener(resultLatch::countDown, sExecutorService);
return result;
}
+
+ private ListenableFuture<String> callJSEngineAsync(
+ @NonNull JSScriptEngine engine,
+ @NonNull String jsScript,
+ @NonNull byte[] wasmScript,
+ @NonNull List<JSScriptArgument> args,
+ @NonNull String functionName,
+ @NonNull CountDownLatch resultLatch) {
+ Objects.requireNonNull(engine);
+ Objects.requireNonNull(resultLatch);
+ ListenableFuture<String> result = engine.evaluate(jsScript, wasmScript, args, functionName);
+ result.addListener(resultLatch::countDown, sExecutorService);
+ return result;
+ }
+
+ private byte[] readBinaryAsset(@NonNull String assetName) throws IOException {
+ return sContext.getAssets().open(assetName).readAllBytes();
+ }
+
+ private String readAsset(@NonNull String assetName) throws IOException {
+ return new String(readBinaryAsset(assetName), StandardCharsets.UTF_8);
+ }
}
diff --git a/apct-tests/perftests/surfaceflinger/Android.bp b/apct-tests/perftests/surfaceflinger/Android.bp
new file mode 100644
index 000000000000..0c28bcef469c
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/Android.bp
@@ -0,0 +1,40 @@
+// 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+ name: "SurfaceFlingerPerfTests",
+ srcs: ["src/**/*.java"],
+ libs: ["android.test.runner.stubs"],
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "androidx.annotation_annotation",
+ "apct-perftests-utils",
+ "collector-device-lib",
+ "platform-test-annotations",
+ ],
+ test_suites: ["device-tests"],
+ data: [":perfetto_artifacts"],
+ platform_apis: true,
+ certificate: "platform",
+}
diff --git a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
new file mode 100644
index 000000000000..89a5219a8cff
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.perftests.surfaceflinger">
+
+ <application android:label="SurfaceFlingerPerfTests">
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="android.perftests.utils.SurfaceFlingerTestActivity"
+ android:exported="true">
+
+ <intent-filter>
+ <action android:name="com.android.perftests.core.PERFTEST" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.perftests.surfaceflinger">
+ </instrumentation>
+</manifest>
diff --git a/apct-tests/perftests/surfaceflinger/AndroidTest.xml b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
new file mode 100644
index 000000000000..b8bd8b42917b
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
@@ -0,0 +1,63 @@
+<?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.
+-->
+<configuration description="Runs SurfaceFlingerPerfTests metric instrumentation.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-metric-instrumentation" />
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="SurfaceFlingerPerfTests.apk" />
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <option name="force-skip-system-props" value="true" />
+ <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+ <option name="run-command" value="cmd window dismiss-keyguard" />
+ <option name="run-command" value="cmd package compile -m speed android.perftests.surfaceflinger" />
+ </target_preparer>
+
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
+ </target_preparer>
+
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false" />
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="package" value="android.perftests.surfaceflinger" />
+ <option name="hidden-api-checks" value="false"/>
+
+ <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
+ <option name="device-listeners" value="android.device.collectors.PerfettoListener,android.device.collectors.SimpleperfListener" />
+
+ <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
+ <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
+ </test>
+
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="directory-keys" value="/data/local/tmp/SurfaceFlingerPerfTests" />
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <option name="pull-pattern-keys" value="perfetto_file_path" />
+ </metrics_collector>
+
+</configuration>
diff --git a/apct-tests/perftests/surfaceflinger/OWNERS b/apct-tests/perftests/surfaceflinger/OWNERS
new file mode 100644
index 000000000000..0862c05e0ee4
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/apct-tests/perftests/surfaceflinger/README.md b/apct-tests/perftests/surfaceflinger/README.md
new file mode 100644
index 000000000000..0dec70f3cf18
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/README.md
@@ -0,0 +1,34 @@
+## SurfaceFlinger performance tests
+
+### Precondition
+To reduce the variance of the test, if `perf-setup.sh` (platform_testing/scripts/perf-setup)
+is available, it is better to use the following instructions to lock CPU and GPU frequencies.
+```
+m perf-setup
+PERF_SETUP_PATH=/data/local/tmp/perf-setup.sh
+adb push $OUT/$PERF_SETUP_PATH $PERF_SETUP_PATH
+adb shell chmod +x $PERF_SETUP_PATH
+adb shell $PERF_SETUP_PATH
+```
+
+### Example to run
+Use `atest`
+```
+atest SurfaceFlingerPerfTests:SurfaceFlingerPerfTest -- \
+ --module-arg SurfaceFlingerPerfTests:instrumentation-arg:kill-bg:=true
+```
+Use `am instrument`
+```
+adb shell am instrument -w -r -e class android.surfaceflinger.SurfaceFlingerPerfTest \
+ -e kill-bg true \
+ com.android.perftests.surfaceflinger/androidx.test.runner.AndroidJUnitRunner
+```
+* `kill-bg` is optional.
+
+Test arguments
+- kill-bg
+ * boolean: Kill background process before running test.
+- profiling-iterations
+ * int: Run the extra iterations with enabling method profiling.
+- profiling-sampling
+ * int: The interval (0=trace each method, default is 10) of sample profiling in microseconds.
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
new file mode 100644
index 000000000000..347cb7867a36
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.surfaceflinger;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.perftests.utils.SurfaceFlingerTestActivity;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
+
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class SurfaceFlingerPerfTest {
+ protected ActivityScenarioRule<SurfaceFlingerTestActivity> mActivityRule =
+ new ActivityScenarioRule<>(SurfaceFlingerTestActivity.class);
+ protected PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Rule
+ public final RuleChain mAllRules = RuleChain
+ .outerRule(mPerfStatusReporter)
+ .around(mActivityRule);
+
+ @Test
+ public void helloWorld() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ // Do Something
+ }
+
+ }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java b/apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java
new file mode 100644
index 000000000000..511ebbecf17e
--- /dev/null
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java
@@ -0,0 +1,44 @@
+/*
+ * 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.perftests.utils;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.SurfaceView;
+import android.view.WindowManager;
+import android.widget.LinearLayout;
+
+/**
+ * A simple activity used for testing, e.g. performance of activity switching, or as a base
+ * container of testing view.
+ */
+public class SurfaceFlingerTestActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+ final LinearLayout layout = new LinearLayout(this);
+ layout.setOrientation(LinearLayout.VERTICAL);
+
+ final SurfaceView surfaceview = new SurfaceView(this);
+ layout.addView(surfaceview);
+ setContentView(layout);
+
+ }
+}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
index d401373c0066..aeb6abc3ce1b 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
@@ -306,6 +306,10 @@ public abstract class EconomicPolicy {
return eventId & MASK_TYPE;
}
+ static boolean isReward(int eventId) {
+ return getEventType(eventId) == TYPE_REWARD;
+ }
+
@NonNull
static String eventToString(int eventId) {
switch (eventId & MASK_TYPE) {
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
index 2e2a9b56d3df..e91ed1287e1b 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
@@ -17,15 +17,19 @@
package com.android.server.tare;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static android.util.TimeUtils.dumpTime;
import static com.android.server.tare.TareUtils.cakeToString;
-import static com.android.server.tare.TareUtils.dumpTime;
import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.IndentingPrintWriter;
import android.util.SparseLongArray;
+import android.util.TimeUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.List;
@@ -34,6 +38,21 @@ import java.util.List;
* Ledger to track the last recorded balance and recent activities of an app.
*/
class Ledger {
+ /** The window size within which rewards will be counted and used towards reward limiting. */
+ private static final long TOTAL_REWARD_WINDOW_MS = 24 * HOUR_IN_MILLIS;
+ /** The number of buckets to split {@link #TOTAL_REWARD_WINDOW_MS} into. */
+ @VisibleForTesting
+ static final int NUM_REWARD_BUCKET_WINDOWS = 4;
+ /**
+ * The duration size of each bucket resulting from splitting {@link #TOTAL_REWARD_WINDOW_MS}
+ * into smaller buckets.
+ */
+ private static final long REWARD_BUCKET_WINDOW_SIZE_MS =
+ TOTAL_REWARD_WINDOW_MS / NUM_REWARD_BUCKET_WINDOWS;
+ /** The maximum number of transactions to retain in memory at any one time. */
+ @VisibleForTesting
+ static final int MAX_TRANSACTION_COUNT = 50;
+
static class Transaction {
public final long startTimeMs;
public final long endTimeMs;
@@ -54,18 +73,47 @@ class Ledger {
}
}
+ static class RewardBucket {
+ @CurrentTimeMillisLong
+ public long startTimeMs;
+ public final SparseLongArray cumulativeDelta = new SparseLongArray();
+
+ private void reset() {
+ startTimeMs = 0;
+ cumulativeDelta.clear();
+ }
+ }
+
/** Last saved balance. This doesn't take currently ongoing events into account. */
private long mCurrentBalance = 0;
- private final List<Transaction> mTransactions = new ArrayList<>();
- private final SparseLongArray mCumulativeDeltaPerReason = new SparseLongArray();
- private long mEarliestSumTime;
+ private final Transaction[] mTransactions = new Transaction[MAX_TRANSACTION_COUNT];
+ /** Index within {@link #mTransactions} where the next transaction should be placed. */
+ private int mTransactionIndex = 0;
+ private final RewardBucket[] mRewardBuckets = new RewardBucket[NUM_REWARD_BUCKET_WINDOWS];
+ /** Index within {@link #mRewardBuckets} of the current active bucket. */
+ private int mRewardBucketIndex = 0;
Ledger() {
}
- Ledger(long currentBalance, @NonNull List<Transaction> transactions) {
+ Ledger(long currentBalance, @NonNull List<Transaction> transactions,
+ @NonNull List<RewardBucket> rewardBuckets) {
mCurrentBalance = currentBalance;
- mTransactions.addAll(transactions);
+
+ final int numTxs = transactions.size();
+ for (int i = Math.max(0, numTxs - MAX_TRANSACTION_COUNT); i < numTxs; ++i) {
+ mTransactions[mTransactionIndex++] = transactions.get(i);
+ }
+ mTransactionIndex %= MAX_TRANSACTION_COUNT;
+
+ final int numBuckets = rewardBuckets.size();
+ if (numBuckets > 0) {
+ // Set the index to -1 so that we put the first bucket in index 0.
+ mRewardBucketIndex = -1;
+ for (int i = Math.max(0, numBuckets - NUM_REWARD_BUCKET_WINDOWS); i < numBuckets; ++i) {
+ mRewardBuckets[++mRewardBucketIndex] = rewardBuckets.get(i);
+ }
+ }
}
long getCurrentBalance() {
@@ -74,66 +122,142 @@ class Ledger {
@Nullable
Transaction getEarliestTransaction() {
- if (mTransactions.size() > 0) {
- return mTransactions.get(0);
+ for (int t = 0; t < mTransactions.length; ++t) {
+ final Transaction transaction =
+ mTransactions[(mTransactionIndex + t) % mTransactions.length];
+ if (transaction != null) {
+ return transaction;
+ }
}
return null;
}
@NonNull
+ List<RewardBucket> getRewardBuckets() {
+ final long cutoffMs = getCurrentTimeMillis() - TOTAL_REWARD_WINDOW_MS;
+ final List<RewardBucket> list = new ArrayList<>(NUM_REWARD_BUCKET_WINDOWS);
+ for (int i = 1; i <= NUM_REWARD_BUCKET_WINDOWS; ++i) {
+ final int idx = (mRewardBucketIndex + i) % NUM_REWARD_BUCKET_WINDOWS;
+ final RewardBucket rewardBucket = mRewardBuckets[idx];
+ if (rewardBucket != null) {
+ if (cutoffMs <= rewardBucket.startTimeMs) {
+ list.add(rewardBucket);
+ } else {
+ rewardBucket.reset();
+ }
+ }
+ }
+ return list;
+ }
+
+ @NonNull
List<Transaction> getTransactions() {
- return mTransactions;
+ final List<Transaction> list = new ArrayList<>(MAX_TRANSACTION_COUNT);
+ for (int i = 0; i < MAX_TRANSACTION_COUNT; ++i) {
+ final int idx = (mTransactionIndex + i) % MAX_TRANSACTION_COUNT;
+ final Transaction transaction = mTransactions[idx];
+ if (transaction != null) {
+ list.add(transaction);
+ }
+ }
+ return list;
}
void recordTransaction(@NonNull Transaction transaction) {
- mTransactions.add(transaction);
+ mTransactions[mTransactionIndex] = transaction;
mCurrentBalance += transaction.delta;
+ mTransactionIndex = (mTransactionIndex + 1) % MAX_TRANSACTION_COUNT;
- final long sum = mCumulativeDeltaPerReason.get(transaction.eventId);
- mCumulativeDeltaPerReason.put(transaction.eventId, sum + transaction.delta);
- mEarliestSumTime = Math.min(mEarliestSumTime, transaction.startTimeMs);
+ if (EconomicPolicy.isReward(transaction.eventId)) {
+ final RewardBucket bucket = getCurrentRewardBucket();
+ bucket.cumulativeDelta.put(transaction.eventId,
+ bucket.cumulativeDelta.get(transaction.eventId, 0) + transaction.delta);
+ }
+ }
+
+ @NonNull
+ private RewardBucket getCurrentRewardBucket() {
+ RewardBucket bucket = mRewardBuckets[mRewardBucketIndex];
+ final long now = getCurrentTimeMillis();
+ if (bucket == null) {
+ bucket = new RewardBucket();
+ bucket.startTimeMs = now;
+ mRewardBuckets[mRewardBucketIndex] = bucket;
+ return bucket;
+ }
+
+ if (now - bucket.startTimeMs < REWARD_BUCKET_WINDOW_SIZE_MS) {
+ return bucket;
+ }
+
+ mRewardBucketIndex = (mRewardBucketIndex + 1) % NUM_REWARD_BUCKET_WINDOWS;
+ bucket = mRewardBuckets[mRewardBucketIndex];
+ if (bucket == null) {
+ bucket = new RewardBucket();
+ mRewardBuckets[mRewardBucketIndex] = bucket;
+ }
+ bucket.reset();
+ // Using now as the start time means there will be some gaps between sequential buckets,
+ // but makes processing of large gaps between events easier.
+ bucket.startTimeMs = now;
+ return bucket;
}
long get24HourSum(int eventId, final long now) {
final long windowStartTime = now - 24 * HOUR_IN_MILLIS;
- if (mEarliestSumTime < windowStartTime) {
- // Need to redo sums
- mCumulativeDeltaPerReason.clear();
- for (int i = mTransactions.size() - 1; i >= 0; --i) {
- final Transaction transaction = mTransactions.get(i);
- if (transaction.endTimeMs <= windowStartTime) {
- break;
- }
- long sum = mCumulativeDeltaPerReason.get(transaction.eventId);
- if (transaction.startTimeMs >= windowStartTime) {
- sum += transaction.delta;
- } else {
- // Pro-rate durationed deltas. Intentionally floor the result.
- sum += (long) (1.0 * (transaction.endTimeMs - windowStartTime)
- * transaction.delta)
- / (transaction.endTimeMs - transaction.startTimeMs);
- }
- mCumulativeDeltaPerReason.put(transaction.eventId, sum);
+ long sum = 0;
+ for (int i = 0; i < mRewardBuckets.length; ++i) {
+ final RewardBucket bucket = mRewardBuckets[i];
+ if (bucket != null
+ && bucket.startTimeMs >= windowStartTime && bucket.startTimeMs < now) {
+ sum += bucket.cumulativeDelta.get(eventId, 0);
}
- mEarliestSumTime = windowStartTime;
}
- return mCumulativeDeltaPerReason.get(eventId);
+ return sum;
}
- /** Deletes transactions that are older than {@code minAgeMs}. */
- void removeOldTransactions(long minAgeMs) {
+ /**
+ * Deletes transactions that are older than {@code minAgeMs}.
+ * @return The earliest transaction in the ledger, or {@code null} if there are no more
+ * transactions.
+ */
+ @Nullable
+ Transaction removeOldTransactions(long minAgeMs) {
final long cutoff = getCurrentTimeMillis() - minAgeMs;
- while (mTransactions.size() > 0 && mTransactions.get(0).endTimeMs <= cutoff) {
- mTransactions.remove(0);
+ for (int t = 0; t < mTransactions.length; ++t) {
+ final int idx = (mTransactionIndex + t) % mTransactions.length;
+ final Transaction transaction = mTransactions[idx];
+ if (transaction == null) {
+ continue;
+ }
+ if (transaction.endTimeMs <= cutoff) {
+ mTransactions[idx] = null;
+ } else {
+ // Everything we look at after this transaction will also be within the window,
+ // so no need to go further.
+ return transaction;
+ }
}
+ return null;
}
void dump(IndentingPrintWriter pw, int numRecentTransactions) {
pw.print("Current balance", cakeToString(getCurrentBalance())).println();
+ pw.println();
- final int size = mTransactions.size();
- for (int i = Math.max(0, size - numRecentTransactions); i < size; ++i) {
- final Transaction transaction = mTransactions.get(i);
+ boolean printedTransactionTitle = false;
+ for (int t = 0; t < Math.min(MAX_TRANSACTION_COUNT, numRecentTransactions); ++t) {
+ final int idx = (mTransactionIndex - t + MAX_TRANSACTION_COUNT) % MAX_TRANSACTION_COUNT;
+ final Transaction transaction = mTransactions[idx];
+ if (transaction == null) {
+ continue;
+ }
+
+ if (!printedTransactionTitle) {
+ pw.println("Transactions:");
+ pw.increaseIndent();
+ printedTransactionTitle = true;
+ }
dumpTime(pw, transaction.startTimeMs);
pw.print("--");
@@ -151,5 +275,42 @@ class Ledger {
pw.print(cakeToString(transaction.ctp));
pw.println(")");
}
+ if (printedTransactionTitle) {
+ pw.decreaseIndent();
+ pw.println();
+ }
+
+ final long now = getCurrentTimeMillis();
+ boolean printedBucketTitle = false;
+ for (int b = 0; b < NUM_REWARD_BUCKET_WINDOWS; ++b) {
+ final int idx = (mRewardBucketIndex - b + NUM_REWARD_BUCKET_WINDOWS)
+ % NUM_REWARD_BUCKET_WINDOWS;
+ final RewardBucket rewardBucket = mRewardBuckets[idx];
+ if (rewardBucket == null) {
+ continue;
+ }
+
+ if (!printedBucketTitle) {
+ pw.println("Reward buckets:");
+ pw.increaseIndent();
+ printedBucketTitle = true;
+ }
+
+ dumpTime(pw, rewardBucket.startTimeMs);
+ pw.print(" (");
+ TimeUtils.formatDuration(now - rewardBucket.startTimeMs, pw);
+ pw.println(" ago):");
+ pw.increaseIndent();
+ for (int r = 0; r < rewardBucket.cumulativeDelta.size(); ++r) {
+ pw.print(EconomicPolicy.eventToString(rewardBucket.cumulativeDelta.keyAt(r)));
+ pw.print(": ");
+ pw.println(cakeToString(rewardBucket.cumulativeDelta.valueAt(r)));
+ }
+ pw.decreaseIndent();
+ }
+ if (printedBucketTitle) {
+ pw.decreaseIndent();
+ pw.println();
+ }
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java b/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java
index 941cc39f2d97..8f7657e6c414 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java
@@ -62,15 +62,14 @@ public class Scribe {
private static final int MAX_NUM_TRANSACTION_DUMP = 25;
/**
* The maximum amount of time we'll keep a transaction around for.
- * For now, only keep transactions we actually have a use for. We can increase it if we want
- * to use older transactions or provide older transactions to apps.
*/
- private static final long MAX_TRANSACTION_AGE_MS = 24 * HOUR_IN_MILLIS;
+ private static final long MAX_TRANSACTION_AGE_MS = 8 * 24 * HOUR_IN_MILLIS;
private static final String XML_TAG_HIGH_LEVEL_STATE = "irs-state";
private static final String XML_TAG_LEDGER = "ledger";
private static final String XML_TAG_TARE = "tare";
private static final String XML_TAG_TRANSACTION = "transaction";
+ private static final String XML_TAG_REWARD_BUCKET = "rewardBucket";
private static final String XML_TAG_USER = "user";
private static final String XML_TAG_PERIOD_REPORT = "report";
@@ -346,8 +345,8 @@ public class Scribe {
for (int pIdx = mLedgers.numElementsForKey(userId) - 1; pIdx >= 0; --pIdx) {
final String pkgName = mLedgers.keyAt(uIdx, pIdx);
final Ledger ledger = mLedgers.get(userId, pkgName);
- ledger.removeOldTransactions(MAX_TRANSACTION_AGE_MS);
- Ledger.Transaction transaction = ledger.getEarliestTransaction();
+ final Ledger.Transaction transaction =
+ ledger.removeOldTransactions(MAX_TRANSACTION_AGE_MS);
if (transaction != null) {
earliestEndTime = Math.min(earliestEndTime, transaction.endTimeMs);
}
@@ -370,6 +369,7 @@ public class Scribe {
final String pkgName;
final long curBalance;
final List<Ledger.Transaction> transactions = new ArrayList<>();
+ final List<Ledger.RewardBucket> rewardBuckets = new ArrayList<>();
pkgName = parser.getAttributeValue(null, XML_ATTR_PACKAGE_NAME);
curBalance = parser.getAttributeLong(null, XML_ATTR_CURRENT_BALANCE);
@@ -391,8 +391,7 @@ public class Scribe {
}
continue;
}
- if (eventType != XmlPullParser.START_TAG || !XML_TAG_TRANSACTION.equals(tagName)) {
- // Expecting only "transaction" tags.
+ if (eventType != XmlPullParser.START_TAG || tagName == null) {
Slog.e(TAG, "Unexpected event: (" + eventType + ") " + tagName);
return null;
}
@@ -402,25 +401,37 @@ public class Scribe {
if (DEBUG) {
Slog.d(TAG, "Starting ledger tag: " + tagName);
}
- final String tag = parser.getAttributeValue(null, XML_ATTR_TAG);
- final long startTime = parser.getAttributeLong(null, XML_ATTR_START_TIME);
- final long endTime = parser.getAttributeLong(null, XML_ATTR_END_TIME);
- final int eventId = parser.getAttributeInt(null, XML_ATTR_EVENT_ID);
- final long delta = parser.getAttributeLong(null, XML_ATTR_DELTA);
- final long ctp = parser.getAttributeLong(null, XML_ATTR_CTP);
- if (endTime <= endTimeCutoff) {
- if (DEBUG) {
- Slog.d(TAG, "Skipping event because it's too old.");
- }
- continue;
+ switch (tagName) {
+ case XML_TAG_TRANSACTION:
+ final long endTime = parser.getAttributeLong(null, XML_ATTR_END_TIME);
+ if (endTime <= endTimeCutoff) {
+ if (DEBUG) {
+ Slog.d(TAG, "Skipping event because it's too old.");
+ }
+ continue;
+ }
+ final String tag = parser.getAttributeValue(null, XML_ATTR_TAG);
+ final long startTime = parser.getAttributeLong(null, XML_ATTR_START_TIME);
+ final int eventId = parser.getAttributeInt(null, XML_ATTR_EVENT_ID);
+ final long delta = parser.getAttributeLong(null, XML_ATTR_DELTA);
+ final long ctp = parser.getAttributeLong(null, XML_ATTR_CTP);
+ transactions.add(
+ new Ledger.Transaction(startTime, endTime, eventId, tag, delta, ctp));
+ break;
+ case XML_TAG_REWARD_BUCKET:
+ rewardBuckets.add(readRewardBucketFromXml(parser));
+ break;
+ default:
+ // Expecting only "transaction" and "rewardBucket" tags.
+ Slog.e(TAG, "Unexpected event: (" + eventType + ") " + tagName);
+ return null;
}
- transactions.add(new Ledger.Transaction(startTime, endTime, eventId, tag, delta, ctp));
}
if (!isInstalled) {
return null;
}
- return Pair.create(pkgName, new Ledger(curBalance, transactions));
+ return Pair.create(pkgName, new Ledger(curBalance, transactions, rewardBuckets));
}
/**
@@ -508,6 +519,44 @@ public class Scribe {
return report;
}
+ /**
+ * @param parser Xml parser at the beginning of a {@value #XML_TAG_REWARD_BUCKET} tag. The next
+ * "parser.next()" call will take the parser into the body of the tag.
+ * @return Newly instantiated {@link Ledger.RewardBucket} holding all the information we just
+ * read out of the xml tag.
+ */
+ @Nullable
+ private static Ledger.RewardBucket readRewardBucketFromXml(TypedXmlPullParser parser)
+ throws XmlPullParserException, IOException {
+
+ final Ledger.RewardBucket rewardBucket = new Ledger.RewardBucket();
+
+ rewardBucket.startTimeMs = parser.getAttributeLong(null, XML_ATTR_START_TIME);
+
+ for (int eventType = parser.next(); eventType != XmlPullParser.END_DOCUMENT;
+ eventType = parser.next()) {
+ final String tagName = parser.getName();
+ if (eventType == XmlPullParser.END_TAG) {
+ if (XML_TAG_REWARD_BUCKET.equals(tagName)) {
+ // We've reached the end of the rewardBucket tag.
+ break;
+ }
+ continue;
+ }
+ if (eventType != XmlPullParser.START_TAG || !XML_ATTR_DELTA.equals(tagName)) {
+ // Expecting only delta tags.
+ Slog.e(TAG, "Unexpected event: (" + eventType + ") " + tagName);
+ return null;
+ }
+
+ final int eventId = parser.getAttributeInt(null, XML_ATTR_EVENT_ID);
+ final long delta = parser.getAttributeLong(null, XML_ATTR_DELTA);
+ rewardBucket.cumulativeDelta.put(eventId, delta);
+ }
+
+ return rewardBucket;
+ }
+
private void scheduleCleanup(long earliestEndTime) {
if (earliestEndTime == Long.MAX_VALUE) {
return;
@@ -595,6 +644,11 @@ public class Scribe {
}
writeTransaction(out, transaction);
}
+
+ final List<Ledger.RewardBucket> rewardBuckets = ledger.getRewardBuckets();
+ for (int r = 0; r < rewardBuckets.size(); ++r) {
+ writeRewardBucket(out, rewardBuckets.get(r));
+ }
out.endTag(null, XML_TAG_LEDGER);
}
out.endTag(null, XML_TAG_USER);
@@ -616,6 +670,23 @@ public class Scribe {
out.endTag(null, XML_TAG_TRANSACTION);
}
+ private static void writeRewardBucket(@NonNull TypedXmlSerializer out,
+ @NonNull Ledger.RewardBucket rewardBucket) throws IOException {
+ final int numEvents = rewardBucket.cumulativeDelta.size();
+ if (numEvents == 0) {
+ return;
+ }
+ out.startTag(null, XML_TAG_REWARD_BUCKET);
+ out.attributeLong(null, XML_ATTR_START_TIME, rewardBucket.startTimeMs);
+ for (int i = 0; i < numEvents; ++i) {
+ out.startTag(null, XML_ATTR_DELTA);
+ out.attributeInt(null, XML_ATTR_EVENT_ID, rewardBucket.cumulativeDelta.keyAt(i));
+ out.attributeLong(null, XML_ATTR_DELTA, rewardBucket.cumulativeDelta.valueAt(i));
+ out.endTag(null, XML_ATTR_DELTA);
+ }
+ out.endTag(null, XML_TAG_REWARD_BUCKET);
+ }
+
private static void writeReport(@NonNull TypedXmlSerializer out,
@NonNull Analyst.Report report) throws IOException {
out.startTag(null, XML_TAG_PERIOD_REPORT);
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
index 6b6984f6ac17..aa4c75a0be80 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
@@ -19,26 +19,15 @@ package com.android.server.tare;
import static android.app.tare.EconomyManager.CAKE_IN_ARC;
import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.util.IndentingPrintWriter;
import com.android.internal.annotations.VisibleForTesting;
-import java.text.SimpleDateFormat;
import java.time.Clock;
class TareUtils {
- @SuppressLint("SimpleDateFormat")
- private static final SimpleDateFormat sDumpDateFormat =
- new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
-
@VisibleForTesting
static Clock sSystemClock = Clock.systemUTC();
- static void dumpTime(IndentingPrintWriter pw, long time) {
- pw.print(sDumpDateFormat.format(time));
- }
-
static long getCurrentTimeMillis() {
return sSystemClock.millis();
}
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index fbb99d2aea89..836801deaa08 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -47,10 +47,16 @@ enum {
#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day
// Skip these sections (for dumpstate only)
-// Skip logs (1100 - 1108) and traces (1200 - 1202) because they are already in the bug report.
+// Skip logs (1100 - 1108), traces (1200 - 1202), dumpsys (3000 - 3024, 3027 - 3056, 4000 - 4001)
+// because they are already in the bug report.
#define SKIPPED_DUMPSTATE_SECTIONS { \
1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
- 1200, 1201, 1202, /* Native, hal, java traces */ }
+ 1200, 1201, 1202, /* Native, hal, java traces */ \
+ 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, \
+ 3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3027, 3028, 3029, \
+ 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043, \
+ 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 4000, \
+ 4001, /* Dumpsys */ }
namespace android {
namespace os {
diff --git a/core/api/current.txt b/core/api/current.txt
index 1e1a4a6f5506..7fbf3ece4550 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -11219,9 +11219,9 @@ package android.content.pm {
field public int requiresSmallestWidthDp;
field public String[] sharedLibraryFiles;
field public String sourceDir;
- field public String[] splitNames;
- field public String[] splitPublicSourceDirs;
- field public String[] splitSourceDirs;
+ field @Nullable public String[] splitNames;
+ field @Nullable public String[] splitPublicSourceDirs;
+ field @Nullable public String[] splitSourceDirs;
field public java.util.UUID storageUuid;
field public int targetSdkVersion;
field public String taskAffinity;
@@ -31613,7 +31613,7 @@ package android.os {
public interface OutcomeReceiver<R, E extends java.lang.Throwable> {
method public default void onError(@NonNull E);
- method public void onResult(@NonNull R);
+ method public void onResult(R);
}
public final class Parcel {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index b13ebf388d1f..fccb3c0146cf 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1026,6 +1026,7 @@ package android.graphics {
}
public class Typeface {
+ method @NonNull public static android.util.Pair<java.util.List<android.graphics.Typeface>,java.util.List<android.graphics.Typeface>> changeDefaultFontForTest(@NonNull java.util.List<android.graphics.Typeface>, @NonNull java.util.List<android.graphics.Typeface>);
method @NonNull public static long[] deserializeFontMap(@NonNull java.nio.ByteBuffer, @NonNull java.util.Map<java.lang.String,android.graphics.Typeface>) throws java.io.IOException;
method @Nullable public static android.os.SharedMemory getSystemFontMapSharedMemory();
method @NonNull public static android.os.SharedMemory serializeFontMap(@NonNull java.util.Map<java.lang.String,android.graphics.Typeface>) throws android.system.ErrnoException, java.io.IOException;
@@ -3326,7 +3327,7 @@ package android.window {
method @NonNull public java.util.concurrent.Executor getExecutor();
method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizerToken();
method public void onTaskFragmentAppeared(@NonNull android.window.TaskFragmentInfo);
- method public void onTaskFragmentError(@NonNull android.os.IBinder, @NonNull Throwable);
+ method public void onTaskFragmentError(@NonNull android.os.IBinder, @Nullable android.window.TaskFragmentInfo, int, @NonNull Throwable);
method public void onTaskFragmentInfoChanged(@NonNull android.window.TaskFragmentInfo);
method public void onTaskFragmentParentInfoChanged(@NonNull android.os.IBinder, @NonNull android.content.res.Configuration);
method public void onTaskFragmentVanished(@NonNull android.window.TaskFragmentInfo);
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index f29998af7ae1..c2c065b5a360 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -16,11 +16,8 @@
package android.accounts;
-import android.Manifest;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
@@ -152,6 +149,7 @@ public abstract class AbstractAccountAuthenticator {
}
private class Transport extends IAccountAuthenticator.Stub {
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
@Override
public void addAccount(IAccountAuthenticatorResponse response, String accountType,
String authTokenType, String[] features, Bundle options)
@@ -161,7 +159,6 @@ public abstract class AbstractAccountAuthenticator {
+ ", authTokenType " + authTokenType
+ ", features " + (features == null ? "[]" : Arrays.toString(features)));
}
- checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.addAccount(
new AccountAuthenticatorResponse(response),
@@ -183,13 +180,13 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
@Override
public void confirmCredentials(IAccountAuthenticatorResponse response,
Account account, Bundle options) throws RemoteException {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "confirmCredentials: " + account);
}
- checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.confirmCredentials(
new AccountAuthenticatorResponse(response), account, options);
@@ -208,6 +205,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
@Override
public void getAuthTokenLabel(IAccountAuthenticatorResponse response,
String authTokenType)
@@ -215,7 +213,6 @@ public abstract class AbstractAccountAuthenticator {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthTokenLabel: authTokenType " + authTokenType);
}
- checkBinderPermission();
try {
Bundle result = new Bundle();
result.putString(AccountManager.KEY_AUTH_TOKEN_LABEL,
@@ -233,6 +230,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
@Override
public void getAuthToken(IAccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle loginOptions)
@@ -241,7 +239,6 @@ public abstract class AbstractAccountAuthenticator {
Log.v(TAG, "getAuthToken: " + account
+ ", authTokenType " + authTokenType);
}
- checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.getAuthToken(
new AccountAuthenticatorResponse(response), account,
@@ -261,6 +258,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
@Override
public void updateCredentials(IAccountAuthenticatorResponse response, Account account,
String authTokenType, Bundle loginOptions) throws RemoteException {
@@ -268,7 +266,6 @@ public abstract class AbstractAccountAuthenticator {
Log.v(TAG, "updateCredentials: " + account
+ ", authTokenType " + authTokenType);
}
- checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.updateCredentials(
new AccountAuthenticatorResponse(response), account,
@@ -369,6 +366,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
@Override
public void startAddAccountSession(IAccountAuthenticatorResponse response,
String accountType, String authTokenType, String[] features, Bundle options)
@@ -379,7 +377,6 @@ public abstract class AbstractAccountAuthenticator {
+ ", authTokenType " + authTokenType
+ ", features " + (features == null ? "[]" : Arrays.toString(features)));
}
- checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.startAddAccountSession(
new AccountAuthenticatorResponse(response), accountType, authTokenType,
@@ -399,6 +396,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
@Override
public void startUpdateCredentialsSession(
IAccountAuthenticatorResponse response,
@@ -411,7 +409,6 @@ public abstract class AbstractAccountAuthenticator {
+ ", authTokenType "
+ authTokenType);
}
- checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this
.startUpdateCredentialsSession(
@@ -438,6 +435,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
@Override
public void finishSession(
IAccountAuthenticatorResponse response,
@@ -446,7 +444,6 @@ public abstract class AbstractAccountAuthenticator {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "finishSession: accountType " + accountType);
}
- checkBinderPermission();
try {
final Bundle result = AbstractAccountAuthenticator.this.finishSession(
new AccountAuthenticatorResponse(response), accountType, sessionBundle);
@@ -510,14 +507,6 @@ public abstract class AbstractAccountAuthenticator {
}
}
- private void checkBinderPermission() {
- final int uid = Binder.getCallingUid();
- final String perm = Manifest.permission.ACCOUNT_MANAGER;
- if (mContext.checkCallingOrSelfPermission(perm) != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("caller uid " + uid + " lacks " + perm);
- }
- }
-
private Transport mTransport = new Transport();
/**
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
index 0575c07592b6..c74b9d044f3d 100644
--- a/core/java/android/accounts/IAccountAuthenticator.aidl
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -28,6 +28,7 @@ oneway interface IAccountAuthenticator {
/**
* prompts the user for account information and adds the result to the IAccountManager
*/
+ @EnforcePermission("ACCOUNT_MANAGER")
@UnsupportedAppUsage
void addAccount(in IAccountAuthenticatorResponse response, String accountType,
String authTokenType, in String[] requiredFeatures, in Bundle options);
@@ -35,6 +36,7 @@ oneway interface IAccountAuthenticator {
/**
* prompts the user for the credentials of the account
*/
+ @EnforcePermission("ACCOUNT_MANAGER")
@UnsupportedAppUsage
void confirmCredentials(in IAccountAuthenticatorResponse response, in Account account,
in Bundle options);
@@ -42,6 +44,7 @@ oneway interface IAccountAuthenticator {
/**
* gets the password by either prompting the user or querying the IAccountManager
*/
+ @EnforcePermission("ACCOUNT_MANAGER")
@UnsupportedAppUsage
void getAuthToken(in IAccountAuthenticatorResponse response, in Account account,
String authTokenType, in Bundle options);
@@ -49,12 +52,14 @@ oneway interface IAccountAuthenticator {
/**
* Gets the user-visible label of the given authtoken type.
*/
+ @EnforcePermission("ACCOUNT_MANAGER")
@UnsupportedAppUsage
void getAuthTokenLabel(in IAccountAuthenticatorResponse response, String authTokenType);
/**
* prompts the user for a new password and writes it to the IAccountManager
*/
+ @EnforcePermission("ACCOUNT_MANAGER")
@UnsupportedAppUsage
void updateCredentials(in IAccountAuthenticatorResponse response, in Account account,
String authTokenType, in Bundle options);
@@ -101,12 +106,14 @@ oneway interface IAccountAuthenticator {
* Starts the add account session by prompting the user for account information
* and return a Bundle containing data to finish the session later.
*/
+ @EnforcePermission("ACCOUNT_MANAGER")
void startAddAccountSession(in IAccountAuthenticatorResponse response, String accountType,
String authTokenType, in String[] requiredFeatures, in Bundle options);
/**
* Prompts the user for a new password but does not write it to the IAccountManager.
*/
+ @EnforcePermission("ACCOUNT_MANAGER")
void startUpdateCredentialsSession(in IAccountAuthenticatorResponse response, in Account account,
String authTokenType, in Bundle options);
@@ -115,6 +122,7 @@ oneway interface IAccountAuthenticator {
* startUpdateCredentialsSession(...) by adding account to or updating local credentials
* in the IAccountManager.
*/
+ @EnforcePermission("ACCOUNT_MANAGER")
void finishSession(in IAccountAuthenticatorResponse response, String accountType,
in Bundle sessionBundle);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2a83cbddd3dc..b383d7daafd0 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -374,6 +374,7 @@ public final class ActivityThread extends ClientTransactionHandler
int mCurDefaultDisplayDpi;
@UnsupportedAppUsage
boolean mDensityCompatMode;
+ private CompatibilityInfo mCompatibilityInfo;
@UnsupportedAppUsage(trackingBug = 176961850, maxTargetSdk = Build.VERSION_CODES.R,
publicAlternatives = "Use {@code Context#getResources()#getConfiguration()} instead.")
Configuration mConfiguration;
@@ -612,7 +613,7 @@ public final class ActivityThread extends ClientTransactionHandler
}
public ActivityClientRecord(IBinder token, Intent intent, int ident,
- ActivityInfo info, Configuration overrideConfig, CompatibilityInfo compatInfo,
+ ActivityInfo info, Configuration overrideConfig,
String referrer, IVoiceInteractor voiceInteractor, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
@@ -627,7 +628,6 @@ public final class ActivityThread extends ClientTransactionHandler
this.referrer = referrer;
this.voiceInteractor = voiceInteractor;
this.activityInfo = info;
- this.compatInfo = compatInfo;
this.state = state;
this.persistentState = persistentState;
this.pendingResults = pendingResults;
@@ -635,8 +635,7 @@ public final class ActivityThread extends ClientTransactionHandler
this.isForward = isForward;
this.profilerInfo = profilerInfo;
this.overrideConfig = overrideConfig;
- this.packageInfo = client.getPackageInfoNoCheck(activityInfo.applicationInfo,
- compatInfo);
+ this.packageInfo = client.getPackageInfoNoCheck(activityInfo.applicationInfo);
mActivityOptions = activityOptions;
mLaunchedFromBubble = launchedFromBubble;
mInitialTaskFragmentToken = initialTaskFragmentToken;
@@ -804,7 +803,6 @@ public final class ActivityThread extends ClientTransactionHandler
static final class CreateBackupAgentData {
ApplicationInfo appInfo;
- CompatibilityInfo compatInfo;
int backupMode;
int userId;
int operationType;
@@ -1038,15 +1036,13 @@ public final class ActivityThread extends ClientTransactionHandler
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
sync, false, mAppThread.asBinder(), sendingUser);
r.info = info;
- r.compatInfo = compatInfo;
sendMessage(H.RECEIVER, r);
}
public final void scheduleCreateBackupAgent(ApplicationInfo app,
- CompatibilityInfo compatInfo, int backupMode, int userId, int operationType) {
+ int backupMode, int userId, int operationType) {
CreateBackupAgentData d = new CreateBackupAgentData();
d.appInfo = app;
- d.compatInfo = compatInfo;
d.backupMode = backupMode;
d.userId = userId;
d.operationType = operationType;
@@ -1054,11 +1050,9 @@ public final class ActivityThread extends ClientTransactionHandler
sendMessage(H.CREATE_BACKUP_AGENT, d);
}
- public final void scheduleDestroyBackupAgent(ApplicationInfo app,
- CompatibilityInfo compatInfo, int userId) {
+ public final void scheduleDestroyBackupAgent(ApplicationInfo app, int userId) {
CreateBackupAgentData d = new CreateBackupAgentData();
d.appInfo = app;
- d.compatInfo = compatInfo;
d.userId = userId;
sendMessage(H.DESTROY_BACKUP_AGENT, d);
@@ -1070,7 +1064,6 @@ public final class ActivityThread extends ClientTransactionHandler
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
- s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
@@ -2577,16 +2570,16 @@ public final class ActivityThread extends ClientTransactionHandler
registerPackage);
}
- @Override
@UnsupportedAppUsage
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}
- private LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, CompatibilityInfo compatInfo,
- boolean isSdkSandbox) {
- return getPackageInfo(ai, compatInfo, null, false, true, false, isSdkSandbox);
+ @Override
+ public LoadedApk getPackageInfoNoCheck(ApplicationInfo ai) {
+ return getPackageInfo(ai, mCompatibilityInfo, null /* baseLoader */,
+ false /* securityViolation */, true /* includeCode */, false /* registerPackage */);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -3538,7 +3531,7 @@ public final class ActivityThread extends ClientTransactionHandler
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
- r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
+ r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo,
Context.CONTEXT_INCLUDE_CODE);
}
@@ -4279,8 +4272,7 @@ public final class ActivityThread extends ClientTransactionHandler
String component = data.intent.getComponent().getClassName();
- LoadedApk packageInfo = getPackageInfoNoCheck(
- data.info.applicationInfo, data.compatInfo);
+ final LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo);
IActivityManager mgr = ActivityManager.getService();
@@ -4366,7 +4358,7 @@ public final class ActivityThread extends ClientTransactionHandler
unscheduleGcIdler();
// instantiate the BackupAgent class named in the manifest
- LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
+ final LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo);
String packageName = packageInfo.mPackageName;
if (packageName == null) {
Slog.d(TAG, "Asked to create backup agent for nonexistent package");
@@ -4439,7 +4431,7 @@ public final class ActivityThread extends ClientTransactionHandler
private void handleDestroyBackupAgent(CreateBackupAgentData data) {
if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
- LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
+ final LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo);
String packageName = packageInfo.mPackageName;
ArrayMap<String, BackupAgent> backupAgents = getBackupAgentsForUser(data.userId);
BackupAgent agent = backupAgents.get(packageName);
@@ -4471,8 +4463,7 @@ public final class ActivityThread extends ClientTransactionHandler
// we are back active so skip it.
unscheduleGcIdler();
- LoadedApk packageInfo = getPackageInfoNoCheck(
- data.info.applicationInfo, data.compatInfo);
+ final LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo);
Service service = null;
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
@@ -5306,6 +5297,7 @@ public final class ActivityThread extends ClientTransactionHandler
}
private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
+ mCompatibilityInfo = data.info;
LoadedApk apk = peekPackageInfo(data.pkg, false);
if (apk != null) {
apk.setCompatibilityInfo(data.info);
@@ -6486,6 +6478,7 @@ public final class ActivityThread extends ClientTransactionHandler
mConfigurationController.setConfiguration(data.config);
mConfigurationController.setCompatConfiguration(data.config);
mConfiguration = mConfigurationController.getConfiguration();
+ mCompatibilityInfo = data.compatInfo;
mProfiler = new Profiler();
String agent = null;
@@ -6569,7 +6562,9 @@ public final class ActivityThread extends ClientTransactionHandler
}
final boolean isSdkSandbox = data.sdkSandboxClientAppPackage != null;
- data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo, isSdkSandbox);
+ data.info = getPackageInfo(data.appInfo, mCompatibilityInfo, null /* baseLoader */,
+ false /* securityViolation */, true /* includeCode */,
+ false /* registerPackage */, isSdkSandbox);
if (isSdkSandbox) {
data.info.setSdkSandboxStorage(data.sdkSandboxClientAppVolumeUuid,
data.sdkSandboxClientAppPackage);
@@ -6844,7 +6839,7 @@ public final class ActivityThread extends ClientTransactionHandler
private void handleInstrumentWithoutRestart(AppBindData data) {
try {
data.compatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
- data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
+ data.info = getPackageInfoNoCheck(data.appInfo);
mInstrumentingWithoutRestart = true;
final InstrumentationInfo ii = prepareInstrumentation(data);
final ContextImpl appContext =
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index 65e6ab7a2137..389da2d094d5 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -23,7 +23,6 @@ import android.app.servertransaction.PendingTransactionActions;
import android.app.servertransaction.TransactionExecutor;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
-import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.IBinder;
import android.util.MergedConfiguration;
@@ -180,8 +179,7 @@ public abstract class ClientTransactionHandler {
PendingTransactionActions pendingActions, ActivityOptions activityOptions);
/** Get package info. */
- public abstract LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
- CompatibilityInfo compatInfo);
+ public abstract LoadedApk getPackageInfoNoCheck(ApplicationInfo ai);
/** Deliver app configuration change notification. */
public abstract void handleConfigurationChanged(Configuration config);
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 75ad363a2668..843b6846d053 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -102,10 +102,9 @@ oneway interface IApplicationThread {
void scheduleLowMemory();
void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType);
void setSchedulingGroup(int group);
- void scheduleCreateBackupAgent(in ApplicationInfo app, in CompatibilityInfo compatInfo,
+ void scheduleCreateBackupAgent(in ApplicationInfo app,
int backupMode, int userId, int operationType);
- void scheduleDestroyBackupAgent(in ApplicationInfo app,
- in CompatibilityInfo compatInfo, int userId);
+ void scheduleDestroyBackupAgent(in ApplicationInfo app, int userId);
void scheduleOnNewActivityOptions(IBinder token, in Bundle options);
void scheduleSuicide();
void dispatchPackageBroadcast(int cmd, in String[] packages);
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
index 1769993e0e07..f97415ca20c8 100644
--- a/core/java/android/app/NotificationChannelGroup.java
+++ b/core/java/android/app/NotificationChannelGroup.java
@@ -20,7 +20,6 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Intent;
-import android.content.pm.ParceledListSlice;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -67,7 +66,7 @@ public final class NotificationChannelGroup implements Parcelable {
private CharSequence mName;
private String mDescription;
private boolean mBlocked;
- private ParceledListSlice<NotificationChannel> mChannels;
+ private List<NotificationChannel> mChannels = new ArrayList<>();
// Bitwise representation of fields that have been changed by the user
private int mUserLockedFields;
@@ -101,8 +100,7 @@ public final class NotificationChannelGroup implements Parcelable {
} else {
mDescription = null;
}
- mChannels = in.readParcelable(
- NotificationChannelGroup.class.getClassLoader(), ParceledListSlice.class);
+ in.readParcelableList(mChannels, NotificationChannel.class.getClassLoader(), android.app.NotificationChannel.class);
mBlocked = in.readBoolean();
mUserLockedFields = in.readInt();
}
@@ -129,7 +127,7 @@ public final class NotificationChannelGroup implements Parcelable {
} else {
dest.writeByte((byte) 0);
}
- dest.writeParcelable(mChannels, flags);
+ dest.writeParcelableList(mChannels, flags);
dest.writeBoolean(mBlocked);
dest.writeInt(mUserLockedFields);
}
@@ -159,7 +157,7 @@ public final class NotificationChannelGroup implements Parcelable {
* Returns the list of channels that belong to this group
*/
public List<NotificationChannel> getChannels() {
- return mChannels == null ? new ArrayList<>() : mChannels.getList();
+ return mChannels;
}
/**
@@ -193,8 +191,15 @@ public final class NotificationChannelGroup implements Parcelable {
/**
* @hide
*/
+ public void addChannel(NotificationChannel channel) {
+ mChannels.add(channel);
+ }
+
+ /**
+ * @hide
+ */
public void setChannels(List<NotificationChannel> channels) {
- mChannels = new ParceledListSlice<>(channels);
+ mChannels = channels;
}
/**
@@ -329,7 +334,7 @@ public final class NotificationChannelGroup implements Parcelable {
proto.write(NotificationChannelGroupProto.NAME, mName.toString());
proto.write(NotificationChannelGroupProto.DESCRIPTION, mDescription);
proto.write(NotificationChannelGroupProto.IS_BLOCKED, mBlocked);
- for (NotificationChannel channel : mChannels.getList()) {
+ for (NotificationChannel channel : mChannels) {
channel.dumpDebug(proto, NotificationChannelGroupProto.CHANNELS);
}
proto.end(token);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f98ad4e07da8..68665107dfde 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -379,8 +379,8 @@ public class DevicePolicyManager {
* Only one {@link ComponentName} in the entire system should be enabled, and the rest of the
* components are not started by this intent.
*
- * @deprecated Starting from Android T, the system no longer launches an intent with this action
- * when user provisioning completes.
+ * @deprecated Starting from Android 13, the system no longer launches an intent with this
+ * action when user provisioning completes.
* @hide
*/
@Deprecated
@@ -14626,7 +14626,8 @@ public class DevicePolicyManager {
/**
* Called by a device owner or a profile owner to disable user control over apps. User will not
* be able to clear app data or force-stop packages. When called by a device owner, applies to
- * all users on the device.
+ * all users on the device. Starting from Android 13, packages with user control disabled are
+ * exempted from being put in the "restricted" App Standby Bucket.
*
* @param admin which {@link DeviceAdminReceiver} this request is associated with
* @param packages The package names for the apps.
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 076dbef9ebc4..03d6e27d6a8d 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -30,7 +30,6 @@ import android.app.ResultInfo;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.BaseBundle;
import android.os.Bundle;
@@ -58,7 +57,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
private ActivityInfo mInfo;
private Configuration mCurConfig;
private Configuration mOverrideConfig;
- private CompatibilityInfo mCompatInfo;
private String mReferrer;
private IVoiceInteractor mVoiceInteractor;
private int mProcState;
@@ -94,7 +92,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
- mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
+ mOverrideConfig, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
mTaskFragmentToken);
@@ -115,7 +113,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
/** Obtain an instance initialized with provided params. */
public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info,
- Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo,
+ Configuration curConfig, Configuration overrideConfig,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
@@ -126,7 +124,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
if (instance == null) {
instance = new LaunchActivityItem();
}
- setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
+ setValues(instance, intent, ident, info, curConfig, overrideConfig, referrer,
voiceInteractor, procState, state, persistentState, pendingResults,
pendingNewIntents, activityOptions, isForward, profilerInfo, assistToken,
activityClientController, shareableActivityToken,
@@ -137,7 +135,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
@Override
public void recycle() {
- setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null,
+ setValues(this, null, 0, null, null, null, null, null, 0, null, null, null, null,
null, false, null, null, null, null, false, null);
ObjectPool.recycle(this);
}
@@ -153,7 +151,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
dest.writeTypedObject(mInfo, flags);
dest.writeTypedObject(mCurConfig, flags);
dest.writeTypedObject(mOverrideConfig, flags);
- dest.writeTypedObject(mCompatInfo, flags);
dest.writeString(mReferrer);
dest.writeStrongInterface(mVoiceInteractor);
dest.writeInt(mProcState);
@@ -175,8 +172,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
private LaunchActivityItem(Parcel in) {
setValues(this, in.readTypedObject(Intent.CREATOR), in.readInt(),
in.readTypedObject(ActivityInfo.CREATOR), in.readTypedObject(Configuration.CREATOR),
- in.readTypedObject(Configuration.CREATOR),
- in.readTypedObject(CompatibilityInfo.CREATOR), in.readString(),
+ in.readTypedObject(Configuration.CREATOR), in.readString(),
IVoiceInteractor.Stub.asInterface(in.readStrongBinder()), in.readInt(),
in.readBundle(getClass().getClassLoader()),
in.readPersistableBundle(getClass().getClassLoader()),
@@ -216,7 +212,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
return intentsEqual && mIdent == other.mIdent
&& activityInfoEqual(other.mInfo) && Objects.equals(mCurConfig, other.mCurConfig)
&& Objects.equals(mOverrideConfig, other.mOverrideConfig)
- && Objects.equals(mCompatInfo, other.mCompatInfo)
&& Objects.equals(mReferrer, other.mReferrer)
&& mProcState == other.mProcState && areBundlesEqualRoughly(mState, other.mState)
&& areBundlesEqualRoughly(mPersistentState, other.mPersistentState)
@@ -237,7 +232,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
result = 31 * result + mIdent;
result = 31 * result + Objects.hashCode(mCurConfig);
result = 31 * result + Objects.hashCode(mOverrideConfig);
- result = 31 * result + Objects.hashCode(mCompatInfo);
result = 31 * result + Objects.hashCode(mReferrer);
result = 31 * result + Objects.hashCode(mProcState);
result = 31 * result + getRoughBundleHashCode(mState);
@@ -292,7 +286,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
// Using the same method to set and clear values to make sure we don't forget anything
private static void setValues(LaunchActivityItem instance, Intent intent, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
- CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
+ String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo,
@@ -303,7 +297,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
instance.mInfo = info;
instance.mCurConfig = curConfig;
instance.mOverrideConfig = overrideConfig;
- instance.mCompatInfo = compatInfo;
instance.mReferrer = referrer;
instance.mVoiceInteractor = voiceInteractor;
instance.mProcState = procState;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 756c468e982a..e13f60c3265b 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -941,21 +941,27 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
/**
* The names of all installed split APKs, ordered lexicographically.
+ * May be null if no splits are installed.
*/
+ @Nullable
public String[] splitNames;
/**
- * Full paths to zero or more split APKs, indexed by the same order as {@link #splitNames}.
+ * Full paths to split APKs, indexed by the same order as {@link #splitNames}.
+ * May be null if no splits are installed.
*/
+ @Nullable
public String[] splitSourceDirs;
/**
* Full path to the publicly available parts of {@link #splitSourceDirs},
* including resources and manifest. This may be different from
* {@link #splitSourceDirs} if an application is forward locked.
+ * May be null if no splits are installed.
*
* @see #splitSourceDirs
*/
+ @Nullable
public String[] splitPublicSourceDirs;
/**
diff --git a/core/java/android/content/pm/VerifierDeviceIdentity.java b/core/java/android/content/pm/VerifierDeviceIdentity.java
index 3ce0b65e9f95..7e82edf8ec8f 100644
--- a/core/java/android/content/pm/VerifierDeviceIdentity.java
+++ b/core/java/android/content/pm/VerifierDeviceIdentity.java
@@ -89,8 +89,8 @@ public class VerifierDeviceIdentity implements Parcelable {
* @return verifier device identity based on the input from the provided
* random number generator
*/
- @VisibleForTesting
- static VerifierDeviceIdentity generate(Random rng) {
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ public static VerifierDeviceIdentity generate(Random rng) {
long identity = rng.nextLong();
return new VerifierDeviceIdentity(identity);
}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 8db298ff8a85..861a8502c44d 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1325,8 +1325,11 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* flashlight brightness level via
* {@link android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel }.
* If this value is equal to 1, flashlight brightness control is not supported.
- * The value for this key will be null for devices with no flash unit.
- * This level must be set to a safe value to prevent any burn out issues.</p>
+ * The value for this key will be null for devices with no flash unit.</p>
+ * <p>The maximum value is guaranteed to be safe to use for an indefinite duration in
+ * terms of device flashlight lifespan, but may be too bright for comfort for many
+ * use cases. Use the default torch brightness value to avoid problems with an
+ * over-bright flashlight.</p>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
*/
@PublicKey
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index e5b9cdb74d3b..26415d30e323 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -920,15 +920,15 @@ public final class MandatoryStreamCombination {
// UH res YUV / RAW / JPEG + YUV preview size stream
new StreamCombinationTemplate(new StreamTemplate [] {
new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.FULL_RES),
- new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW)},
+ new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW)},
"No-viewfinder Ultra high resolution YUV image capture with image analysis"),
new StreamCombinationTemplate(new StreamTemplate [] {
new StreamTemplate(ImageFormat.RAW_SENSOR, SizeThreshold.FULL_RES),
- new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW)},
+ new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW)},
"No-viewfinder Ultra high resolution RAW_SENSOR image capture with image analysis"),
new StreamCombinationTemplate(new StreamTemplate [] {
new StreamTemplate(ImageFormat.JPEG, SizeThreshold.FULL_RES),
- new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW)},
+ new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW)},
"No-viewfinder Ultra high resolution JPEG image capture with image analysis"),
// UH res YUV / RAW / JPEG + PRIV preview + PRIV RECORD stream
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c6fc9ec0ee6b..b108490e54e9 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2894,7 +2894,6 @@ public class InputMethodService extends AbstractInputMethodService {
// Back callback is typically unregistered in {@link #hideWindow()}, but it's possible
// for {@link #doFinishInput()} to be called without {@link #hideWindow()} so we also
// unregister here.
- // TODO(b/232341407): Add CTS to verify back behavior after screen on / off.
unregisterCompatOnBackInvokedCallback();
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 91d6a9bf69cb..40f7533a2800 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -117,6 +117,7 @@ interface INetworkManagementService
/**
* Shuts down the service
*/
+ @EnforcePermission("SHUTDOWN")
void shutdown();
/**
@@ -277,6 +278,7 @@ interface INetworkManagementService
*/
void setUidOnMeteredNetworkDenylist(int uid, boolean enable);
void setUidOnMeteredNetworkAllowlist(int uid, boolean enable);
+ @EnforcePermission("NETWORK_SETTINGS")
boolean setDataSaverModeEnabled(boolean enable);
void setUidCleartextNetworkPolicy(int uid, int policy);
@@ -308,5 +310,6 @@ interface INetworkManagementService
void removeInterfaceFromLocalNetwork(String iface);
int removeRoutesFromLocalNetwork(in List<RouteInfo> routes);
+ @EnforcePermission("OBSERVE_NETWORK_POLICY")
boolean isNetworkRestricted(int uid);
}
diff --git a/core/java/android/os/OutcomeReceiver.java b/core/java/android/os/OutcomeReceiver.java
index 01b276411446..4b9552e238eb 100644
--- a/core/java/android/os/OutcomeReceiver.java
+++ b/core/java/android/os/OutcomeReceiver.java
@@ -31,7 +31,7 @@ public interface OutcomeReceiver<R, E extends Throwable> {
* Called when the asynchronous operation succeeds and delivers a result value.
* @param result The value delivered by the asynchronous operation.
*/
- void onResult(@NonNull R result);
+ void onResult(R result);
/**
* Called when the asynchronous operation fails. The mode of failure is indicated by the
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 73bbc4030c78..6fc2811572af 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10987,6 +10987,14 @@ public final class Settings {
public static final String ADAPTIVE_CHARGING_ENABLED = "adaptive_charging_enabled";
/**
+ * Whether battery saver is currently set to different schedule mode.
+ *
+ * @hide
+ */
+ public static final String EXTRA_AUTOMATIC_POWER_SAVE_MODE =
+ "extra_automatic_power_save_mode";
+
+ /**
* These entries are considered common between the personal and the managed profile,
* since the managed profile doesn't get to change them.
*/
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 02176b0c123e..fb52ed2b20fa 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -261,6 +261,10 @@ public abstract class NotificationListenerService extends Service {
/**
* Notification was canceled when entering lockdown mode, which turns off
* Smart Lock, fingerprint unlocking, and notifications on the lock screen.
+ * All the listeners shall ensure the canceled notifications are indeed removed
+ * on their end to prevent data leaking.
+ * When the user exits the lockdown mode, the removed notifications (due to lockdown)
+ * will be restored via NotificationListeners#notifyPostedLocked()
*/
public static final int REASON_LOCKDOWN = 23;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index f1ce9c3aa04b..eae951f7b73d 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -107,6 +107,15 @@ public class FeatureFlagUtils {
*/
public static final String SETTINGS_ENABLE_CLEAR_CALLING = "settings_enable_clear_calling";
+
+ /** Flag to enable / disable the Simple Cursor accessibility feature in
+ * Settings.
+ * @hide
+ */
+ public static final String SETTINGS_ACCESSIBILITY_SIMPLE_CURSOR =
+ "settings_accessibility_simple_cursor";
+
+
private static final Map<String, String> DEFAULT_FLAGS;
static {
@@ -138,6 +147,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SETTINGS_AUTO_TEXT_WRAPPING, "false");
DEFAULT_FLAGS.put(SETTINGS_GUEST_MODE_UX_CHANGES, "true");
DEFAULT_FLAGS.put(SETTINGS_ENABLE_CLEAR_CALLING, "false");
+ DEFAULT_FLAGS.put(SETTINGS_ACCESSIBILITY_SIMPLE_CURSOR, "false");
}
private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index f1fd324b4229..af432228183c 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -44,7 +44,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import java.util.function.Supplier;
/**
* A singleton that connects with a remote NTP server as its trusted time source. This class
@@ -251,80 +250,102 @@ public abstract class NtpTrustedTime implements TrustedTime {
}
}
+ /** Forces a refresh using the default network. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean forceRefresh() {
synchronized (this) {
- NtpConfig ntpConfig = getNtpConfig();
- if (ntpConfig == null) {
- // missing server config, so no NTP time available
- if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
- return false;
- }
-
- Network network = getNetwork();
+ Network network = getDefaultNetwork();
if (network == null) {
if (LOGD) Log.d(TAG, "forceRefresh: no network available");
return false;
}
- if (LOGD) {
- Log.d(TAG, "forceRefresh: NTP request network=" + network
- + " ntpConfig=" + ntpConfig);
- }
+ return forceRefreshLocked(network);
+ }
+ }
- List<URI> unorderedServerUris = ntpConfig.getServerUris();
-
- // Android supports multiple NTP server URIs for situations where servers might be
- // unreachable for some devices due to network topology, e.g. we understand that devices
- // travelling to China often have difficulty accessing "time.android.com". Android
- // partners may want to configure alternative URIs for devices sold globally, or those
- // that are likely to travel to part of the world without access to the full internet.
- //
- // The server URI list is expected to contain one element in the general case, with two
- // or three as the anticipated maximum. The list is never empty. Server URIs are
- // considered to be in a rough priority order of servers to try initially (no
- // randomization), but besides that there is assumed to be no preference.
- //
- // The server selection algorithm below tries to stick with a successfully accessed NTP
- // server's URI where possible:
- //
- // The algorithm based on the assumption that a cluster of NTP servers sharing the same
- // host name, particularly commercially run ones, are likely to agree more closely on
- // the time than servers from different URIs, so it's best to be sticky. Switching
- // between URIs could result in flip-flopping between reference clocks or involve
- // talking to server clusters with different approaches to leap second handling.
- //
- // Stickiness may also be useful if some server URIs early in the list are permanently
- // black-holing requests, or if the responses are not routed back. In those cases it's
- // best not to try those URIs more than we have to, as might happen if the algorithm
- // always started at the beginning of the list.
- //
- // Generally, we have to assume that any of the configured servers are going to be "good
- // enough" as an external reference clock when reachable, so the stickiness is a very
- // lightly applied bias. There's no tracking of failure rates or back-off on a per-URI
- // basis; higher level code is expected to handle rate limiting of NTP requests in the
- // event of failure to contact any server.
-
- List<URI> orderedServerUris = new ArrayList<>();
- for (URI serverUri : unorderedServerUris) {
- if (serverUri.equals(mLastSuccessfulNtpServerUri)) {
- orderedServerUris.add(0, serverUri);
- } else {
- orderedServerUris.add(serverUri);
- }
+ /** Forces a refresh using the specified network. */
+ public boolean forceRefresh(@NonNull Network network) {
+ Objects.requireNonNull(network);
+
+ synchronized (this) {
+ return forceRefreshLocked(network);
+ }
+ }
+
+ @GuardedBy("this")
+ private boolean forceRefreshLocked(@NonNull Network network) {
+ Objects.requireNonNull(network);
+
+ if (!isNetworkConnected(network)) {
+ if (LOGD) Log.d(TAG, "forceRefreshLocked: network=" + network + " is not connected");
+ return false;
+ }
+
+ NtpConfig ntpConfig = getNtpConfig();
+ if (ntpConfig == null) {
+ // missing server config, so no NTP time available
+ if (LOGD) Log.d(TAG, "forceRefreshLocked: invalid server config");
+ return false;
+ }
+
+ if (LOGD) {
+ Log.d(TAG, "forceRefreshLocked: NTP request network=" + network
+ + " ntpConfig=" + ntpConfig);
+ }
+
+ List<URI> unorderedServerUris = ntpConfig.getServerUris();
+
+ // Android supports multiple NTP server URIs for situations where servers might be
+ // unreachable for some devices due to network topology, e.g. we understand that devices
+ // travelling to China often have difficulty accessing "time.android.com". Android
+ // partners may want to configure alternative URIs for devices sold globally, or those
+ // that are likely to travel to part of the world without access to the full internet.
+ //
+ // The server URI list is expected to contain one element in the general case, with two
+ // or three as the anticipated maximum. The list is never empty. Server URIs are
+ // considered to be in a rough priority order of servers to try initially (no
+ // randomization), but besides that there is assumed to be no preference.
+ //
+ // The server selection algorithm below tries to stick with a successfully accessed NTP
+ // server's URI where possible:
+ //
+ // The algorithm based on the assumption that a cluster of NTP servers sharing the same
+ // host name, particularly commercially run ones, are likely to agree more closely on
+ // the time than servers from different URIs, so it's best to be sticky. Switching
+ // between URIs could result in flip-flopping between reference clocks or involve
+ // talking to server clusters with different approaches to leap second handling.
+ //
+ // Stickiness may also be useful if some server URIs early in the list are permanently
+ // black-holing requests, or if the responses are not routed back. In those cases it's
+ // best not to try those URIs more than we have to, as might happen if the algorithm
+ // always started at the beginning of the list.
+ //
+ // Generally, we have to assume that any of the configured servers are going to be "good
+ // enough" as an external reference clock when reachable, so the stickiness is a very
+ // lightly applied bias. There's no tracking of failure rates or back-off on a per-URI
+ // basis; higher level code is expected to handle rate limiting of NTP requests in the
+ // event of failure to contact any server.
+
+ List<URI> orderedServerUris = new ArrayList<>();
+ for (URI serverUri : unorderedServerUris) {
+ if (serverUri.equals(mLastSuccessfulNtpServerUri)) {
+ orderedServerUris.add(0, serverUri);
+ } else {
+ orderedServerUris.add(serverUri);
}
+ }
- for (URI serverUri : orderedServerUris) {
- TimeResult timeResult = queryNtpServer(network, serverUri, ntpConfig.getTimeout());
- // Only overwrite previous state if the request was successful.
- if (timeResult != null) {
- mLastSuccessfulNtpServerUri = serverUri;
- mTimeResult = timeResult;
- return true;
- }
+ for (URI serverUri : orderedServerUris) {
+ TimeResult timeResult = queryNtpServer(network, serverUri, ntpConfig.getTimeout());
+ // Only overwrite previous state if the request was successful.
+ if (timeResult != null) {
+ mLastSuccessfulNtpServerUri = serverUri;
+ mTimeResult = timeResult;
+ return true;
}
- return false;
}
+ return false;
}
@GuardedBy("this")
@@ -346,14 +367,23 @@ public abstract class NtpTrustedTime implements TrustedTime {
public abstract NtpConfig getNtpConfigInternal();
/**
- * Returns the {@link Network} to use during an NTP query. This method can return {@code null}
- * if there is no connectivity
+ * Returns the default {@link Network} to use during an NTP query when no network is specified.
+ * This method can return {@code null} if the device hasn't fully initialized or there is no
+ * active network.
*
* <p>This method has been made public for easy replacement during tests.
*/
@VisibleForTesting
@Nullable
- public abstract Network getNetwork();
+ public abstract Network getDefaultNetwork();
+
+ /**
+ * Returns {@code true} if there is likely to be connectivity on the supplied network.
+ *
+ * <p>This method has been made public for easy replacement during tests.
+ */
+ @VisibleForTesting
+ public abstract boolean isNetworkConnected(@NonNull Network network);
/**
* Queries the specified NTP server. This is a blocking call. Returns {@code null} if the query
@@ -565,25 +595,8 @@ public abstract class NtpTrustedTime implements TrustedTime {
*/
private static final class NtpTrustedTimeImpl extends NtpTrustedTime {
- /**
- * A supplier that returns the ConnectivityManager. The Supplier can return null if
- * ConnectivityService isn't running yet.
- */
- private final Supplier<ConnectivityManager> mConnectivityManagerSupplier =
- new Supplier<>() {
- private ConnectivityManager mConnectivityManager;
-
- @Nullable
- @Override
- public synchronized ConnectivityManager get() {
- // We can't do this at initialization time: ConnectivityService might not be running
- // yet.
- if (mConnectivityManager == null) {
- mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
- }
- return mConnectivityManager;
- }
- };
+ @GuardedBy("this")
+ private ConnectivityManager mConnectivityManager;
@NonNull
private final Context mContext;
@@ -629,13 +642,20 @@ public abstract class NtpTrustedTime implements TrustedTime {
}
@Override
- public Network getNetwork() {
- ConnectivityManager connectivityManager = mConnectivityManagerSupplier.get();
+ public Network getDefaultNetwork() {
+ ConnectivityManager connectivityManager = getConnectivityManager();
if (connectivityManager == null) {
- if (LOGD) Log.d(TAG, "getNetwork: no ConnectivityManager");
return null;
}
- final Network network = connectivityManager.getActiveNetwork();
+ return connectivityManager.getActiveNetwork();
+ }
+
+ @Override
+ public boolean isNetworkConnected(@NonNull Network network) {
+ ConnectivityManager connectivityManager = getConnectivityManager();
+ if (connectivityManager == null) {
+ return false;
+ }
final NetworkInfo ni = connectivityManager.getNetworkInfo(network);
// This connectivity check is to avoid performing a DNS lookup for the time server on a
@@ -649,9 +669,19 @@ public abstract class NtpTrustedTime implements TrustedTime {
// addresses are actually reachable.
if (ni == null || !ni.isConnected()) {
if (LOGD) Log.d(TAG, "getNetwork: no connectivity");
- return null;
+ return false;
+ }
+ return true;
+ }
+
+ private synchronized ConnectivityManager getConnectivityManager() {
+ if (mConnectivityManager == null) {
+ mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+ }
+ if (mConnectivityManager == null) {
+ if (LOGD) Log.d(TAG, "getConnectivityManager: no ConnectivityManager");
}
- return network;
+ return mConnectivityManager;
}
@Override
diff --git a/core/java/android/util/SafetyProtectionUtils.java b/core/java/android/util/SafetyProtectionUtils.java
new file mode 100644
index 000000000000..af985c573063
--- /dev/null
+++ b/core/java/android/util/SafetyProtectionUtils.java
@@ -0,0 +1,53 @@
+/*
+ * 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.util;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.DeviceConfig;
+
+/**
+ * Util class for whether we should show the safety protection resources.
+ *
+ * @hide
+ */
+public class SafetyProtectionUtils {
+ private static final String SAFETY_PROTECTION_RESOURCES_ENABLED = "safety_protection_enabled";
+
+ /**
+ * Determines whether we should show the safety protection resources.
+ * We show the resources only if
+ * (1) the feature flag safety_protection_enabled is enabled and
+ * (2) the config value config_safetyProtectionEnabled is enabled/true and
+ * (3) the resources exist (currently the resources only exist on GMS devices)
+ *
+ * TODO: make this an API in U
+ *
+ * @hide
+ */
+ public static boolean shouldShowSafetyProtectionResources(Context context) {
+ return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
+ SAFETY_PROTECTION_RESOURCES_ENABLED, false)
+ && context.getResources().getBoolean(
+ Resources.getSystem()
+ .getIdentifier("config_safetyProtectionEnabled",
+ "bool", "android"))
+ && context.getDrawable(android.R.drawable.ic_safety_protection) != null
+ && context.getString(android.R.string.safety_protection_display_text) != null
+ && !context.getString(android.R.string.safety_protection_display_text).isEmpty();
+ }
+}
diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java
index bd468d95858a..c69298192109 100644
--- a/core/java/android/view/AttachedSurfaceControl.java
+++ b/core/java/android/view/AttachedSurfaceControl.java
@@ -17,10 +17,10 @@ package android.view;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.annotation.UiThread;
import android.graphics.Region;
import android.hardware.HardwareBuffer;
+import android.window.SurfaceSyncGroup;
/**
* Provides an interface to the root-Surface of a View Hierarchy or Window. This
@@ -138,4 +138,15 @@ public interface AttachedSurfaceControl {
*/
default void setTouchableRegion(@Nullable Region r) {
}
+
+ /**
+ * Returns a SyncTarget that can be used to sync {@link AttachedSurfaceControl} in a
+ * {@link SurfaceSyncGroup}
+ *
+ * @hide
+ */
+ @Nullable
+ default SurfaceSyncGroup.SyncTarget getSyncTarget() {
+ return null;
+ }
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 536a0ac6403b..70a5eda1d03e 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -47,7 +47,7 @@ import android.util.Log;
import android.view.SurfaceControl.Transaction;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityEmbeddedConnection;
-import android.window.SurfaceSyncer;
+import android.window.SurfaceSyncGroup;
import com.android.internal.view.SurfaceCallbackHelper;
@@ -119,6 +119,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
final int[] mLocation = new int[2];
@UnsupportedAppUsage
+ // Used to ensure the Surface remains valid between SurfaceHolder#lockCanvas and
+ // SurfaceHolder#unlockCanvasAndPost calls. This prevents SurfaceView from destroying or
+ // invalidating the Surface. This means this lock should be acquired when destroying the
+ // BlastBufferQueue.
final ReentrantLock mSurfaceLock = new ReentrantLock();
@UnsupportedAppUsage
final Surface mSurface = new Surface(); // Current surface in use
@@ -206,8 +210,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private int mSurfaceFlags = SurfaceControl.HIDDEN;
- private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
- private final ArraySet<Integer> mSyncIds = new ArraySet<>();
+ private final ArraySet<SurfaceSyncGroup> mSyncGroups = new ArraySet<>();
/**
* Transaction that should be used from the render thread. This transaction is only thread safe
@@ -724,14 +727,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private void releaseSurfaces(boolean releaseSurfacePackage) {
mSurfaceAlpha = 1f;
- mSurface.destroy();
-
- synchronized (mSurfaceControlLock) {
+ try {
+ mSurfaceLock.lock();
+ mSurface.destroy();
if (mBlastBufferQueue != null) {
mBlastBufferQueue.destroy();
mBlastBufferQueue = null;
}
+ } finally {
+ mSurfaceLock.unlock();
+ }
+ synchronized (mSurfaceControlLock) {
final Transaction transaction = new Transaction();
if (mSurfaceControl != null) {
transaction.remove(mSurfaceControl);
@@ -1069,20 +1076,21 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
private void handleSyncNoBuffer(SurfaceHolder.Callback[] callbacks) {
- final int syncId = mSurfaceSyncer.setupSync(this::onDrawFinished);
+ final SurfaceSyncGroup syncGroup = new SurfaceSyncGroup();
+ synchronized (mSyncGroups) {
+ mSyncGroups.add(syncGroup);
+ }
- mSurfaceSyncer.addToSync(syncId, syncBufferCallback -> redrawNeededAsync(callbacks,
+ syncGroup.addToSync(syncBufferCallback -> redrawNeededAsync(callbacks,
() -> {
syncBufferCallback.onBufferReady(null);
- synchronized (mSyncIds) {
- mSyncIds.remove(syncId);
+ onDrawFinished();
+ synchronized (mSyncGroups) {
+ mSyncGroups.remove(syncGroup);
}
}));
- mSurfaceSyncer.markSyncReady(syncId);
- synchronized (mSyncIds) {
- mSyncIds.add(syncId);
- }
+ syncGroup.markSyncReady();
}
private void redrawNeededAsync(SurfaceHolder.Callback[] callbacks,
@@ -1098,9 +1106,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
public void surfaceSyncStarted() {
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
- synchronized (mSyncIds) {
- for (int syncId : mSyncIds) {
- viewRoot.mergeSync(syncId, mSurfaceSyncer);
+ synchronized (mSyncGroups) {
+ for (SurfaceSyncGroup syncGroup : mSyncGroups) {
+ viewRoot.mergeSync(syncGroup);
}
}
}
@@ -1232,16 +1240,21 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
.build();
}
- // Always recreate the IGBP for compatibility. This can be optimized in the future but
- // the behavior change will need to be gated by SDK version.
- if (mBlastBufferQueue != null) {
- mBlastBufferQueue.destroy();
- }
mTransformHint = viewRoot.getBufferTransformHint();
mBlastSurfaceControl.setTransformHint(mTransformHint);
- mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
- mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
+ // Always recreate the IGBP for compatibility. This can be optimized in the future but
+ // the behavior change will need to be gated by SDK version.
+ try {
+ mSurfaceLock.lock();
+ if (mBlastBufferQueue != null) {
+ mBlastBufferQueue.destroy();
+ }
+ mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
+ mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
+ } finally {
+ mSurfaceLock.unlock();
+ }
mBlastBufferQueue.setTransactionHangCallback(ViewRootImpl.sTransactionHangCallback);
}
@@ -1814,7 +1827,14 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
// so the next connect will always work if we end up reusing
// the surface.
if (mSurface.isValid()) {
- mSurface.forceScopedDisconnect();
+ // We need to grab this lock since mSurface.forceScopedDisconnect
+ // will free buffers from the queue.
+ try {
+ mSurfaceLock.lock();
+ mSurface.forceScopedDisconnect();
+ } finally {
+ mSurfaceLock.unlock();
+ }
}
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fbfeac71e655..c1a5a3a25680 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -197,7 +197,7 @@ import android.window.ClientWindowFrames;
import android.window.CompatOnBackInvokedCallback;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
-import android.window.SurfaceSyncer;
+import android.window.SurfaceSyncGroup;
import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.R;
@@ -829,9 +829,8 @@ public final class ViewRootImpl implements ViewParent,
return mHandwritingInitiator;
}
- private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
- private int mSyncId = UNSET_SYNC_ID;
- private SurfaceSyncer.SyncBufferCallback mSyncBufferCallback;
+ private SurfaceSyncGroup mSyncGroup;
+ private SurfaceSyncGroup.SyncBufferCallback mSyncBufferCallback;
private int mNumSyncsInProgress = 0;
private HashSet<ScrollCaptureCallback> mRootScrollCaptureCallbacks;
@@ -3594,8 +3593,8 @@ public final class ViewRootImpl implements ViewParent,
mSyncBufferCallback = null;
mSyncBuffer = false;
if (isInLocalSync()) {
- mSurfaceSyncer.markSyncReady(mSyncId);
- mSyncId = UNSET_SYNC_ID;
+ mSyncGroup.markSyncReady();
+ mSyncGroup = null;
}
}
}
@@ -3607,17 +3606,19 @@ public final class ViewRootImpl implements ViewParent,
}
final int seqId = mSyncSeqId;
- mSyncId = mSurfaceSyncer.setupSync(transaction -> {
+ mSyncGroup = new SurfaceSyncGroup(transaction -> {
// Callback will be invoked on executor thread so post to main thread.
mHandler.postAtFrontOfQueue(() -> {
- mSurfaceChangedTransaction.merge(transaction);
+ if (transaction != null) {
+ mSurfaceChangedTransaction.merge(transaction);
+ }
reportDrawFinished(seqId);
});
});
if (DEBUG_BLAST) {
- Log.d(mTag, "Setup new sync id=" + mSyncId);
+ Log.d(mTag, "Setup new sync id=" + mSyncGroup);
}
- mSurfaceSyncer.addToSync(mSyncId, mSyncTarget);
+ mSyncGroup.addToSync(mSyncTarget);
notifySurfaceSyncStarted();
}
@@ -4255,11 +4256,11 @@ public final class ViewRootImpl implements ViewParent,
return mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled();
}
- void addToSync(SurfaceSyncer.SyncTarget syncable) {
+ void addToSync(SurfaceSyncGroup.SyncTarget syncable) {
if (!isInLocalSync()) {
return;
}
- mSurfaceSyncer.addToSync(mSyncId, syncable);
+ mSyncGroup.addToSync(syncable);
}
/**
@@ -4267,7 +4268,7 @@ public final class ViewRootImpl implements ViewParent,
* within VRI.
*/
public boolean isInLocalSync() {
- return mSyncId != UNSET_SYNC_ID;
+ return mSyncGroup != null;
}
private void addFrameCommitCallbackIfNeeded() {
@@ -4392,7 +4393,7 @@ public final class ViewRootImpl implements ViewParent,
}
if (mSurfaceHolder != null && mSurface.isValid()) {
- final SurfaceSyncer.SyncBufferCallback syncBufferCallback = mSyncBufferCallback;
+ final SurfaceSyncGroup.SyncBufferCallback syncBufferCallback = mSyncBufferCallback;
SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() ->
mHandler.post(() -> syncBufferCallback.onBufferReady(null)));
mSyncBufferCallback = null;
@@ -10929,7 +10930,7 @@ public final class ViewRootImpl implements ViewParent,
}
private void registerCallbacksForSync(boolean syncBuffer,
- final SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
+ final SurfaceSyncGroup.SyncBufferCallback syncBufferCallback) {
if (!isHardwareEnabled()) {
return;
}
@@ -11002,9 +11003,9 @@ public final class ViewRootImpl implements ViewParent,
});
}
- public final SurfaceSyncer.SyncTarget mSyncTarget = new SurfaceSyncer.SyncTarget() {
+ public final SurfaceSyncGroup.SyncTarget mSyncTarget = new SurfaceSyncGroup.SyncTarget() {
@Override
- public void onReadyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
+ public void onReadyToSync(SurfaceSyncGroup.SyncBufferCallback syncBufferCallback) {
readyToSync(syncBufferCallback);
}
@@ -11018,7 +11019,12 @@ public final class ViewRootImpl implements ViewParent,
}
};
- private void readyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
+ @Override
+ public SurfaceSyncGroup.SyncTarget getSyncTarget() {
+ return mSyncTarget;
+ }
+
+ private void readyToSync(SurfaceSyncGroup.SyncBufferCallback syncBufferCallback) {
mNumSyncsInProgress++;
if (!isInLocalSync()) {
// Always sync the buffer if the sync request did not come from VRI.
@@ -11041,10 +11047,10 @@ public final class ViewRootImpl implements ViewParent,
}
}
- void mergeSync(int syncId, SurfaceSyncer otherSyncer) {
+ void mergeSync(SurfaceSyncGroup otherSyncGroup) {
if (!isInLocalSync()) {
return;
}
- mSurfaceSyncer.merge(mSyncId, syncId, otherSyncer);
+ mSyncGroup.merge(otherSyncGroup);
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 70a690c3f264..e56c43e57aa0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -824,16 +824,20 @@ public interface WindowManager extends ViewManager {
* provide consent for their app to allow OEMs to manually provide ActivityEmbedding split
* rule configuration on behalf of the app.
*
- * <p>If {@code true}, the system CAN override the windowing behaviors for the app, such as
+ * <p>If {@code true}, the system can override the windowing behaviors for the app, such as
* showing some activities side-by-side. In this case, it will report that ActivityEmbedding
* APIs are disabled for the app to avoid conflict.
*
- * <p>If {@code false}, the system MUST NOT override the window behavior for the app. It should
+ * <p>If {@code false}, the system can't override the window behavior for the app. It should
* be used if the app wants to provide their own ActivityEmbedding split rules, or if the app
* wants to opt-out of system overrides for any other reason.
*
* <p>Default is {@code false}.
*
+ * <p>The system enforcement will be added in Android 14, but some devices may start following
+ * the requirement before that. The best practice for apps is to always explicitly set this
+ * property in AndroidManifest instead of relying on the default value.
+ *
* <p>Example usage:
* <pre>
* &lt;application&gt;
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 98ef4e7ae6fa..90384b520315 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -64,6 +64,7 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -630,7 +631,11 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
mComponentName = null;
mEvents = null;
if (mDirectServiceInterface != null) {
- mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0);
+ try {
+ mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0);
+ } catch (NoSuchElementException e) {
+ Log.w(TAG, "IContentCaptureDirectManager does not exist");
+ }
}
mDirectServiceInterface = null;
mHandler.removeMessages(MSG_FLUSH);
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index 949237548926..fdff7a30a6e9 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -1099,4 +1099,41 @@ public class EditorInfo implements InputType, Parcelable {
public int describeContents() {
return 0;
}
+
+ /**
+ * Performs a loose equality check, which means there can be false negatives, but if the method
+ * returns {@code true}, then both objects are guaranteed to be equal.
+ * <ul>
+ * <li>{@link #extras} is compared with {@link Bundle#kindofEquals}</li>
+ * <li>{@link #actionLabel}, {@link #hintText}, and {@link #label} are compared with
+ * {@link TextUtils#equals}, which does not account for Spans. </li>
+ * </ul>
+ * @hide
+ */
+ public boolean kindofEquals(@Nullable EditorInfo that) {
+ if (that == null) return false;
+ if (this == that) return true;
+ return inputType == that.inputType
+ && imeOptions == that.imeOptions
+ && internalImeOptions == that.internalImeOptions
+ && actionId == that.actionId
+ && initialSelStart == that.initialSelStart
+ && initialSelEnd == that.initialSelEnd
+ && initialCapsMode == that.initialCapsMode
+ && fieldId == that.fieldId
+ && Objects.equals(autofillId, that.autofillId)
+ && Objects.equals(privateImeOptions, that.privateImeOptions)
+ && Objects.equals(packageName, that.packageName)
+ && Objects.equals(fieldName, that.fieldName)
+ && Objects.equals(hintLocales, that.hintLocales)
+ && Objects.equals(targetInputMethodUser, that.targetInputMethodUser)
+ && Arrays.equals(contentMimeTypes, that.contentMimeTypes)
+ && TextUtils.equals(actionLabel, that.actionLabel)
+ && TextUtils.equals(hintText, that.hintText)
+ && TextUtils.equals(label, that.label)
+ && (extras == that.extras || (extras != null && extras.kindofEquals(that.extras)))
+ && (mInitialSurroundingText == that.mInitialSurroundingText
+ || (mInitialSurroundingText != null
+ && mInitialSurroundingText.isEqualTo(that.mInitialSurroundingText)));
+ }
}
diff --git a/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
index fc1ede094825..d21ceb2ec79e 100644
--- a/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
+++ b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
@@ -90,10 +90,10 @@ final class IInputMethodManagerInvoker {
@AnyThread
@NonNull
List<InputMethodSubtype> getEnabledInputMethodSubtypeList(@Nullable String imiId,
- boolean allowsImplicitlySelectedSubtypes) {
+ boolean allowsImplicitlySelectedSubtypes, @UserIdInt int userId) {
try {
return mTarget.getEnabledInputMethodSubtypeList(imiId,
- allowsImplicitlySelectedSubtypes);
+ allowsImplicitlySelectedSubtypes, userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -101,9 +101,9 @@ final class IInputMethodManagerInvoker {
@AnyThread
@Nullable
- InputMethodSubtype getLastInputMethodSubtype() {
+ InputMethodSubtype getLastInputMethodSubtype(@UserIdInt int userId) {
try {
- return mTarget.getLastInputMethodSubtype();
+ return mTarget.getLastInputMethodSubtype(userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -139,11 +139,13 @@ final class IInputMethodManagerInvoker {
@WindowManager.LayoutParams.Flags int windowFlags, @Nullable EditorInfo editorInfo,
@Nullable IRemoteInputConnection remoteInputConnection,
@Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion, @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
+ int unverifiedTargetSdkVersion, @UserIdInt int userId,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
try {
return mTarget.startInputOrWindowGainedFocus(startInputReason, client, windowToken,
startInputFlags, softInputMode, windowFlags, editorInfo, remoteInputConnection,
- remoteAccessibilityInputConnection, unverifiedTargetSdkVersion, imeDispatcher);
+ remoteAccessibilityInputConnection, unverifiedTargetSdkVersion, userId,
+ imeDispatcher);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -180,9 +182,9 @@ final class IInputMethodManagerInvoker {
@AnyThread
@Nullable
- InputMethodSubtype getCurrentInputMethodSubtype() {
+ InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId) {
try {
- return mTarget.getCurrentInputMethodSubtype();
+ return mTarget.getCurrentInputMethodSubtype(userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 654713be416d..e7abbbcee7ca 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -70,6 +70,7 @@ import android.os.Process;
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
+import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
@@ -284,9 +285,10 @@ public final class InputMethodManager {
private static final String SUBTYPE_MODE_VOICE = "voice";
/**
- * Provide this to {@link IInputMethodManager#startInputOrWindowGainedFocus(
- * int, IInputMethodClient, IBinder, int, int, int, EditorInfo,
- * com.android.internal.inputmethod.IRemoteInputConnection, int)} to receive
+ * Provide this to {@link IInputMethodManagerInvoker#startInputOrWindowGainedFocus(int,
+ * IInputMethodClient, IBinder, int, int, int, EditorInfo,
+ * com.android.internal.inputmethod.IRemoteInputConnection, IRemoteAccessibilityInputConnection,
+ * int, int, ImeOnBackInvokedDispatcher)} to receive
* {@link android.window.OnBackInvokedCallback} registrations from IME.
*/
private final ImeOnBackInvokedDispatcher mImeDispatcher =
@@ -398,6 +400,18 @@ public final class InputMethodManager {
public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // This is a bug id.
/**
+ * If {@code true}, avoid calling the
+ * {@link com.android.server.inputmethod.InputMethodManagerService InputMethodManagerService}
+ * by skipping the call to {@link IInputMethodManager#startInputOrWindowGainedFocus}
+ * when we are switching focus between two non-editable views. This saves the cost of a binder
+ * call into the system server.
+ * <p><b>Note:</b>
+ * The default value is {@code true}.
+ */
+ private static final boolean OPTIMIZE_NONEDITABLE_VIEWS =
+ SystemProperties.getBoolean("debug.imm.optimize_noneditable_views", true);
+
+ /**
* @deprecated Use {@link #mServiceInvoker} instead.
*/
@Deprecated
@@ -646,6 +660,26 @@ public final class InputMethodManager {
private final class DelegateImpl implements
ImeFocusController.InputMethodManagerDelegate {
+ @GuardedBy("mH")
+ @Nullable
+ private ViewFocusParameterInfo mPreviousViewFocusParameters;
+
+ @GuardedBy("mH")
+ private void updatePreviousViewFocusParametersLocked(
+ @Nullable EditorInfo currentEditorInfo,
+ @StartInputFlags int startInputFlags,
+ @StartInputReason int startInputReason,
+ @SoftInputModeFlags int softInputMode,
+ int windowFlags) {
+ mPreviousViewFocusParameters = new ViewFocusParameterInfo(currentEditorInfo,
+ startInputFlags, startInputReason, softInputMode, windowFlags);
+ }
+
+ @GuardedBy("mH")
+ private void clearStateLocked() {
+ mPreviousViewFocusParameters = null;
+ }
+
/**
* Used by {@link ImeFocusController} to start input connection.
*/
@@ -757,7 +791,7 @@ public final class InputMethodManager {
null,
null, null,
mCurRootView.mContext.getApplicationInfo().targetSdkVersion,
- mImeDispatcher);
+ UserHandle.myUserId(), mImeDispatcher);
}
}
@@ -1514,7 +1548,8 @@ public final class InputMethodManager {
boolean allowsImplicitlySelectedSubtypes) {
return mServiceInvoker.getEnabledInputMethodSubtypeList(
imi == null ? null : imi.getId(),
- allowsImplicitlySelectedSubtypes);
+ allowsImplicitlySelectedSubtypes,
+ UserHandle.myUserId());
}
/**
@@ -1691,8 +1726,10 @@ public final class InputMethodManager {
* Reset all of the state associated with a served view being connected
* to an input method
*/
+ @GuardedBy("mH")
private void clearConnectionLocked() {
mCurrentEditorInfo = null;
+ mDelegate.clearStateLocked();
if (mServedInputConnection != null) {
mServedInputConnection.deactivate();
mServedInputConnection = null;
@@ -2295,22 +2332,22 @@ public final class InputMethodManager {
// Okay we are now ready to call into the served view and have it
// do its stuff.
// Life is good: let's hook everything up!
- EditorInfo tba = new EditorInfo();
+ EditorInfo editorInfo = new EditorInfo();
// Note: Use Context#getOpPackageName() rather than Context#getPackageName() so that the
// system can verify the consistency between the uid of this process and package name passed
// from here. See comment of Context#getOpPackageName() for details.
- tba.packageName = view.getContext().getOpPackageName();
- tba.autofillId = view.getAutofillId();
- tba.fieldId = view.getId();
- InputConnection ic = view.onCreateInputConnection(tba);
- if (DEBUG) Log.v(TAG, "Starting input: tba=" + tba + " ic=" + ic);
+ editorInfo.packageName = view.getContext().getOpPackageName();
+ editorInfo.autofillId = view.getAutofillId();
+ editorInfo.fieldId = view.getId();
+ InputConnection ic = view.onCreateInputConnection(editorInfo);
+ if (DEBUG) Log.v(TAG, "Starting input: editorInfo=" + editorInfo + " ic=" + ic);
// Clear autofill and field ids if a connection could not be established.
// This ensures that even disconnected EditorInfos have well-defined attributes,
// making them consistently and straightforwardly comparable.
if (ic == null) {
- tba.autofillId = AutofillId.NO_AUTOFILL_ID;
- tba.fieldId = 0;
+ editorInfo.autofillId = AutofillId.NO_AUTOFILL_ID;
+ editorInfo.fieldId = 0;
}
final Handler icHandler;
@@ -2342,7 +2379,10 @@ public final class InputMethodManager {
}
// Hook 'em up and let 'er rip.
- mCurrentEditorInfo = tba.createCopyInternal();
+ mCurrentEditorInfo = editorInfo.createCopyInternal();
+ // Store the previously served connection so that we can determine whether it is safe
+ // to skip the call to startInputOrWindowGainedFocus in the IMMS
+ final RemoteInputConnectionImpl previouslyServedConnection = mServedInputConnection;
mServedConnecting = false;
if (mServedInputConnection != null) {
@@ -2352,8 +2392,8 @@ public final class InputMethodManager {
}
final RemoteInputConnectionImpl servedInputConnection;
if (ic != null) {
- mCursorSelStart = tba.initialSelStart;
- mCursorSelEnd = tba.initialSelEnd;
+ mCursorSelStart = editorInfo.initialSelStart;
+ mCursorSelEnd = editorInfo.initialSelEnd;
mInitialSelStart = mCursorSelStart;
mInitialSelEnd = mCursorSelEnd;
mCursorCandStart = -1;
@@ -2379,22 +2419,40 @@ public final class InputMethodManager {
if (DEBUG) {
Log.v(TAG, "START INPUT: view=" + dumpViewInfo(view) + " ic="
- + ic + " tba=" + tba + " startInputFlags="
+ + ic + " editorInfo=" + editorInfo + " startInputFlags="
+ InputMethodDebug.startInputFlagsToString(startInputFlags));
}
+
+ // When we switch between non-editable views, do not call into the IMMS.
+ final boolean canSkip = OPTIMIZE_NONEDITABLE_VIEWS
+ && previouslyServedConnection == null
+ && ic == null
+ && isSwitchingBetweenEquivalentNonEditableViews(
+ mDelegate.mPreviousViewFocusParameters, startInputFlags,
+ startInputReason, softInputMode, windowFlags);
+ updatePreviousViewFocusParametersLocked(mCurrentEditorInfo, startInputFlags,
+ startInputReason, softInputMode, windowFlags);
+ if (canSkip) {
+ if (DEBUG) {
+ Log.d(TAG, "Not calling IMMS due to switching between non-editable views.");
+ }
+ return false;
+ }
+ final int targetUserId = editorInfo.targetInputMethodUser != null
+ ? editorInfo.targetInputMethodUser.getIdentifier() : UserHandle.myUserId();
res = mServiceInvoker.startInputOrWindowGainedFocus(
startInputReason, mClient, windowGainingFocus, startInputFlags,
- softInputMode, windowFlags, tba, servedInputConnection,
+ softInputMode, windowFlags, editorInfo, servedInputConnection,
servedInputConnection == null ? null
: servedInputConnection.asIRemoteAccessibilityInputConnection(),
- view.getContext().getApplicationInfo().targetSdkVersion,
+ view.getContext().getApplicationInfo().targetSdkVersion, targetUserId,
mImeDispatcher);
if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
if (res == null) {
Log.wtf(TAG, "startInputOrWindowGainedFocus must not return"
+ " null. startInputReason="
+ InputMethodDebug.startInputReasonToString(startInputReason)
- + " editorInfo=" + tba
+ + " editorInfo=" + editorInfo
+ " startInputFlags="
+ InputMethodDebug.startInputFlagsToString(startInputFlags));
return false;
@@ -2436,17 +2494,58 @@ public final class InputMethodManager {
if (ic != null && res != null && res.method != null) {
if (DEBUG) {
Log.v(TAG, "Calling View.onInputConnectionOpened: view= " + view
- + ", ic=" + ic + ", tba=" + tba + ", handler=" + icHandler);
+ + ", ic=" + ic + ", editorInfo=" + editorInfo + ", handler=" + icHandler);
}
- reportInputConnectionOpened(ic, tba, icHandler, view);
+ reportInputConnectionOpened(ic, editorInfo, icHandler, view);
}
return true;
}
+ /**
+ * This method exists only so that the
+ * <a href="https://errorprone.info/bugpattern/GuardedBy">errorprone</a> false positive warning
+ * can be suppressed without granting a blanket exception to the {@link #startInputInner}
+ * method.
+ * <p>
+ * The warning in question implies that the access to the
+ * {@link DelegateImpl#updatePreviousViewFocusParametersLocked} method should be guarded by
+ * {@code InputMethodManager.this.mH}, but instead {@code mDelegate.mH} is held in the caller.
+ * In this case errorprone fails to realize that it is the same object.
+ */
+ @GuardedBy("mH")
+ @SuppressWarnings("GuardedBy")
+ private void updatePreviousViewFocusParametersLocked(
+ @Nullable EditorInfo currentEditorInfo,
+ @StartInputFlags int startInputFlags,
+ @StartInputReason int startInputReason,
+ @SoftInputModeFlags int softInputMode,
+ int windowFlags) {
+ mDelegate.updatePreviousViewFocusParametersLocked(currentEditorInfo, startInputFlags,
+ startInputReason, softInputMode, windowFlags);
+ }
+
+ /**
+ * @return {@code true} when we are switching focus between two non-editable views
+ * so that we can avoid calling {@link IInputMethodManager#startInputOrWindowGainedFocus}.
+ */
+ @GuardedBy("mH")
+ private boolean isSwitchingBetweenEquivalentNonEditableViews(
+ @Nullable ViewFocusParameterInfo previousViewFocusParameters,
+ @StartInputFlags int startInputFlags,
+ @StartInputReason int startInputReason,
+ @SoftInputModeFlags int softInputMode,
+ int windowFlags) {
+ return (startInputFlags & StartInputFlags.WINDOW_GAINED_FOCUS) == 0
+ && (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) == 0
+ && previousViewFocusParameters != null
+ && previousViewFocusParameters.sameAs(mCurrentEditorInfo,
+ startInputFlags, startInputReason, softInputMode, windowFlags);
+ }
+
private void reportInputConnectionOpened(
- InputConnection ic, EditorInfo tba, Handler icHandler, View view) {
- view.onInputConnectionOpenedInternal(ic, tba, icHandler);
+ InputConnection ic, EditorInfo editorInfo, Handler icHandler, View view) {
+ view.onInputConnectionOpenedInternal(ic, editorInfo, icHandler);
final ViewRootImpl viewRoot = view.getViewRootImpl();
if (viewRoot != null) {
viewRoot.getHandwritingInitiator().onInputConnectionCreated(view);
@@ -3275,7 +3374,7 @@ public final class InputMethodManager {
*/
@Nullable
public InputMethodSubtype getCurrentInputMethodSubtype() {
- return mServiceInvoker.getCurrentInputMethodSubtype();
+ return mServiceInvoker.getCurrentInputMethodSubtype(UserHandle.myUserId());
}
/**
@@ -3320,7 +3419,8 @@ public final class InputMethodManager {
return false;
}
final List<InputMethodSubtype> enabledSubtypes =
- mServiceInvoker.getEnabledInputMethodSubtypeList(imeId, true);
+ mServiceInvoker.getEnabledInputMethodSubtypeList(imeId, true,
+ UserHandle.myUserId());
final int numSubtypes = enabledSubtypes.size();
for (int i = 0; i < numSubtypes; ++i) {
final InputMethodSubtype enabledSubtype = enabledSubtypes.get(i);
@@ -3515,7 +3615,7 @@ public final class InputMethodManager {
@Nullable
public InputMethodSubtype getLastInputMethodSubtype() {
- return mServiceInvoker.getLastInputMethodSubtype();
+ return mServiceInvoker.getLastInputMethodSubtype(UserHandle.myUserId());
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 9c63d56d74da..121839bc9ea6 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -666,14 +666,12 @@ public final class InputMethodSubtype implements Parcelable {
/**
* Sort the list of InputMethodSubtype
- * @param context Context will be used for getting localized strings from IME
- * @param flags Flags for the sort order
* @param imi InputMethodInfo of which subtypes are subject to be sorted
* @param subtypeList List of InputMethodSubtype which will be sorted
* @return Sorted list of subtypes
* @hide
*/
- public static List<InputMethodSubtype> sort(Context context, int flags, InputMethodInfo imi,
+ public static List<InputMethodSubtype> sort(InputMethodInfo imi,
List<InputMethodSubtype> subtypeList) {
if (imi == null) return subtypeList;
final HashSet<InputMethodSubtype> inputSubtypesSet = new HashSet<InputMethodSubtype>(
diff --git a/core/java/android/view/inputmethod/SurroundingText.java b/core/java/android/view/inputmethod/SurroundingText.java
index c85a18a1df79..6bfd63bafd45 100644
--- a/core/java/android/view/inputmethod/SurroundingText.java
+++ b/core/java/android/view/inputmethod/SurroundingText.java
@@ -181,4 +181,14 @@ public final class SurroundingText implements Parcelable {
}
}
}
+
+ /** @hide */
+ public boolean isEqualTo(@Nullable SurroundingText that) {
+ if (that == null) return false;
+ if (this == that) return true;
+ return mSelectionStart == that.mSelectionStart
+ && mSelectionEnd == that.mSelectionEnd
+ && mOffset == that.mOffset
+ && TextUtils.equals(mText, that.mText);
+ }
}
diff --git a/core/java/android/view/inputmethod/ViewFocusParameterInfo.java b/core/java/android/view/inputmethod/ViewFocusParameterInfo.java
new file mode 100644
index 000000000000..44c33fac8ccb
--- /dev/null
+++ b/core/java/android/view/inputmethod/ViewFocusParameterInfo.java
@@ -0,0 +1,64 @@
+/*
+ * 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.view.inputmethod;
+
+import android.annotation.Nullable;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+
+import com.android.internal.inputmethod.StartInputFlags;
+import com.android.internal.inputmethod.StartInputReason;
+import com.android.internal.view.IInputMethodManager;
+
+/**
+ * This data class is a container for storing the last arguments used when calling into
+ * {@link IInputMethodManager#startInputOrWindowGainedFocus}. They are used to determine if we
+ * are switching from a non-editable view to another non-editable view, in which case we avoid
+ * a binder call into the {@link com.android.server.inputmethod.InputMethodManagerService}.
+ */
+final class ViewFocusParameterInfo {
+ @Nullable final EditorInfo mPreviousEditorInfo;
+ @StartInputFlags final int mPreviousStartInputFlags;
+ @StartInputReason final int mPreviousStartInputReason;
+ @SoftInputModeFlags final int mPreviousSoftInputMode;
+ final int mPreviousWindowFlags;
+
+ ViewFocusParameterInfo(@Nullable EditorInfo previousEditorInfo,
+ @StartInputFlags int previousStartInputFlags,
+ @StartInputReason int previousStartInputReason,
+ @SoftInputModeFlags int previousSoftInputMode,
+ int previousWindowFlags) {
+ mPreviousEditorInfo = previousEditorInfo;
+ mPreviousStartInputFlags = previousStartInputFlags;
+ mPreviousStartInputReason = previousStartInputReason;
+ mPreviousSoftInputMode = previousSoftInputMode;
+ mPreviousWindowFlags = previousWindowFlags;
+ }
+
+ boolean sameAs(@Nullable EditorInfo currentEditorInfo,
+ @StartInputFlags int startInputFlags,
+ @StartInputReason int startInputReason,
+ @SoftInputModeFlags int softInputMode,
+ int windowFlags) {
+ return mPreviousStartInputFlags == startInputFlags
+ && mPreviousStartInputReason == startInputReason
+ && mPreviousSoftInputMode == softInputMode
+ && mPreviousWindowFlags == windowFlags
+ && (mPreviousEditorInfo == currentEditorInfo
+ || (mPreviousEditorInfo != null
+ && mPreviousEditorInfo.kindofEquals(currentEditorInfo)));
+ }
+}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index dbf3570b1d24..ca57c84a1631 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -32,6 +32,7 @@ import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
@@ -494,19 +495,39 @@ public class Toast {
*/
public static Toast makeText(@NonNull Context context, @Nullable Looper looper,
@NonNull CharSequence text, @Duration int duration) {
+ Toast result = new Toast(context, looper);
+
if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) {
- Toast result = new Toast(context, looper);
result.mText = text;
- result.mDuration = duration;
- return result;
} else {
- Toast result = new Toast(context, looper);
- View v = ToastPresenter.getTextToastView(context, text);
- result.mNextView = v;
- result.mDuration = duration;
+ result.mNextView = ToastPresenter.getTextToastView(context, text);
+ }
+
+ result.mDuration = duration;
+ return result;
+ }
- return result;
+ /**
+ * Make a standard toast with an icon to display using the specified looper.
+ * If looper is null, Looper.myLooper() is used.
+ *
+ * The toast will be a custom view that's rendered by the app (instead of by SystemUI).
+ * In Android version R and above, non-system apps can only render the toast
+ * when it's in the foreground.
+ *
+ * @hide
+ */
+ public static Toast makeCustomToastWithIcon(@NonNull Context context, @Nullable Looper looper,
+ @NonNull CharSequence text, @Duration int duration, @NonNull Drawable icon) {
+ if (icon == null) {
+ throw new IllegalArgumentException("Drawable icon should not be null "
+ + "for makeCustomToastWithIcon");
}
+
+ Toast result = new Toast(context, looper);
+ result.mNextView = ToastPresenter.getTextToastViewWithIcon(context, text, icon);
+ result.mDuration = duration;
+ return result;
}
/**
diff --git a/core/java/android/widget/ToastPresenter.java b/core/java/android/widget/ToastPresenter.java
index eccff0692fab..7467100838ec 100644
--- a/core/java/android/widget/ToastPresenter.java
+++ b/core/java/android/widget/ToastPresenter.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -55,6 +56,8 @@ public class ToastPresenter {
@VisibleForTesting
public static final int TEXT_TOAST_LAYOUT = R.layout.transient_notification;
+ @VisibleForTesting
+ public static final int TEXT_TOAST_LAYOUT_WITH_ICON = R.layout.transient_notification_with_icon;
/**
* Returns the default text toast view for message {@code text}.
@@ -66,6 +69,24 @@ public class ToastPresenter {
return view;
}
+ /**
+ * Returns the default icon text toast view for message {@code text} and the icon {@code icon}.
+ */
+ public static View getTextToastViewWithIcon(Context context, CharSequence text, Drawable icon) {
+ if (icon == null) {
+ return getTextToastView(context, text);
+ }
+
+ View view = LayoutInflater.from(context).inflate(TEXT_TOAST_LAYOUT_WITH_ICON, null);
+ TextView textView = view.findViewById(com.android.internal.R.id.message);
+ textView.setText(text);
+ ImageView imageView = view.findViewById(com.android.internal.R.id.icon);
+ if (imageView != null) {
+ imageView.setImageDrawable(icon);
+ }
+ return view;
+ }
+
private final Context mContext;
private final Resources mResources;
private final WindowManager mWindowManager;
diff --git a/core/java/android/window/ITaskFragmentOrganizer.aidl b/core/java/android/window/ITaskFragmentOrganizer.aidl
index 8dfda7d41c2d..3335c9c073e0 100644
--- a/core/java/android/window/ITaskFragmentOrganizer.aidl
+++ b/core/java/android/window/ITaskFragmentOrganizer.aidl
@@ -45,10 +45,11 @@ oneway interface ITaskFragmentOrganizer {
*
* @param errorCallbackToken Token set through {@link
* WindowContainerTransaction#setErrorCallbackToken(IBinder)}
- * @param exceptionBundle Bundle containing the exception. Should be created with
- * {@link TaskFragmentOrganizer#putExceptionInBundle}.
+ * @param errorBundle Bundle containing the exception, operation type and TaskFragmentInfo
+ * if any. Should be created with
+ * {@link TaskFragmentOrganizer#putErrorInfoInBundle}.
*/
- void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle exceptionBundle);
+ void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle errorBundle);
/**
* Called when an Activity is reparented to the Task with organized TaskFragment. For example,
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index f1a052b61c59..2fc22c23ff06 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -221,8 +221,6 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
* @param previous the previously focused {@link ViewRootImpl}.
* @param current the currently focused {@link ViewRootImpl}.
*/
- // TODO(b/232845902): Add CTS to test IME back behavior when there's root view change while
- // IME is up.
public void switchRootView(ViewRootImpl previous, ViewRootImpl current) {
for (ImeOnBackInvokedCallback imeCallback : mImeCallbacks) {
if (previous != null) {
diff --git a/core/java/android/window/SurfaceSyncGroup.java b/core/java/android/window/SurfaceSyncGroup.java
new file mode 100644
index 000000000000..4248096f307d
--- /dev/null
+++ b/core/java/android/window/SurfaceSyncGroup.java
@@ -0,0 +1,392 @@
+/*
+ * 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.Nullable;
+import android.annotation.UiThread;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.Pair;
+import android.view.AttachedSurfaceControl;
+import android.view.SurfaceControl.Transaction;
+import android.view.SurfaceView;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * Used to organize syncs for surfaces.
+ *
+ * The SurfaceSyncGroup allows callers to add desired syncs into a set and wait for them to all
+ * complete before getting a callback. The purpose of the SurfaceSyncGroup is to be an accounting
+ * mechanism so each sync implementation doesn't need to handle it themselves. The SurfaceSyncGroup
+ * class is used the following way.
+ *
+ * 1. {@link #SurfaceSyncGroup()} constructor is called
+ * 2. {@link #addToSync(SyncTarget)} is called for every SyncTarget object that wants to be
+ * included in the sync. If the addSync is called for an {@link AttachedSurfaceControl} or
+ * {@link SurfaceView} it needs to be called on the UI thread. When addToSync is called, it's
+ * guaranteed that any UI updates that were requested before addToSync but after the last frame
+ * drew, will be included in the sync.
+ * 3. {@link #markSyncReady()} should be called when all the {@link SyncTarget}s have been added
+ * to the SurfaceSyncGroup. At this point, the SurfaceSyncGroup is closed and no more SyncTargets
+ * can be added to it.
+ * 4. The SurfaceSyncGroup will gather the data for each SyncTarget using the steps described below.
+ * When all the SyncTargets have finished, the syncRequestComplete will be invoked and the
+ * transaction will either be applied or sent to the caller. In most cases, only the
+ * SurfaceSyncGroup should be handling the Transaction object directly. However, there are some
+ * cases where the framework needs to send the Transaction elsewhere, like in ViewRootImpl, so that
+ * option is provided.
+ *
+ * The following is what happens within the {@link SurfaceSyncGroup}
+ * 1. Each SyncTarget will get a {@link SyncTarget#onReadyToSync} callback that contains a
+ * {@link SyncBufferCallback}.
+ * 2. Each {@link SyncTarget} needs to invoke {@link SyncBufferCallback#onBufferReady(Transaction)}.
+ * This makes sure the SurfaceSyncGroup knows when the SyncTarget is complete, allowing the
+ * SurfaceSyncGroup to get the Transaction that contains the buffer.
+ * 3. When the final SyncBufferCallback finishes for the SurfaceSyncGroup, in most cases the
+ * transaction is applied and then the sync complete callbacks are invoked, letting the callers know
+ * the sync is now complete.
+ *
+ * @hide
+ */
+public final class SurfaceSyncGroup {
+ private static final String TAG = "SurfaceSyncGroup";
+ private static final boolean DEBUG = false;
+
+ private static Supplier<Transaction> sTransactionFactory = Transaction::new;
+
+ /**
+ * Class that collects the {@link SyncTarget}s and notifies when all the surfaces have
+ * a frame ready.
+ */
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
+ private final Set<Integer> mPendingSyncs = new ArraySet<>();
+ @GuardedBy("mLock")
+ private final Transaction mTransaction = sTransactionFactory.get();
+ @GuardedBy("mLock")
+ private boolean mSyncReady;
+ @GuardedBy("mLock")
+ private final Set<SyncTarget> mSyncTargets = new ArraySet<>();
+
+ @GuardedBy("mLock")
+ private Consumer<Transaction> mSyncRequestCompleteCallback;
+
+ @GuardedBy("mLock")
+ private final Set<SurfaceSyncGroup> mMergedSyncGroups = new ArraySet<>();
+
+ @GuardedBy("mLock")
+ private boolean mFinished;
+
+ @GuardedBy("mLock")
+ private final ArraySet<Pair<Executor, Runnable>> mSyncCompleteCallbacks = new ArraySet<>();
+
+ /**
+ * @hide
+ */
+ public static void setTransactionFactory(Supplier<Transaction> transactionFactory) {
+ sTransactionFactory = transactionFactory;
+ }
+
+ /**
+ * Starts a sync and will automatically apply the final, merged transaction.
+ */
+ public SurfaceSyncGroup() {
+ this(transaction -> {
+ if (transaction != null) {
+ transaction.apply();
+ }
+ });
+
+ }
+
+ /**
+ * Creates a sync.
+ *
+ * @param syncRequestComplete The complete callback that contains the syncId and transaction
+ * with all the sync data merged. The Transaction passed back can be
+ * null.
+ *
+ * NOTE: Only should be used by ViewRootImpl
+ * @hide
+ */
+ public SurfaceSyncGroup(Consumer<Transaction> syncRequestComplete) {
+ mSyncRequestCompleteCallback = transaction -> {
+ syncRequestComplete.accept(transaction);
+ synchronized (mLock) {
+ for (Pair<Executor, Runnable> callback : mSyncCompleteCallbacks) {
+ callback.first.execute(callback.second);
+ }
+ }
+ };
+
+ if (DEBUG) {
+ Log.d(TAG, "setupSync");
+ }
+ }
+
+ /**
+ * Add a {@link Runnable} to be executed when the sync completes.
+ *
+ * @param executor The Executor to invoke the Runnable on
+ * @param runnable The Runnable to get called
+ */
+ public void addSyncCompleteCallback(Executor executor, Runnable runnable) {
+ synchronized (mLock) {
+ mSyncCompleteCallbacks.add(new Pair<>(executor, runnable));
+ }
+ }
+
+ /**
+ * Add a SurfaceView to a sync set. This is different than
+ * {@link #addToSync(AttachedSurfaceControl)} because it requires the caller to notify the start
+ * and finish drawing in order to sync.
+ *
+ * @param surfaceView The SurfaceView to add to the sync.
+ * @param frameCallbackConsumer The callback that's invoked to allow the caller to notify
+ * the
+ * Syncer when the SurfaceView has started drawing and
+ * finished.
+ * @return true if the SurfaceView was successfully added to the SyncGroup, false otherwise.
+ */
+ @UiThread
+ public boolean addToSync(SurfaceView surfaceView,
+ Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) {
+ return addToSync(new SurfaceViewSyncTarget(surfaceView, frameCallbackConsumer));
+ }
+
+ /**
+ * Add a View's rootView to a sync set.
+ *
+ * @param viewRoot The viewRoot that will be add to the sync set
+ * @return true if the View was successfully added to the SyncGroup, false otherwise.
+ */
+ @UiThread
+ public boolean addToSync(@Nullable AttachedSurfaceControl viewRoot) {
+ if (viewRoot == null) {
+ return false;
+ }
+ SyncTarget syncTarget = viewRoot.getSyncTarget();
+ if (syncTarget == null) {
+ return false;
+ }
+ return addToSync(syncTarget);
+ }
+
+ /**
+ * Add a {@link SyncTarget} to a sync set. The sync set will wait for all
+ * SyncableSurfaces to complete before notifying.
+ *
+ * @param syncTarget A SyncableSurface that implements how to handle syncing
+ * buffers.
+ * @return true if the SyncTarget was successfully added to the SyncGroup, false otherwise.
+ */
+ public boolean addToSync(SyncTarget syncTarget) {
+ SyncBufferCallback syncBufferCallback = new SyncBufferCallback() {
+ @Override
+ public void onBufferReady(Transaction t) {
+ synchronized (mLock) {
+ if (t != null) {
+ mTransaction.merge(t);
+ }
+ mPendingSyncs.remove(hashCode());
+ checkIfSyncIsComplete();
+ }
+ }
+ };
+
+ synchronized (mLock) {
+ if (mSyncReady) {
+ Log.e(TAG, "Sync " + this + " was already marked as ready. No more "
+ + "SyncTargets can be added.");
+ return false;
+ }
+ mPendingSyncs.add(syncBufferCallback.hashCode());
+ mSyncTargets.add(syncTarget);
+ }
+ syncTarget.onReadyToSync(syncBufferCallback);
+ return true;
+ }
+
+ /**
+ * Mark the sync set as ready to complete. No more data can be added to the specified
+ * syncId.
+ * Once the sync set is marked as ready, it will be able to complete once all Syncables in the
+ * set have completed their sync
+ */
+ public void markSyncReady() {
+ synchronized (mLock) {
+ mSyncReady = true;
+ checkIfSyncIsComplete();
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void checkIfSyncIsComplete() {
+ if (!mSyncReady || !mPendingSyncs.isEmpty() || !mMergedSyncGroups.isEmpty()) {
+ if (DEBUG) {
+ Log.d(TAG, "Syncable is not complete. mSyncReady=" + mSyncReady
+ + " mPendingSyncs=" + mPendingSyncs.size() + " mergedSyncs="
+ + mMergedSyncGroups.size());
+ }
+ return;
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "Successfully finished sync id=" + this);
+ }
+
+ for (SyncTarget syncTarget : mSyncTargets) {
+ syncTarget.onSyncComplete();
+ }
+ mSyncTargets.clear();
+ mSyncRequestCompleteCallback.accept(mTransaction);
+ mFinished = true;
+ }
+
+ /**
+ * Add a Transaction to this sync set. This allows the caller to provide other info that
+ * should be synced with the buffers.
+ */
+ public void addTransactionToSync(Transaction t) {
+ synchronized (mLock) {
+ mTransaction.merge(t);
+ }
+ }
+
+ private void updateCallback(Consumer<Transaction> transactionConsumer) {
+ synchronized (mLock) {
+ if (mFinished) {
+ Log.e(TAG, "Attempting to merge SyncGroup " + this + " when sync is"
+ + " already complete");
+ transactionConsumer.accept(null);
+ }
+
+ final Consumer<Transaction> oldCallback = mSyncRequestCompleteCallback;
+ mSyncRequestCompleteCallback = transaction -> {
+ oldCallback.accept(null);
+ transactionConsumer.accept(transaction);
+ };
+ }
+ }
+
+ /**
+ * Merge a SyncGroup into this SyncGroup. Since SyncGroups could still have pending SyncTargets,
+ * we need to make sure those can still complete before the mergeTo SyncGroup is considered
+ * complete.
+ *
+ * We keep track of all the merged SyncGroups until they are marked as done, and then they
+ * are removed from the set. This SyncGroup is not considered done until all the merged
+ * SyncGroups are done.
+ *
+ * When the merged SyncGroup is complete, it will invoke the original syncRequestComplete
+ * callback but send an empty transaction to ensure the changes are applied early. This
+ * is needed in case the original sync is relying on the callback to continue processing.
+ *
+ * @param otherSyncGroup The other SyncGroup to merge into this one.
+ */
+ public void merge(SurfaceSyncGroup otherSyncGroup) {
+ synchronized (mLock) {
+ mMergedSyncGroups.add(otherSyncGroup);
+ }
+ otherSyncGroup.updateCallback(transaction -> {
+ synchronized (mLock) {
+ mMergedSyncGroups.remove(otherSyncGroup);
+ if (transaction != null) {
+ mTransaction.merge(transaction);
+ }
+ checkIfSyncIsComplete();
+ }
+ });
+ }
+
+ /**
+ * Wrapper class to help synchronize SurfaceViews
+ */
+ private static class SurfaceViewSyncTarget implements SyncTarget {
+ private final SurfaceView mSurfaceView;
+ private final Consumer<SurfaceViewFrameCallback> mFrameCallbackConsumer;
+
+ SurfaceViewSyncTarget(SurfaceView surfaceView,
+ Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) {
+ mSurfaceView = surfaceView;
+ mFrameCallbackConsumer = frameCallbackConsumer;
+ }
+
+ @Override
+ public void onReadyToSync(SyncBufferCallback syncBufferCallback) {
+ mFrameCallbackConsumer.accept(
+ () -> mSurfaceView.syncNextFrame(syncBufferCallback::onBufferReady));
+ }
+ }
+
+ /**
+ * A SyncTarget that can be added to a sync set.
+ */
+ public interface SyncTarget {
+ /**
+ * Called when the Syncable is ready to begin handing a sync request. When invoked, the
+ * implementor is required to call {@link SyncBufferCallback#onBufferReady(Transaction)}
+ * and {@link SyncBufferCallback#onBufferReady(Transaction)} in order for this Syncable
+ * to be marked as complete.
+ *
+ * Always invoked on the thread that initiated the call to {@link #addToSync(SyncTarget)}
+ *
+ * @param syncBufferCallback A SyncBufferCallback that the caller must invoke onBufferReady
+ */
+ void onReadyToSync(SyncBufferCallback syncBufferCallback);
+
+ /**
+ * There's no guarantee about the thread this callback is invoked on.
+ */
+ default void onSyncComplete() {
+ }
+ }
+
+ /**
+ * Interface so the SurfaceSyncer can know when it's safe to start and when everything has been
+ * completed. The caller should invoke the calls when the rendering has started and finished a
+ * frame.
+ */
+ public interface SyncBufferCallback {
+ /**
+ * Invoked when the transaction contains the buffer and is ready to sync.
+ *
+ * @param t The transaction that contains the buffer to be synced. This can be null if
+ * there's nothing to sync
+ */
+ void onBufferReady(@Nullable Transaction t);
+ }
+
+ /**
+ * A frame callback that is used to synchronize SurfaceViews. The owner of the SurfaceView must
+ * implement onFrameStarted when trying to sync the SurfaceView. This is to ensure the sync
+ * knows when the frame is ready to add to the sync.
+ */
+ public interface SurfaceViewFrameCallback {
+ /**
+ * Called when the SurfaceView is going to render a frame
+ */
+ void onFrameStarted();
+ }
+}
diff --git a/core/java/android/window/SurfaceSyncGroup.md b/core/java/android/window/SurfaceSyncGroup.md
new file mode 100644
index 000000000000..659aade24a91
--- /dev/null
+++ b/core/java/android/window/SurfaceSyncGroup.md
@@ -0,0 +1,86 @@
+## SurfaceSyncGroup
+
+### Overview
+
+A generic way for data to be gathered so multiple surfaces can be synced. This is intended to be used with Views, SurfaceView, and any other surface that wants to be involved in a sync. This allows different parts of the Android system to synchronize different windows and layers themselves without having to go through WindowManagerService
+
+### Code
+
+SurfaceSyncGroup is a class that manages sync requests and reports back when all participants in the sync are ready.
+
+##### Constructor
+The first step is to create a sync request. This is done by creating a new `SurfaceSyncGroup`.
+There are two constructors: one that accepts a `Consumer<Transaction>` and one that's empty. The empty constructor will automatically apply the final transaction. The second constructor should only be used by ViewRootImpl. The purpose of this one is to allow the caller to get back the merged transaction without it being applied. ViewRootImpl uses it to send the transaction to WindowManagerService to be synced there. Using this one for other cases is unsafe because the caller may hold the transaction longer than expected and prevent buffers from being latched and released.
+
+##### markSyncReady
+
+When the caller has added all the `SyncTarget` to the sync, they should call `markSyncReady()` If the caller doesn't call this, the sync will never complete since the SurfaceSyncGroup wants to give the caller a chance to add all the SyncTargets before considering the sync ready. Before `markSyncReady` is called, the `SyncTargets` can actually produce a frame, which will just be held in a transaction until all other `SyncTargets` are ready AND `markSyncReady` has been called. Once markSyncReady has been called, you cannot add any more `SyncTargets` to that particular SurfaceSyncGroup.
+
+##### addToSync
+
+The caller will invoke `addToSync` for every `SyncTarget` that it wants included. There are a few helper methods since the most common cases are Views and SurfaceView
+* `addToSync(AttachedSurfaceControl)` - This is used for syncing the root of the View, specificially the ViewRootImpl
+* `addToSync(SurfaceView, Consumer<SurfaceViewFrameCallback>)` - This is to sync a SurfaceView. Since SurfaceViews are rendered by the app, the caller will be expected to provide a way to get back the buffer to sync. More details about that [below](#surfaceviewframecallback)
+* `addToSync(SyncTarget)` - This is the generic method. It can be used to sync arbitrary info. The SyncTarget interface has required methods that need to be implemented to properly get the transaction to sync.
+
+When calling addToSync with either AttachedSurfaceControl or SurfaceView, it must be called on the UI Thread. This is to ensure consistent behavior, where any UI changes done while still on the UI thread are included in this frame. The next vsync will pick up those changes and request to draw.
+
+##### addTransactionToSync
+
+This is a simple method that allows callers to add generic Transactions to the sync. The caller invokes `addTransactionToSync(Transaction)`. This can be used for any additional things that need to be included in the same SyncGroup.
+
+##### merge
+
+To add more flexibility to Syncs, an API is provided to merge SurfaceSyncGroups. The caller provides the SurfaceSyncGroup it wants merged. The current SurfaceSyncGroup will now wait for the passed in SurfaceSyncGroup to complete, as well as its own SyncTargets to complete before invoking the callback. The passed in SurfaceSyncGroup will also get a complete callback but only when its SurfaceSyncGroup completes, not the one it merged into. If a `Consumer<Transaction>` was passed in to the SurfaceSyncGroup, it will get back an emtpy Transaction so it can't accidentally apply things that were meant to be merged.
+
+##### addSyncCompleteCallback
+
+This allows callers to receive a callback when the sync is complete. The method takes in an Executor and a Runnable that will be invoked when the SurfaceSyncGroup has completed. The Executor is used to invoke the callback on the desired thread. You can add more than one callback.
+
+##### SyncTarget
+
+This interface is used to handle syncs. The interface has two methods
+* `onReadyToSync(SyncBufferCallback)` - This one must be implemented. The sync will notify the `SyncTarget` so it can invoke the `SyncBufferCallback`, letting the sync know when it's ready.
+* `onSyncComplete()` - This method is optional. It's used to notify the `SyncTarget` that the entire sync is complete. This is similar to the callback sent in `setupSync`, but it's invoked to the `SyncTargets` rather than the caller who started the sync. This is used by ViewRootImpl to restore the state when the entire sync is done
+
+When syncing ViewRootImpl, these methods are implemented already since ViewRootImpl handles the rendering requests and timing.
+
+##### SyncBufferCallback
+
+This interface is used to tell the sync that this SyncTarget is ready. There's only method here, `onBufferReady(Transaction)`, that sends back the transaction that contains the data to be synced, normally with a buffer.
+
+##### SurfaceViewFrameCallback
+
+As mentioned above, SurfaceViews are a special case because the buffers produced are handled by the app, and not the framework. Because of this, the SurfaceSyncGroup doesn't know which frame to sync. Therefore, to sync SurfaceViews, the caller must provide a way to notify the SurfaceSyncGroup that it's going to render a buffer and that this next buffer is the one to sync. The `SurfaceViewFrameCallback` has one method `onFrameStarted()`. When this is invoked, the SurfaceSyncGroup sets up a request to sync the next buffer for the SurfaceView.
+
+
+### Example
+
+A simple example where you want to sync two windows and also include a transaction in the sync
+
+```java
+SurfaceSyncGroup syncGroup = new SurfaceSyncGroup();
+SyncGroup.addSyncCompleteCallback(mMainThreadExecutor, () -> {
+ Log.d(TAG, "syncComplete");
+};
+syncGroup.addToSync(view1.getRootSurfaceControl());
+syncGroup.addToSync(view2.getRootSurfaceControl());
+syncGroup.addTransactionToSync(transaction);
+syncGroup.markSyncReady();
+```
+
+A SurfaceView example:
+See `frameworks/base/tests/SurfaceViewSyncTest` for a working example
+
+```java
+SurfaceSyncGroup syncGroup = new SurfaceSyncGroup();
+syncGroup.addSyncCompleteCallback(mMainThreadExecutor, () -> {
+ Log.d(TAG, "syncComplete");
+};
+syncGroup.addToSync(container.getRootSurfaceControl());
+syncGroup.addToSync(surfaceView, frameCallback -> {
+ // Call this when the SurfaceView is ready to render a new frame with the changes.
+ frameCallback.onFrameStarted()
+}
+syncGroup.markSyncReady();
+``` \ No newline at end of file
diff --git a/core/java/android/window/SurfaceSyncer.java b/core/java/android/window/SurfaceSyncer.java
deleted file mode 100644
index e6eb07162a3b..000000000000
--- a/core/java/android/window/SurfaceSyncer.java
+++ /dev/null
@@ -1,472 +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;
-import android.annotation.Nullable;
-import android.annotation.UiThread;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.SurfaceControl.Transaction;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.ViewRootImpl;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.Set;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-/**
- * Used to organize syncs for surfaces.
- *
- * The SurfaceSyncer allows callers to add desired syncs into a set and wait for them to all
- * complete before getting a callback. The purpose of the Syncer is to be an accounting mechanism
- * so each sync implementation doesn't need to handle it themselves. The Syncer class is used the
- * following way.
- *
- * 1. {@link #setupSync(Runnable)} is called
- * 2. {@link #addToSync(int, SyncTarget)} is called for every SyncTarget object that wants to be
- * included in the sync. If the addSync is called for a View or SurfaceView it needs to be called
- * on the UI thread. When addToSync is called, it's guaranteed that any UI updates that were
- * requested before addToSync but after the last frame drew, will be included in the sync.
- * 3. {@link #markSyncReady(int)} should be called when all the {@link SyncTarget}s have been added
- * to the SyncSet. Now the SyncSet is closed and no more SyncTargets can be added to it.
- * 4. The SyncSet will gather the data for each SyncTarget using the steps described below. When
- * all the SyncTargets have finished, the syncRequestComplete will be invoked and the transaction
- * will either be applied or sent to the caller. In most cases, only the SurfaceSyncer should be
- * handling the Transaction object directly. However, there are some cases where the framework
- * needs to send the Transaction elsewhere, like in ViewRootImpl, so that option is provided.
- *
- * The following is what happens within the {@link SyncSet}
- * 1. Each SyncableTarget will get a {@link SyncTarget#onReadyToSync} callback that contains
- * a {@link SyncBufferCallback}.
- * 2. Each {@link SyncTarget} needs to invoke {@link SyncBufferCallback#onBufferReady(Transaction)}.
- * This makes sure the SyncSet knows when the SyncTarget is complete, allowing the SyncSet to get
- * the Transaction that contains the buffer.
- * 3. When the final SyncBufferCallback finishes for the SyncSet, the syncRequestComplete Consumer
- * will be invoked with the transaction that contains all information requested in the sync. This
- * could include buffers and geometry changes. The buffer update will include the UI changes that
- * were requested for the View.
- *
- * @hide
- */
-public class SurfaceSyncer {
- private static final String TAG = "SurfaceSyncer";
- private static final boolean DEBUG = false;
-
- private static Supplier<Transaction> sTransactionFactory = Transaction::new;
-
- private final Object mSyncSetLock = new Object();
- @GuardedBy("mSyncSetLock")
- private final SparseArray<SyncSet> mSyncSets = new SparseArray<>();
- @GuardedBy("mSyncSetLock")
- private int mIdCounter = 0;
-
- /**
- * @hide
- */
- public static void setTransactionFactory(Supplier<Transaction> transactionFactory) {
- sTransactionFactory = transactionFactory;
- }
-
- /**
- * Starts a sync and will automatically apply the final, merged transaction.
- *
- * @param onComplete The runnable that is invoked when the sync has completed. This will run on
- * the same thread that the sync was started on.
- * @return The syncId for the newly created sync.
- * @see #setupSync(Consumer)
- */
- public int setupSync(@Nullable Runnable onComplete) {
- Handler handler = new Handler(Looper.myLooper());
- return setupSync(transaction -> {
- transaction.apply();
- if (onComplete != null) {
- handler.post(onComplete);
- }
- });
- }
-
- /**
- * Starts a sync.
- *
- * @param syncRequestComplete The complete callback that contains the syncId and transaction
- * with all the sync data merged.
- * @return The syncId for the newly created sync.
- * @hide
- * @see #setupSync(Runnable)
- */
- public int setupSync(@NonNull Consumer<Transaction> syncRequestComplete) {
- synchronized (mSyncSetLock) {
- final int syncId = mIdCounter++;
- if (DEBUG) {
- Log.d(TAG, "setupSync " + syncId);
- }
- SyncSet syncSet = new SyncSet(syncId, transaction -> {
- synchronized (mSyncSetLock) {
- mSyncSets.remove(syncId);
- }
- syncRequestComplete.accept(transaction);
- });
- mSyncSets.put(syncId, syncSet);
- return syncId;
- }
- }
-
- /**
- * Mark the sync set as ready to complete. No more data can be added to the specified syncId.
- * Once the sync set is marked as ready, it will be able to complete once all Syncables in the
- * set have completed their sync
- *
- * @param syncId The syncId to mark as ready.
- */
- public void markSyncReady(int syncId) {
- SyncSet syncSet;
- synchronized (mSyncSetLock) {
- syncSet = mSyncSets.get(syncId);
- }
- if (syncSet == null) {
- Log.e(TAG, "Failed to find syncSet for syncId=" + syncId);
- return;
- }
- syncSet.markSyncReady();
- }
-
- /**
- * Merge another SyncSet into the specified syncId.
- * @param syncId The current syncId to merge into
- * @param otherSyncId The other syncId to be merged
- * @param otherSurfaceSyncer The other SurfaceSyncer where the otherSyncId is from
- */
- public void merge(int syncId, int otherSyncId, SurfaceSyncer otherSurfaceSyncer) {
- SyncSet syncSet;
- synchronized (mSyncSetLock) {
- syncSet = mSyncSets.get(syncId);
- }
-
- SyncSet otherSyncSet = otherSurfaceSyncer.getAndValidateSyncSet(otherSyncId);
- if (otherSyncSet == null) {
- return;
- }
-
- if (DEBUG) {
- Log.d(TAG,
- "merge id=" + otherSyncId + " from=" + otherSurfaceSyncer + " into id=" + syncId
- + " from" + this);
- }
- syncSet.merge(otherSyncSet);
- }
-
- /**
- * Add a SurfaceView to a sync set. This is different than {@link #addToSync(int, View)} because
- * it requires the caller to notify the start and finish drawing in order to sync.
- *
- * @param syncId The syncId to add an entry to.
- * @param surfaceView The SurfaceView to add to the sync.
- * @param frameCallbackConsumer The callback that's invoked to allow the caller to notify the
- * Syncer when the SurfaceView has started drawing and finished.
- *
- * @return true if the SurfaceView was successfully added to the SyncSet, false otherwise.
- */
- @UiThread
- public boolean addToSync(int syncId, SurfaceView surfaceView,
- Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) {
- return addToSync(syncId, new SurfaceViewSyncTarget(surfaceView, frameCallbackConsumer));
- }
-
- /**
- * Add a View's rootView to a sync set.
- *
- * @param syncId The syncId to add an entry to.
- * @param view The view where the root will be add to the sync set
- *
- * @return true if the View was successfully added to the SyncSet, false otherwise.
- */
- @UiThread
- public boolean addToSync(int syncId, @NonNull View view) {
- ViewRootImpl viewRoot = view.getViewRootImpl();
- if (viewRoot == null) {
- return false;
- }
- return addToSync(syncId, viewRoot.mSyncTarget);
- }
-
- /**
- * Add a {@link SyncTarget} to a sync set. The sync set will wait for all
- * SyncableSurfaces to complete before notifying.
- *
- * @param syncId The syncId to add an entry to.
- * @param syncTarget A SyncableSurface that implements how to handle syncing
- * buffers.
- *
- * @return true if the SyncTarget was successfully added to the SyncSet, false otherwise.
- */
- public boolean addToSync(int syncId, @NonNull SyncTarget syncTarget) {
- SyncSet syncSet = getAndValidateSyncSet(syncId);
- if (syncSet == null) {
- return false;
- }
- if (DEBUG) {
- Log.d(TAG, "addToSync id=" + syncId);
- }
- return syncSet.addSyncableSurface(syncTarget);
- }
-
- /**
- * Add a transaction to a specific sync so it can be merged along with the frames from the
- * Syncables in the set. This is so the caller can add arbitrary transaction info that will be
- * applied at the same time as the buffers
- * @param syncId The syncId where the transaction will be merged to.
- * @param t The transaction to merge in the sync set.
- */
- public void addTransactionToSync(int syncId, Transaction t) {
- SyncSet syncSet = getAndValidateSyncSet(syncId);
- if (syncSet != null) {
- syncSet.addTransactionToSync(t);
- }
- }
-
- private SyncSet getAndValidateSyncSet(int syncId) {
- SyncSet syncSet;
- synchronized (mSyncSetLock) {
- syncSet = mSyncSets.get(syncId);
- }
- if (syncSet == null) {
- Log.e(TAG, "Failed to find sync for id=" + syncId);
- return null;
- }
- return syncSet;
- }
-
- /**
- * A SyncTarget that can be added to a sync set.
- */
- public interface SyncTarget {
- /**
- * Called when the Syncable is ready to begin handing a sync request. When invoked, the
- * implementor is required to call {@link SyncBufferCallback#onBufferReady(Transaction)}
- * and {@link SyncBufferCallback#onBufferReady(Transaction)} in order for this Syncable
- * to be marked as complete.
- *
- * Always invoked on the thread that initiated the call to
- * {@link #addToSync(int, SyncTarget)}
- *
- * @param syncBufferCallback A SyncBufferCallback that the caller must invoke onBufferReady
- */
- void onReadyToSync(SyncBufferCallback syncBufferCallback);
-
- /**
- * There's no guarantee about the thread this callback is invoked on.
- */
- default void onSyncComplete() {}
- }
-
- /**
- * Interface so the SurfaceSyncer can know when it's safe to start and when everything has been
- * completed. The caller should invoke the calls when the rendering has started and finished a
- * frame.
- */
- public interface SyncBufferCallback {
- /**
- * Invoked when the transaction contains the buffer and is ready to sync.
- *
- * @param t The transaction that contains the buffer to be synced. This can be null if
- * there's nothing to sync
- */
- void onBufferReady(@Nullable Transaction t);
- }
-
- /**
- * Class that collects the {@link SyncTarget}s and notifies when all the surfaces have
- * a frame ready.
- */
- private static class SyncSet {
- private final Object mLock = new Object();
-
- @GuardedBy("mLock")
- private final Set<Integer> mPendingSyncs = new ArraySet<>();
- @GuardedBy("mLock")
- private final Transaction mTransaction = sTransactionFactory.get();
- @GuardedBy("mLock")
- private boolean mSyncReady;
- @GuardedBy("mLock")
- private final Set<SyncTarget> mSyncTargets = new ArraySet<>();
-
- private final int mSyncId;
- @GuardedBy("mLock")
- private Consumer<Transaction> mSyncRequestCompleteCallback;
-
- @GuardedBy("mLock")
- private final Set<SyncSet> mMergedSyncSets = new ArraySet<>();
-
- @GuardedBy("mLock")
- private boolean mFinished;
-
- private SyncSet(int syncId, Consumer<Transaction> syncRequestComplete) {
- mSyncId = syncId;
- mSyncRequestCompleteCallback = syncRequestComplete;
- }
-
- boolean addSyncableSurface(SyncTarget syncTarget) {
- SyncBufferCallback syncBufferCallback = new SyncBufferCallback() {
- @Override
- public void onBufferReady(Transaction t) {
- synchronized (mLock) {
- if (t != null) {
- mTransaction.merge(t);
- }
- mPendingSyncs.remove(hashCode());
- checkIfSyncIsComplete();
- }
- }
- };
-
- synchronized (mLock) {
- if (mSyncReady) {
- Log.e(TAG, "Sync " + mSyncId + " was already marked as ready. No more "
- + "SyncTargets can be added.");
- return false;
- }
- mPendingSyncs.add(syncBufferCallback.hashCode());
- mSyncTargets.add(syncTarget);
- }
- syncTarget.onReadyToSync(syncBufferCallback);
- return true;
- }
-
- void markSyncReady() {
- synchronized (mLock) {
- mSyncReady = true;
- checkIfSyncIsComplete();
- }
- }
-
- @GuardedBy("mLock")
- private void checkIfSyncIsComplete() {
- if (!mSyncReady || !mPendingSyncs.isEmpty() || !mMergedSyncSets.isEmpty()) {
- if (DEBUG) {
- Log.d(TAG, "Syncable is not complete. mSyncReady=" + mSyncReady
- + " mPendingSyncs=" + mPendingSyncs.size() + " mergedSyncs="
- + mMergedSyncSets.size());
- }
- return;
- }
-
- if (DEBUG) {
- Log.d(TAG, "Successfully finished sync id=" + mSyncId);
- }
-
- for (SyncTarget syncTarget : mSyncTargets) {
- syncTarget.onSyncComplete();
- }
- mSyncTargets.clear();
- mSyncRequestCompleteCallback.accept(mTransaction);
- mFinished = true;
- }
-
- /**
- * Add a Transaction to this sync set. This allows the caller to provide other info that
- * should be synced with the buffers.
- */
- void addTransactionToSync(Transaction t) {
- synchronized (mLock) {
- mTransaction.merge(t);
- }
- }
-
- public void updateCallback(Consumer<Transaction> transactionConsumer) {
- synchronized (mLock) {
- if (mFinished) {
- Log.e(TAG, "Attempting to merge SyncSet " + mSyncId + " when sync is"
- + " already complete");
- transactionConsumer.accept(new Transaction());
- }
-
- final Consumer<Transaction> oldCallback = mSyncRequestCompleteCallback;
- mSyncRequestCompleteCallback = transaction -> {
- oldCallback.accept(new Transaction());
- transactionConsumer.accept(transaction);
- };
- }
- }
-
- /**
- * Merge a SyncSet into this SyncSet. Since SyncSets could still have pending SyncTargets,
- * we need to make sure those can still complete before the mergeTo syncSet is considered
- * complete.
- *
- * We keep track of all the merged SyncSets until they are marked as done, and then they
- * are removed from the set. This SyncSet is not considered done until all the merged
- * SyncSets are done.
- *
- * When the merged SyncSet is complete, it will invoke the original syncRequestComplete
- * callback but send an empty transaction to ensure the changes are applied early. This
- * is needed in case the original sync is relying on the callback to continue processing.
- *
- * @param otherSyncSet The other SyncSet to merge into this one.
- */
- public void merge(SyncSet otherSyncSet) {
- synchronized (mLock) {
- mMergedSyncSets.add(otherSyncSet);
- }
- otherSyncSet.updateCallback(transaction -> {
- synchronized (mLock) {
- mMergedSyncSets.remove(otherSyncSet);
- mTransaction.merge(transaction);
- checkIfSyncIsComplete();
- }
- });
- }
- }
-
- /**
- * Wrapper class to help synchronize SurfaceViews
- */
- private static class SurfaceViewSyncTarget implements SyncTarget {
- private final SurfaceView mSurfaceView;
- private final Consumer<SurfaceViewFrameCallback> mFrameCallbackConsumer;
-
- SurfaceViewSyncTarget(SurfaceView surfaceView,
- Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) {
- mSurfaceView = surfaceView;
- mFrameCallbackConsumer = frameCallbackConsumer;
- }
-
- @Override
- public void onReadyToSync(SyncBufferCallback syncBufferCallback) {
- mFrameCallbackConsumer.accept(
- () -> mSurfaceView.syncNextFrame(syncBufferCallback::onBufferReady));
- }
- }
-
- /**
- * A frame callback that is used to synchronize SurfaceViews. The owner of the SurfaceView must
- * implement onFrameStarted when trying to sync the SurfaceView. This is to ensure the sync
- * knows when the frame is ready to add to the sync.
- */
- public interface SurfaceViewFrameCallback {
- /**
- * Called when the SurfaceView is going to render a frame
- */
- void onFrameStarted();
- }
-}
diff --git a/core/java/android/window/SurfaceSyncer.md b/core/java/android/window/SurfaceSyncer.md
deleted file mode 100644
index 1394bd1ad6ff..000000000000
--- a/core/java/android/window/SurfaceSyncer.md
+++ /dev/null
@@ -1,80 +0,0 @@
-## SurfaceSyncer
-
-### Overview
-
-A generic way for data to be gathered so multiple surfaces can be synced. This is intended to be used with Views, SurfaceView, and any other surface that wants to be involved in a sync. This allows different parts of the Android system to synchronize different windows and layers themselves without having to go through WindowManagerService
-
-### Code
-
-SurfaceSyncer is a class that manages sync requests and reports back when all participants in the sync are ready.
-
-##### setupSync
-The first step is to create a sync request. This is done by calling `setupSync`.
-There are two setupSync methods: one that accepts a `Runnable` and one that accepts a `Consumer<Transaction>`. The `setupSync(Runnable)` will automatically apply the final transaction and invokes the Runnable to notify the caller that the sync is complete. The `Runnable` can be null since not all cases care about the sync being complete. The second `setupSync(Consumer<Transaction>)` should only be used by ViewRootImpl. The purpose of this one is to allow the caller to get back the merged transaction without it being applied. ViewRootImpl uses it to send the transaction to WindowManagerService to be synced there. Using this one for other cases is unsafe because the caller may hold the transaction longer than expected and prevent buffers from being latched and released.
-
-The setupSync returns a syncId which is used for the other APIs
-
-##### markSyncReady
-
-When the caller has added all the `SyncTarget` to the sync, they should call `markSyncReady(syncId)` If the caller doesn't call this, the sync will never complete since the SurfaceSyncer wants to give the caller a chance to add all the SyncTargets before considering the sync ready. Before `markSyncReady` is called, the `SyncTargets` can actually produce a frame, which will just be held in a transaction until all other `SyncTargets` are ready AND `markSyncReady` has been called. Once markSyncReady has been called, you cannot add any more `SyncTargets` to that particular syncId.
-
-##### addToSync
-
-The caller will invoke `addToSync` for every `SyncTarget` that it wants included. The caller must specify which syncId they want to add the `SyncTarget` too since there can be multiple syncs open at the same time. There are a few helper methods since the most common cases are Views and SurfaceView
-* `addToSync(int syncId, View)` - This is used for syncing the root of the View, specificially the ViewRootImpl
-* `addToSync(int syncId, SurfaceView, Consumer<SurfaceViewFrameCallback>)` - This is to sync a SurfaceView. Since SurfaceViews are rendered by the app, the caller will be expected to provide a way to get back the buffer to sync. More details about that [below](#surfaceviewframecallback)
-* `addToSync(int syncId, SyncTarget)` - This is the generic method. It can be used to sync arbitrary info. The SyncTarget interface has required methods that need to be implemented to properly get the transaction to sync.
-
-When calling addToSync with either View or SurfaceView, it must occur on the UI Thread. This is to ensure consistent behavior, where any UI changes done while still on the UI thread are included in this frame. The next vsync will pick up those changes and request to draw.
-
-##### addTransactionToSync
-
-This is a simple method that allows callers to add generic Transactions to the sync. The caller invokes `addTransactionToSync(int syncId, Transaction)`. This can be used for things that need to be synced with content, but aren't updating content themselves.
-
-##### SyncTarget
-
-This interface is used to handle syncs. The interface has two methods
-* `onReadyToSync(SyncBufferCallback)` - This one must be implemented. The sync will notify the `SyncTarget` so it can invoke the `SyncBufferCallback`, letting the sync know when it's ready.
-* `onSyncComplete()` - This method is optional. It's used to notify the `SyncTarget` that the entire sync is complete. This is similar to the callback sent in `setupSync`, but it's invoked to the `SyncTargets` rather than the caller who started the sync. This is used by ViewRootImpl to restore the state when the entire sync is done
-
-When syncing ViewRootImpl, these methods are implemented already since ViewRootImpl handles the rendering requests and timing.
-
-##### SyncBufferCallback
-
-This interface is used to tell the sync that this SyncTarget is ready. There's only method here, `onBufferReady(Transaction)`, that sends back the transaction that contains the data to be synced, normally with a buffer.
-
-##### SurfaceViewFrameCallback
-
-As mentioned above, SurfaceViews are a special case because the buffers produced are handled by the app, and not the framework. Because of this, the syncer doesn't know which frame to sync. Therefore, to sync SurfaceViews, the caller must provide a way to notify the syncer that it's going to render a buffer and that this next buffer is the one to sync. The `SurfaceViewFrameCallback` has one method `onFrameStarted()`. When this is invoked, the Syncer sets up a request to sync the next buffer for the SurfaceView.
-
-
-### Example
-
-A simple example where you want to sync two windows and also include a transaction in the sync
-
-```java
-SurfaceSyncer syncer = new SurfaceSyncer();
-int syncId = syncer.setupSync(() -> {
- Log.d(TAG, "syncComplete");
-};
-syncer.addToSync(syncId, view1);
-syncer.addToSync(syncId, view2);
-syncer.addTransactionToSync(syncId, transaction);
-syncer.markSyncReady(syncId);
-```
-
-A SurfaceView example:
-See `frameworks/base/tests/SurfaceViewSyncTest` for a working example
-
-```java
-SurfaceSyncer syncer = new SurfaceSyncer();
-int syncId = syncer.setupSync(() -> {
- Log.d(TAG, "syncComplete");
-};
-syncer.addToSync(syncId, container);
-syncer.addToSync(syncId, surfaceView, frameCallback -> {
- // Call this when the SurfaceView is ready to render a new frame with the changes.
- frameCallback.onFrameStarted()
-}
-syncer.markSyncReady(syncId);
-``` \ No newline at end of file
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 68c934f6f0a6..765cd8163cb3 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -18,6 +18,7 @@ package android.window;
import android.annotation.CallSuper;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.TestApi;
import android.content.Intent;
import android.content.res.Configuration;
@@ -39,16 +40,23 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
* Key to the exception in {@link Bundle} in {@link ITaskFragmentOrganizer#onTaskFragmentError}.
*/
private static final String KEY_ERROR_CALLBACK_EXCEPTION = "fragment_exception";
+ private static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info";
+ private static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type";
/**
- * Creates a {@link Bundle} with an exception that can be passed to
- * {@link ITaskFragmentOrganizer#onTaskFragmentError}.
+ * Creates a {@link Bundle} with an exception, operation type and TaskFragmentInfo (if any)
+ * that can be passed to {@link ITaskFragmentOrganizer#onTaskFragmentError}.
* @hide
*/
- public static Bundle putExceptionInBundle(@NonNull Throwable exception) {
- final Bundle exceptionBundle = new Bundle();
- exceptionBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception);
- return exceptionBundle;
+ public static @NonNull Bundle putErrorInfoInBundle(@NonNull Throwable exception,
+ @Nullable TaskFragmentInfo info, int opType) {
+ final Bundle errorBundle = new Bundle();
+ errorBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception);
+ if (info != null) {
+ errorBundle.putParcelable(KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, info);
+ }
+ errorBundle.putInt(KEY_ERROR_CALLBACK_OP_TYPE, opType);
+ return errorBundle;
}
/**
@@ -150,10 +158,15 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
*
* @param errorCallbackToken token set in
* {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)}
+ * @param taskFragmentInfo The {@link TaskFragmentInfo}. This could be {@code null} if no
+ * TaskFragment created.
+ * @param opType The {@link WindowContainerTransaction.HierarchyOp} of the failed
+ * transaction operation.
* @param exception exception from the server side.
*/
public void onTaskFragmentError(
- @NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {}
+ @NonNull IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo,
+ int opType, @NonNull Throwable exception) {}
/**
* Called when an Activity is reparented to the Task with organized TaskFragment. For example,
@@ -217,10 +230,16 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
@Override
public void onTaskFragmentError(
- @NonNull IBinder errorCallbackToken, @NonNull Bundle exceptionBundle) {
- mExecutor.execute(() -> TaskFragmentOrganizer.this.onTaskFragmentError(
- errorCallbackToken,
- (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION, java.lang.Throwable.class)));
+ @NonNull IBinder errorCallbackToken, @NonNull Bundle errorBundle) {
+ mExecutor.execute(() -> {
+ final TaskFragmentInfo info = errorBundle.getParcelable(
+ KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, TaskFragmentInfo.class);
+ TaskFragmentOrganizer.this.onTaskFragmentError(
+ errorCallbackToken, info,
+ errorBundle.getInt(KEY_ERROR_CALLBACK_OP_TYPE),
+ (Throwable) errorBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION,
+ java.lang.Throwable.class));
+ });
}
@Override
diff --git a/core/java/com/android/internal/app/procstats/IProcessStats.aidl b/core/java/com/android/internal/app/procstats/IProcessStats.aidl
index a2eca3aee13d..84b2a354020f 100644
--- a/core/java/com/android/internal/app/procstats/IProcessStats.aidl
+++ b/core/java/com/android/internal/app/procstats/IProcessStats.aidl
@@ -21,7 +21,9 @@ import android.os.ParcelFileDescriptor;
import com.android.internal.app.procstats.ProcessStats;
interface IProcessStats {
+ @EnforcePermission("PACKAGE_USAGE_STATS")
byte[] getCurrentStats(out List<ParcelFileDescriptor> historic);
+ @EnforcePermission("PACKAGE_USAGE_STATS")
ParcelFileDescriptor getStatsOverTime(long minTime);
int getCurrentMemoryState();
@@ -43,6 +45,7 @@ interface IProcessStats {
* @param List of Files of individual commits in protobuf binary or one that is merged from them.
* @param ProcessStats object that will be used to return the full set of merged stats.
*/
+ @EnforcePermission("PACKAGE_USAGE_STATS")
long getCommittedStatsMerged(long highWaterMarkMs, int section, boolean doAggregate,
out List<ParcelFileDescriptor> committedStats, out ProcessStats mergedStats);
diff --git a/core/java/com/android/internal/inputmethod/ImeTracing.java b/core/java/com/android/internal/inputmethod/ImeTracing.java
index 8b21b7ef10ea..ee6713118f75 100644
--- a/core/java/com/android/internal/inputmethod/ImeTracing.java
+++ b/core/java/com/android/internal/inputmethod/ImeTracing.java
@@ -17,6 +17,7 @@
package com.android.internal.inputmethod;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.app.ActivityThread;
import android.content.Context;
import android.os.RemoteException;
@@ -93,6 +94,7 @@ public abstract class ImeTracing {
/**
* Calling {@link IInputMethodManager#startImeTrace()}} to capture IME trace.
*/
+ @RequiresPermission(android.Manifest.permission.CONTROL_UI_TRACING)
public final void startImeTrace() {
try {
mService.startImeTrace();
@@ -104,6 +106,7 @@ public abstract class ImeTracing {
/**
* Calling {@link IInputMethodManager#stopImeTrace()} to stop IME trace.
*/
+ @RequiresPermission(android.Manifest.permission.CONTROL_UI_TRACING)
public final void stopImeTrace() {
try {
mService.stopImeTrace();
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 9e0b2495969e..d5f835295ee7 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -45,9 +45,14 @@ interface IInputMethodManager {
+ "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
List<InputMethodInfo> getEnabledInputMethodList(int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in @nullable String imiId,
- boolean allowsImplicitlySelectedSubtypes);
- @nullable InputMethodSubtype getLastInputMethodSubtype();
+ boolean allowsImplicitlySelectedSubtypes, int userId);
+
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
+ InputMethodSubtype getLastInputMethodSubtype(int userId);
boolean showSoftInput(in IInputMethodClient client, @nullable IBinder windowToken, int flags,
in @nullable ResultReceiver resultReceiver, int reason);
@@ -67,7 +72,8 @@ interface IInputMethodManager {
/* @android.view.WindowManager.LayoutParams.Flags */ int windowFlags,
in @nullable EditorInfo editorInfo, in @nullable IRemoteInputConnection inputConnection,
in @nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion, in ImeOnBackInvokedDispatcher imeDispatcher);
+ int unverifiedTargetSdkVersion, int userId,
+ in ImeOnBackInvokedDispatcher imeDispatcher);
void showInputMethodPickerFromClient(in IInputMethodClient client,
int auxiliarySubtypeMode);
@@ -82,7 +88,10 @@ interface IInputMethodManager {
+ "android.Manifest.permission.TEST_INPUT_METHOD)")
boolean isInputMethodPickerShownForTest();
- @nullable InputMethodSubtype getCurrentInputMethodSubtype();
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
+ @nullable InputMethodSubtype getCurrentInputMethodSubtype(int userId);
+
void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
// This is kept due to @UnsupportedAppUsage.
// TODO(Bug 113914148): Consider removing this.
@@ -100,12 +109,22 @@ interface IInputMethodManager {
/** Remove the IME surface. Requires passing the currently focused window. */
oneway void removeImeSurfaceFromWindowAsync(in IBinder windowToken);
+
+ @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
void startProtoDump(in byte[] protoDump, int source, String where);
+
boolean isImeTraceEnabled();
// Starts an ime trace.
+ @EnforcePermission("CONTROL_UI_TRACING")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.CONTROL_UI_TRACING)")
void startImeTrace();
+
// Stops an ime trace.
+ @EnforcePermission("CONTROL_UI_TRACING")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.CONTROL_UI_TRACING)")
void stopImeTrace();
/** Start Stylus handwriting session **/
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 24a3c16fb0d3..cc076ab95ebe 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -170,7 +170,7 @@ public class LockPatternUtils {
public static final String PROFILE_KEY_NAME_DECRYPT = "profile_key_name_decrypt_";
public static final String SYNTHETIC_PASSWORD_KEY_PREFIX = "synthetic_password_";
- public static final String SYNTHETIC_PASSWORD_HANDLE_KEY = "sp-handle";
+ public static final String CURRENT_LSKF_BASED_PROTECTOR_ID_KEY = "sp-handle";
public static final String PASSWORD_HISTORY_DELIMITER = ",";
@UnsupportedAppUsage
diff --git a/core/java/com/android/internal/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java
index 1074004b4c33..40164a45516e 100644
--- a/core/java/com/android/internal/widget/LockscreenCredential.java
+++ b/core/java/com/android/internal/widget/LockscreenCredential.java
@@ -40,8 +40,8 @@ import java.util.List;
import java.util.Objects;
/**
- * A class representing a lockscreen credential. It can be either an empty password, a pattern
- * or a password (or PIN).
+ * A class representing a lockscreen credential, also called a Lock Screen Knowledge Factor (LSKF).
+ * It can be a PIN, pattern, password, or none (a.k.a. empty).
*
* <p> As required by some security certification, the framework tries its best to
* remove copies of the lockscreen credential bytes from memory. In this regard, this class
@@ -52,10 +52,10 @@ import java.util.Objects;
* // Process the credential in some way
* }
* </pre>
- * With this construct, we can guarantee that there will be no copies of the password left in
- * memory when the credential goes out of scope. This should help mitigate certain class of
- * attacks where the attcker gains read-only access to full device memory (cold boot attack,
- * unsecured software/hardware memory dumping interfaces such as JTAG).
+ * With this construct, we can guarantee that there will be no copies of the credential left in
+ * memory when the object goes out of scope. This should help mitigate certain class of attacks
+ * where the attacker gains read-only access to full device memory (cold boot attack, unsecured
+ * software/hardware memory dumping interfaces such as JTAG).
*/
public class LockscreenCredential implements Parcelable, AutoCloseable {
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 6a421f007a76..285258a979e4 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -473,6 +473,13 @@ message SecureSettingsProto {
}
optional PowerMenuPrivacy power_menu_privacy = 81;
+ message ExtraLowPowerMode {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto extra_automatic_power_save_mode = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional ExtraLowPowerMode extra_low_power_mode = 93;
+
message PrintService {
option (android.msg_privacy).dest = DEST_EXPLICIT;
@@ -679,5 +686,5 @@ message SecureSettingsProto {
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 93;
+ // Next tag = 94;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 66394dbd1173..3fbd7973d81f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6542,6 +6542,12 @@
<permission android:name="android.permission.MAKE_UID_VISIBLE"
android:protectionLevel="signature" />
+ <!-- Limits the system as the only handler of the QUERY_PACKAGE_RESTART broadcast
+ @hide -->
+ <permission android:name="android.permission.HANDLE_QUERY_PACKAGE_RESTART"
+ android:protectionLevel="signature" />
+ <uses-permission android:name="android.permission.HANDLE_QUERY_PACKAGE_RESTART" />
+
<!-- Attribution for Geofencing service. -->
<attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
<!-- Attribution for Country Detector. -->
@@ -7081,6 +7087,10 @@
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
+ <service android:name="com.android.server.notification.NotificationHistoryJobService"
+ android:permission="android.permission.BIND_JOB_SERVICE" >
+ </service>
+
<service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader"
android:exported="false">
<intent-filter>
diff --git a/core/res/res/layout/transient_notification_with_icon.xml b/core/res/res/layout/transient_notification_with_icon.xml
new file mode 100644
index 000000000000..e9b17df75333
--- /dev/null
+++ b/core/res/res/layout/transient_notification_with_icon.xml
@@ -0,0 +1,46 @@
+<?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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:maxWidth="@dimen/toast_width"
+ android:background="?android:attr/toastFrameBackground"
+ android:elevation="@dimen/toast_elevation"
+ android:layout_marginEnd="16dp"
+ android:layout_marginStart="16dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp">
+
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:id="@android:id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:maxLines="2"
+ android:paddingTop="12dp"
+ android:paddingBottom="12dp"
+ android:textAppearance="@style/TextAppearance.Toast"/>
+</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index e9381e04b02a..110cde337d06 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan nie vingerafdruksensor gebruik nie. Besoek \'n verskaffer wat herstelwerk doen"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gebruik vingerafdruk"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gebruik vingerafdruk of skermslot"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan nie toegang tot die foon se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan nie toegang tot die tablet se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string>
<string name="system_locale_title" msgid="711882686834677268">"Stelselverstek"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 78f383c2f9f8..9f3a28b99856 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"የጣት አሻራ ዳሳሽን መጠቀም አይቻልም። የጥገና አገልግሎት ሰጪን ይጎብኙ"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"የሥርዓት ነባሪ"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ካርድ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 5d25ba402992..f0d7af34973e 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -615,6 +615,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"لا يمكن استخدام أداة استشعار بصمة الإصبع. يُرجى التواصل مع مقدِّم خدمات إصلاح."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
@@ -2290,6 +2292,5 @@
<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="711882686834677268">"الإعداد التلقائي للنظام"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"‏رقم البطاقة ‎<xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 39647251b41f..d6393e993578 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ ব্যৱহাৰ কৰিব নোৱাৰি। মেৰামতি সেৱা প্ৰদানকাৰী কোনো প্ৰতিষ্ঠানলৈ যাওক"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"ছিষ্টেম ডিফ’ল্ট"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"কাৰ্ড <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index c41f4d7b3488..2e80e87235ab 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Barmaq izi sensorundan istifadə etmək mümkün deyil. Təmir provayderini ziyarət edin"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izini istifadə edin"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına giriş etmək olmur"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan planşetin kamerasına giriş etmək olmur"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistem defoltu"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 9bc0a9123071..1a4045074ccf 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -612,6 +612,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ne možete da koristite senzor za otisak prsta. Posetite dobavljača za popravke"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
@@ -2287,6 +2289,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ne može da se pristupi kameri telefona sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ne može da se pristupi kameri tableta sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
<string name="system_locale_title" msgid="711882686834677268">"Podrazumevani sistemski"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 34bbb0ef2c97..34774009aa68 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не ўдалося скарыстаць сканер адбіткаў пальцаў. Звярніцеся ў сэрвісны цэнтр."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
@@ -2288,6 +2290,5 @@
<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="711882686834677268">"Стандартная сістэмная налада"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 575e3471dbb9..89ffe401bc0a 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Сензорът за отпечатъци не може да се използва. Посетете оторизиран сервиз."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Използване на отпечатък или опцията за заключване на екрана"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Стандартно за системата"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 45935fafe3ca..088285343ca5 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"আঙ্গুলের ছাপের সেন্সর ব্যবহার করা যাচ্ছে না। একজন মেরামতি মিস্ত্রির কাছে যান"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"আঙ্গুলের ছাপ ব্যবহার করুন"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"আঙ্গুলের ছাপ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"সিস্টেম ডিফল্ট"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"কার্ড <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0b8d3d3f5d8a..96b17fb75842 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -612,6 +612,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nije moguće koristiti senzor za otisak prsta. Posjetite pružaoca usluga za popravke"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristi otisak prsta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristi otisak prsta ili zaključavanje ekrana"</string>
@@ -2287,6 +2289,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nije moguće pristupiti kameri telefona s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nije moguće pristupiti kameri tableta s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistemski zadano"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c595ee195786..999eb2d9a497 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes digitals."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No es pot utilitzar el sensor d\'empremtes digitals. Visita un proveïdor de reparacions."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilitza l\'empremta digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilitza l\'empremta digital o el bloqueig de pantalla"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No es pot accedir a la càmera del telèfon des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No es pot accedir a la càmera de la tauleta des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Valor predeterminat del sistema"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"TARGETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index cf7fc26b0167..95ce5a813184 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Snímač otisků prstů nelze použít. Navštivte servis"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použít otisk prstu"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použít otisk prstu nebo zámek obrazovky"</string>
@@ -2288,6 +2290,5 @@
<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="711882686834677268">"Výchozí nastavení systému"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 749b5e8a2bae..b8fd910e9215 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Fingeraftrykslæseren kan ikke bruges. Få den repareret"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Brug fingeraftryk"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Brug fingeraftryk eller skærmlås"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kameraet på din telefon kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kameraet på din tablet kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Systemstandard"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 875964087668..f1d30c3da02a 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Der Fingerabdrucksensor kann nicht verwendet werden. Suche einen Reparaturdienstleister auf."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Fingerabdruck oder Displaysperre verwenden"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Zugriff auf die Kamera des Smartphones über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Zugriff auf die Kamera des Tablets über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string>
<string name="system_locale_title" msgid="711882686834677268">"Standardeinstellung des Systems"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 7f8160c8f476..c274a184437a 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Δεν είναι δυνατή η χρήση του αισθητήρα δακτυλικών αποτυπωμάτων. Επισκεφτείτε έναν πάροχο υπηρεσιών επισκευής."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Χρήση δακτυλικού αποτυπώματος ή κλειδώματος οθόνης"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Προεπιλογή συστήματος"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ΚΑΡΤΑ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 138bb3ba0894..bc376e11da5a 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"System default"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 1972db35390d..b9109c3dc19a 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"System default"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bb3a9d17ef9c..88740daffed7 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"System default"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 526b0d5fd5f9..39c4da2d4c43 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"System default"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index daa0685f46a2..da5582598afa 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎This device does not have a fingerprint sensor.‎‏‎‎‏‎"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎Sensor temporarily disabled.‎‏‎‎‏‎"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎Can’t use fingerprint sensor. Visit a repair provider‎‏‎‎‏‎"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎Finger ‎‏‎‎‏‏‎<xliff:g id="FINGERID">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎Use fingerprint‎‏‎‎‏‎"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎Use fingerprint or screen lock‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 2b46223c5abb..a13392c090ef 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas dactilares."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No se puede usar el sensor de huellas dactilares. Consulta a un proveedor de reparaciones."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella dactilar"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar bloqueo de huella dactilar o pantalla"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del dispositivo desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara de la tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predeterminado del sistema"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"TARJETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a71491b3e0f3..788bbbcd2415 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No se puede usar el sensor de huellas digitales. Visita un proveedor de reparaciones."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar huella digital o bloqueo de pantalla"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del teléfono desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara del tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predeterminado del sistema"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"TARJETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 6e00da736f2c..f1dc2811d9bf 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sõrmejäljeandurit ei saa kasutada. Külastage remonditeenuse pakkujat"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sõrmejälje kasutamine"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sõrmejälje või ekraaniluku kasutamine"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse telefoni kaamerale juurde"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tahvelarvuti kaamerale juurde"</string>
<string name="system_locale_title" msgid="711882686834677268">"Süsteemi vaikeseade"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 9ec55253940a..0469caace050 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ezin da erabili hatz-marken sentsorea. Jarri harremanetan konponketak egiten dituen hornitzaile batekin."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. hatza"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
@@ -620,7 +622,7 @@
</string-array>
<string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Arazo bat izan da. Saiatu berriro."</string>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Hatz-markaren ikonoa"</string>
- <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Aurpegi bidez desblokeatzeko eginbidea"</string>
+ <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Aurpegi bidez desblokeatzea"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Arazoak ditugu aurpegi bidez desblokeatzeko eginbidearekin"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Sakatu hau aurpegi-eredua ezabatzeko eta, gero, gehitu aurpegia berriro"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"Konfiguratu aurpegi bidez desblokeatzeko eginbidea"</string>
@@ -990,7 +992,7 @@
<string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Zabaldu desblokeatzeko eremua."</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Hatza lerratuta desblokeatzea."</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Ereduaren bidez desblokeatzea."</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Aurpegi bidez desblokeatzeko eginbidea."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Aurpegi bidez desblokeatzea."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"PIN kodearen bidez desblokeatzea."</string>
<string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIMa desblokeatzeko PINa."</string>
<string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM txartela desblokeatzeko PUK kodea."</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ezin da atzitu telefonoaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ezin da atzitu tabletaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistemaren balio lehenetsia"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g> TXARTELA"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 8aa014b22682..758228042e7a 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر به‌طور موقت غیرفعال است."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"امکان استفاده از حسگر اثر انگشت وجود ندارد. به ارائه‌دهنده خدمات تعمیر مراجعه کنید"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استفاده از اثر انگشت یا قفل صفحه"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"پیش‌فرض سیستم"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"کارت <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8e65d49e81f0..36eb2e0d6218 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sormenjälkitunnistinta ei voi käyttää. Ota yhteys korjauspalveluun"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Käytä sormenjälkeä"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Käytä sormenjälkeä tai näytön lukitusta"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse puhelimen kameraan"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tabletin kameraan"</string>
<string name="system_locale_title" msgid="711882686834677268">"Järjestelmän oletusarvo"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"Kortti: <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2240a91164ac..a84eebb0d51e 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Le capteur a été désactivé temporairement."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossible d\'utiliser le capteur d\'empreintes digitales. Consultez un fournisseur de services de réparation"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser l\'empreinte digitale ou le verrouillage de l\'écran"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 2b1421961925..0bc5e747bf0d 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossible d\'utiliser le lecteur d\'empreinte digitale. Contactez un réparateur"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 52c26cad1a80..4663e0b302bb 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Non se puido usar o sensor de impresión dixital. Visita un provedor de reparacións"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar impresión dixital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar impresión dixital ou credencial do dispositivo"</string>
@@ -2085,7 +2087,7 @@
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"A tableta non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
<string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"O dispositivo non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
<string name="mime_type_folder" msgid="2203536499348787650">"Cartafol"</string>
- <string name="mime_type_apk" msgid="3168784749499623902">"Aplicación Android"</string>
+ <string name="mime_type_apk" msgid="3168784749499623902">"Aplicación para Android"</string>
<string name="mime_type_generic" msgid="4606589110116560228">"Ficheiro"</string>
<string name="mime_type_generic_ext" msgid="9220220924380909486">"Ficheiro <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
<string name="mime_type_audio" msgid="4933450584432509875">"Audio"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Non se puido acceder á cámara do teléfono desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Non se puido acceder á cámara da tableta desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string>
<string name="system_locale_title" msgid="711882686834677268">"Opción predeterminada do sistema"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"TARXETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 713e33f0c2e7..6a28ef155b62 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ફિંગરપ્રિન્ટ સેન્સરનો ઉપયોગ કરી શકાતો નથી. રિપેર કરવાની સેવા આપતા પ્રદાતાની મુલાકાત લો"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ફિંગરપ્રિન્ટ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"સિસ્ટમ ડિફૉલ્ટ"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"કાર્ડ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index ddf0aa7f3f5c..4fa162449dc5 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फ़िंगरप्रिंट सेंसर इस्तेमाल नहीं किया जा सकता. रिपेयर की सेवा देने वाली कंपनी से संपर्क करें"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
@@ -638,8 +640,8 @@
<string name="face_acquired_too_far" msgid="2922278214231064859">"फ़ोन को नज़दीक लाएं"</string>
<string name="face_acquired_too_high" msgid="8278815780046368576">"फ़ोन को थोड़ा और ऊपर ले जाएं"</string>
<string name="face_acquired_too_low" msgid="4075391872960840081">"फ़ोन को थोड़ा नीचे ले जाएं"</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"फ़ोन को अपनी बाईं ओर ले जाएं"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"फ़ोन को अपनी दाईं ओर ले जाएं"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"फ़ोन को अपने बाईं ओर ले जाएं"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"फ़ोन को अपने दाईं ओर ले जाएं"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"कृपया अपने डिवाइस की तरफ़ सीधे देखें."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"आपका चेहरा नहीं दिख रहा है. फ़ोन को अपनी आंखों की सीध में पकड़कर रखें."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"डिवाइस बहुत ज़्यादा हिल रहा है. फ़ोन को बिना हिलाएं पकड़ें."</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"सिस्टम डिफ़ॉल्ट"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 48aece52c6f9..3b6a61cee131 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -612,6 +612,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Senzor otiska prsta ne može se koristiti. Posjetite davatelja usluga popravaka"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Upotreba otiska prsta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Upotreba otiska prsta ili zaključavanja zaslona"</string>
@@ -2287,6 +2289,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu telefona"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu tableta"</string>
<string name="system_locale_title" msgid="711882686834677268">"Zadane postavke sustava"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f752b82d35d3..32c734caf6aa 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nem lehet használni az ujjlenyomat-érzékelőt. Keresse fel a szervizt."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Ujjlenyomat használata"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"A folytatás ujjlenyomattal vagy képernyőzárral lehetséges"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nem lehet hozzáférni a telefon kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nem lehet hozzáférni a táblagép kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Rendszerbeállítás"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KÁRTYA: <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index e162499affbe..c69f4675e7b3 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Մատնահետքերի սկաները հնարավոր չէ օգտագործել։ Այցելեք սպասարկման կենտրոն։"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Օգտագործել մատնահետք կամ էկրանի կողպում"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Կանխադրված"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ՔԱՐՏ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 38861088dcd7..6ada18041e98 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tidak dapat menggunakan sensor sidik jari. Kunjungi penyedia reparasi"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan sidik jari"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan sidik jari atau kunci layar"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera ponsel dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Default sistem"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTU <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 62a30c79924d..6bf2f548d486 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ekki er hægt að nota fingrafaralesara. Þú verður að fara með hann á verkstæði"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Nota fingrafar"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Nota fingrafar eða skjálás"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ekki er hægt að opna myndavél símans úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ekki er hægt að opna myndavél spjaldtölvunnar úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sjálfgildi kerfis"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index bf320c9fbc36..8c004959e35c 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossibile usare il sensore di impronte digitali. Contatta un fornitore di servizi di riparazione"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usa l\'impronta o il blocco schermo"</string>
@@ -638,8 +640,8 @@
<string name="face_acquired_too_far" msgid="2922278214231064859">"Avvicina il telefono"</string>
<string name="face_acquired_too_high" msgid="8278815780046368576">"Sposta il telefono più in alto"</string>
<string name="face_acquired_too_low" msgid="4075391872960840081">"Sposta il telefono più in basso"</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta il telefono alla tua sinistra"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta il telefono alla tua destra"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta il telefono verso sinistra"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta il telefono verso destra"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Guarda più direttamente verso il dispositivo."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"Impossibile vedere il volto. Tieni il telefono all\'altezza degli occhi."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Troppo movimento. Tieni fermo il telefono."</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossibile accedere alla fotocamera del telefono dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossibile accedere alla fotocamera del tablet dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predefinita di sistema"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"SCHEDA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1e12b1140488..5afe502070ae 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"לא ניתן להשתמש בחיישן טביעות האצבע. צריך ליצור קשר עם ספק תיקונים"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
@@ -2288,6 +2290,5 @@
<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="711882686834677268">"ברירת המחדל של המערכת"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"כרטיס <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6bbf5b48b4e9..404a18a41b04 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋認証センサーを使用できません。修理業者に調整を依頼してください"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"指紋または画面ロックの使用"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"システムのデフォルト"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"カード <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 508cc42b21fa..5793ed7f6e81 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"თითის ანაბეჭდის სენსორის გამოყენება ვერ ხერხდება. ეწვიეთ შეკეთების სერვისის პროვაიდერს"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"სისტემის ნაგულისხმევი"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ბარათი <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index e43fc2e2c859..69a198820376 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Саусақ ізін оқу сканерін пайдалану мүмкін емес. Жөндеу қызметіне барыңыз."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-саусақ"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Жүйенің әдепкі параметрі"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g>-КАРТА"</string>
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 08ec6e8d8afb..72cd81720b47 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះ​មិនមាន​ឧបករណ៍ចាប់​ស្នាមម្រាមដៃទេ។"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"មិនអាចប្រើ​ឧបករណ៍ចាប់ស្នាមម្រាមដៃ​បានទេ។ សូមទាក់ទង​ក្រុមហ៊ុនផ្ដល់​ការជួសជុល"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬ​ការចាក់សោអេក្រង់"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"លំនាំ​ដើម​ប្រព័ន្ធ"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"កាត <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index e6e7f0799fb7..1f1950e5e216 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ರಿಪೇರಿ ಮಾಡುವವರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
@@ -636,7 +638,7 @@
<string name="face_acquired_too_dark" msgid="7919016380747701228">"ಪ್ರಕಾಶಮಾನವಾದ ಲೈಟಿಂಗ್ ಬಳಸಿ"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"ಫೋನ್ ಅನ್ನು ದೂರಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"ಫೋನ್ ಅನ್ನು ಸಮೀಪಕ್ಕೆ ತನ್ನಿ"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"ಫೋನ್ ಅನ್ನು ಎತ್ತರಕ್ಕೆ ಹಿಡಿಯಿರಿ"</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"ಫೋನ್ ಅನ್ನು ಮೇಲಕ್ಕೆ ಎತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
<string name="face_acquired_too_low" msgid="4075391872960840081">"ಫೋನ್ ಅನ್ನು ಕೆಳಗೆ ಸರಿಸಿ"</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"ಫೋನ್ ಅನ್ನು ನಿಮ್ಮ ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"ಫೋನ್ ಅನ್ನು ನಿಮ್ಮ ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
@@ -1357,8 +1359,8 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"ಸಂಪರ್ಕಗೊಂಡಿರುವ ಸಾಧನವನ್ನು ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ. ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ಅನ್‌ಲಾಗ್ ಆಡಿಯೋ ಪರಿಕರ ಪತ್ತೆಯಾಗಿದೆ"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"USB ಡೀಬಗಿಂಗ್‌ ಕನೆಕ್ಟ್‌ ಆಗಿದೆ"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ಡೀಬಗಿಂಗ್ ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಕನೆಕ್ಟ್‌ ಆಗಿದೆ"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"ಸಿಸ್ಟಂ ಡೀಫಾಲ್ಟ್"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ಕಾರ್ಡ್ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 43d808037e9c..fc80ec044a2d 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"지문 센서를 사용할 수 없습니다. 수리업체에 방문하세요."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"지문 또는 화면 잠금 사용"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"시스템 기본값"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g> 카드"</string>
</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 8ce3f1311938..70beacb03642 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Манжа изинин сенсорун колдонууга болбойт. Тейлөө кызматына кайрылыңыз"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
@@ -623,7 +625,7 @@
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Жүзүнөн таанып ачуу"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Жүзүнөн таанып ачуу функциясында маселе келип чыкты"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Жүзүңүздүн үлгүсүн өчүрүү үчүн басып, жаңы үлгүнү кошуңуз"</string>
- <string name="face_setup_notification_title" msgid="8843461561970741790">"Жүзүнөн таанып ачууну жөндөө"</string>
+ <string name="face_setup_notification_title" msgid="8843461561970741790">"Жүзүнөн таанып ачууну тууралоо"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"Телефонуңузду карап туруп эле кулпусун ачып алыңыз"</string>
<string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Жүзүнөн таанып ачуу функциясын колдонуу үчүн Жөндөөлөр &gt; Купуялык бөлүмүнө өтүп, "<b>"Камераны колдонууну"</b>" күйгүзүңүз"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Кулпусун ачуунун көбүрөөк жолдорун жөндөңүз"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Системанын демейки параметрлери"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 197b4b3d6e3d..243662747407 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ບໍ່ສາມາດໃຊ້ເຊັນ​ເຊີລາຍນິ້ວ​ມືໄດ້. ກະລຸນາໄປຫາຜູ້ໃຫ້ບໍລິການສ້ອມແປງ"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວ​ມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍ"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"ຄ່າເລີ່ມຕົ້ນຂອງລະບົບ"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ບັດ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index a6408977f618..641b4da1aa32 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Negalima naudoti kontrolinio kodo jutiklio. Apsilankykite pas taisymo paslaugos teikėją"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Naudoti kontrolinį kodą"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Naudoti kontrolinį kodą arba ekrano užraktą"</string>
@@ -2288,6 +2290,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nepavyko pasiekti telefono fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nepavyko pasiekti planšetinio kompiuterio fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string>
<string name="system_locale_title" msgid="711882686834677268">"Numatytoji sistemos vertė"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KORTELĖ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 7612ea5f6edd..3adf1337c5bc 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -612,6 +612,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nevar izmantot pirksta nospieduma sensoru. Sazinieties ar remonta pakalpojumu sniedzēju."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Pirksta nospieduma izmantošana"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Pirksta nospieduma vai ekrāna bloķēšanas metodes izmantošana"</string>
@@ -2287,6 +2289,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nevar piekļūt tālruņa kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nevar piekļūt planšetdatora kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistēmas noklusējums"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-mcc334-mnc020-pa/strings.xml b/core/res/res/values-mcc334-mnc020-pa/strings.xml
index 3cf6bc88e70e..23f77d88ab72 100644
--- a/core/res/res/values-mcc334-mnc020-pa/strings.xml
+++ b/core/res/res/values-mcc334-mnc020-pa/strings.xml
@@ -21,6 +21,6 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="config_pdp_reject_dialog_title" msgid="41208110171880430"></string>
<string name="config_pdp_reject_user_authentication_failed" msgid="4683454131283459978">"ਪ੍ਰਮਾਣੀਕਰਨ ਅਸਫਲ -29-"</string>
- <string name="config_pdp_reject_service_not_subscribed" msgid="9021140729932308119">"ਸੇਵਾ ਦੀ ਗਾਹਕੀ ਨਹੀਂ ਲਈ -33-"</string>
+ <string name="config_pdp_reject_service_not_subscribed" msgid="9021140729932308119">"ਸੇਵਾ ਨੂੰ ਸਬਸਕ੍ਰਾਈਬ ਨਹੀਂ ਕੀਤਾ -33-"</string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="3838388706348367865">"ਕਿਸੇ ਵੀ APN ਲਈ ਇੱਕ ਤੋਂ ਵੱਧ PDN ਕਨੈਕਸ਼ਨਾਂ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ -55-"</string>
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 15d10223f6de..a93be126cd8e 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не може да се користи сензорот за отпечатоци. Однесете го на поправка"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користи отпечаток или заклучување екран"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Стандардно за системот"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"КАРТИЧКА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 8365de4ecd0f..67d6e67562fb 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"വിരലടയാള സെൻസർ ഉപയോഗിക്കാനാകുന്നില്ല. റിപ്പയർ കേന്ദ്രം സന്ദർശിക്കുക"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ഫിംഗർ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ഫിംഗർപ്രിന്റ് അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"സിസ്‌റ്റം ഡിഫോൾട്ട്"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"കാർഡ് <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 2826b5d6bcdb..e36dd5648059 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Хурууны хээ мэдрэгч ашиглах боломжгүй. Засварын үйлчилгээ үзүүлэгчид зочилно уу"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Хурууны хээ эсвэл дэлгэцийн түгжээ ашиглах"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Системийн өгөгдмөл"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"КАРТ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index c54325c7cbaf..894c264a70b6 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिंट सेन्सर वापरू शकत नाही. दुरुस्तीच्या सेवा पुरवठादाराला भेट द्या"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिंट वापरा"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिंट किंवा स्क्रीन लॉक वापरा"</string>
@@ -649,7 +651,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"तुमच्या फोनकडे आणखी थेट पहा"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"तुमच्या फोनकडे आणखी थेट पहा"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"तुमच्या फोनकडे आणखी थेट पहा"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"तुमचा चहेरा लपवणारे काहीही काढून टाका."</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"तुमचा चेहरा लपवणारे काहीही काढून टाका."</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ब्लॅक बार सह तुमच्या स्क्रीनची वरची बाजू साफ करा"</string>
<string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"तुमचा चेहरा पूर्णपणे दृश्यमान असणे आवश्यक आहे"</string>
<string name="face_acquired_mouth_covering_detected" msgid="615991670821926847">"तुमचा चेहरा पूर्णपणे दृश्यमान असणे आवश्यक आहे"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"सिस्टीम डीफॉल्ट"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index c3fba8c87c30..7a3c7efb8158 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tidak boleh menggunakan penderia cap jari. Lawati penyedia pembaikan"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan cap jari"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan cap jari atau kunci skrin"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera telefon daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string>
<string name="system_locale_title" msgid="711882686834677268">"Lalai sistem"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KAD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 665bbce37d3d..770deed2e83d 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"လက်ဗွေ အာရုံခံကိရိယာကို အသုံးပြု၍ မရပါ။ ပြုပြင်ရေး ဝန်ဆောင်မှုပေးသူထံသို့ သွားပါ"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"စနစ်မူရင်း"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ကတ် <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 65b58acb678a..caa190008a2d 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan ikke bruke fingeravtrykkssensoren. Gå til en reparasjonsleverandør"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Bruk fingeravtrykk"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Bruk fingeravtrykk eller skjermlås"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Det er ikke mulig å få tilgang til telefonkameraet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Det er ikke mulig å få tilgang til kameraet på nettbrettet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Systemstandard"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 4aa60819e53c..d581c67f2df4 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो डिभाइसमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिन्ट सेन्सर प्रयोग गर्न मिल्दैन। फिंगरप्रिन्ट सेन्सर मर्मत गर्ने सेवा प्रदायक कम्पनीमा सम्पर्क गर्नुहोस्"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"सिस्टम डिफल्ट"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 974d64207e76..210ce12d8f80 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor staat tijdelijk uit."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan vingerafdruksensor niet gebruiken. Ga naar een reparateur."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Vingerafdruk gebruiken"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Vingerafdruk of schermvergrendeling gebruiken"</string>
@@ -649,7 +651,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Kijk goed recht naar je telefoon"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Kijk goed recht naar je telefoon"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Kijk goed recht naar je telefoon"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Zorg dat je gezicht volledig zichtbaar is."</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Zorg dat je gezicht volledig zichtbaar is"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Reinig de bovenkant van je scherm, inclusief de zwarte balk"</string>
<string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"Je gezicht moet geheel zichtbaar zijn"</string>
<string name="face_acquired_mouth_covering_detected" msgid="615991670821926847">"Je gezicht moet geheel zichtbaar zijn"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan geen toegang tot de camera van de telefoon krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan geen toegang tot de camera van de tablet krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Systeemstandaard"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index f5922b912788..05e34feddce3 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍‌ରେ ଟିପଚିହ୍ନ ସେନ୍‍ସର୍ ନାହିଁ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ଏକ ମରାମତି କେନ୍ଦ୍ରକୁ ଭିଜିଟ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ଟିପଚିହ୍ନ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -636,10 +638,10 @@
<string name="face_acquired_too_dark" msgid="7919016380747701228">"ଉଜ୍ଜ୍ୱଳ ଲାଇଟ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"ଫୋନକୁ ଟିକେ ଦୂରକୁ ନିଅନ୍ତୁ"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"ଫୋନକୁ ପାଖକୁ ଆଣନ୍ତୁ"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"ଫୋନକୁ ଉପରକୁ ନିଅନ୍ତୁ"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"ଫୋନକୁ ତଳକୁ ନିଅନ୍ତୁ"</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"ଫୋନକୁ ଆପଣଙ୍କ ବାମ ପଟକୁ ନିଅନ୍ତୁ"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"ଫୋନକୁ ଆପଣଙ୍କ ଡାହାଣ ପଟକୁ ନିଅନ୍ତୁ"</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"ଫୋନକୁ ଉପରକୁ ମୁଭ କରନ୍ତୁ"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"ଫୋନ୍‌କୁ ତଳକୁ ମୁଭ କରନ୍ତୁ"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"ଫୋନକୁ ଆପଣଙ୍କ ବାମ ପଟକୁ ମୁଭ କରନ୍ତୁ"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"ଫୋନକୁ ଆପଣଙ୍କ ଡାହାଣ ପଟକୁ ମୁଭ କରନ୍ତୁ"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"ଦୟାକରି ଆପଣଙ୍କ ଡିଭାଇସ୍‌କୁ ସିଧାସଳଖ ଦେଖନ୍ତୁ।"</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"ଆପଣଙ୍କ ଫେସ ଦେଖାଯାଉନାହିଁ। ଆପଣଙ୍କ ଫୋନକୁ ଆଖି ସିଧାରେ ଧରି ରଖନ୍ତୁ।"</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"ଅତ୍ୟଧିକ ଅସ୍ଥିର। ଫୋନ୍‍କୁ ସ୍ଥିର ଭାବେ ଧରନ୍ତୁ।"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"ସିଷ୍ଟମ ଡିଫଲ୍ଟ"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"କାର୍ଡ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index ce8d32330aeb..969b97f266c7 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਮੁਰੰਮਤ ਪ੍ਰਦਾਨਕ \'ਤੇ ਜਾਓ"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"ਸਿਸਟਮ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ਕਾਰਡ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 6fc06962e9ef..6c2aa0da9d97 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nie można użyć czytnika linii papilarnych. Odwiedź serwis."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Używaj odcisku palca"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Używaj odcisku palca lub blokady ekranu"</string>
@@ -2288,6 +2290,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nie można korzystać z aparatu telefonu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nie można korzystać z aparatu tabletu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Ustawienie domyślne systemu"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index caa8cd18f36d..99fd7b651287 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não foi possível usar o sensor de impressão digital. Entre em contato com uma assistência técnica"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Padrão do sistema"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CHIP <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3b7c16254584..81029d696ebf 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não é possível usar o sensor de impressões digitais. Visite um fornecedor de serviços de reparação"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar a impressão digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar o bloqueio de ecrã ou a impressão digital"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível aceder à câmara do telemóvel a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível aceder à câmara do tablet a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predefinição do sistema"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARTÃO <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index caa8cd18f36d..99fd7b651287 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não foi possível usar o sensor de impressão digital. Entre em contato com uma assistência técnica"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Padrão do sistema"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CHIP <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 1b74fd8fd43e..279943139883 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -612,6 +612,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nu se poate folosi senzorul de amprentă. Vizitați un furnizor de servicii de reparații."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
@@ -2287,6 +2289,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nu se poate accesa camera foto a telefonului de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nu se poate accesa camera foto a tabletei de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Prestabilit de sistem"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 16a8e163c83e..c7a2cfe2e250 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Невозможно использовать сканер отпечатков пальцев. Обратитесь в сервисный центр."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Использовать отпечаток пальца или блокировку экрана"</string>
@@ -638,10 +640,10 @@
<string name="face_acquired_too_dark" msgid="7919016380747701228">"Сделайте освещение ярче"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"Переместите телефон дальше от лица."</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"Переместите телефон ближе к лицу"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"Переместите телефон выше."</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"Переместите телефон ниже."</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"Переместите телефон левее."</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Переместите телефон правее."</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"Переместите телефон выше"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"Переместите телефон ниже"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"Переместите телефон левее"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Переместите телефон правее"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Смотрите прямо на устройство."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"Вашего лица не видно. Держите телефон на уровне глаз"</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Не перемещайте устройство. Держите его неподвижно."</string>
@@ -2288,6 +2290,5 @@
<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="711882686834677268">"Системные настройки по умолчанию"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 4cc1370e479d..cc19efcb398c 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ඇඟිලි සලකුණු සංවේදකය භාවිත කළ නොහැකිය. අළුත්වැඩියා සැපයුම්කරුවෙකු බලන්න"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ඇඟිලි සලකුණ භාවිත කරන්න"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ඇඟිලි සලකුණ හෝ තිර අගුල භාවිත කරන්න"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"පද්ධති පෙරනිමිය"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"කාඩ්පත <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 92e0d8225920..06467b0d4837 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Senzor odtlačkov prstov nie je možné používať. Navštívte poskytovateľa opráv."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použiť odtlačok prsta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použiť odtlačok prsta alebo zámku obrazovky"</string>
@@ -2288,6 +2290,5 @@
<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="711882686834677268">"Predvolené systémom"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index aec8232628a6..605f5b00173d 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tipala prstnih odtisov ni mogoče uporabiti. Obiščite ponudnika popravil."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Uporaba prstnega odtisa"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Uporaba prstnega odtisa ali odklepanja s poverilnico"</string>
@@ -2288,6 +2290,5 @@
<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="711882686834677268">"Sistemsko privzeto"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 6554eb800239..6e7c979560a6 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sensori i gjurmës së gishtit nuk mund të përdoret. Vizito një ofrues të shërbimit të riparimit"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nuk mund të qasesh në kamerën e telefonit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nuk mund të qasesh në kamerën e tabletit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Parazgjedhja e sistemit"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index cb1f34da2d75..f1fc5ca375c8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -612,6 +612,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не можете да користите сензор за отисак прста. Посетите добављача за поправке"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
@@ -2287,6 +2289,5 @@
<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="711882686834677268">"Подразумевани системски"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"КАРТИЦА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index a8d0cced54cb..3c96c5661b3f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Det går inte att använda fingeravtryckssensorn. Besök ett reparationsställe"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Använd ditt fingeravtryck"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Använd ditt fingeravtryck eller skärmlåset"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Telefonens kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Surfplattans kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Systemets standardinställning"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 9f10d910ca84..81ccc22f5e96 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Imeshindwa kutumia kitambua alama ya kidole. Tembelea mtoa huduma za urekebishaji"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Tumia alama ya kidole"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Tumia alama ya kidole au mbinu ya kufunga skrini"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Haiwezi kufikia kamera ya simu kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Haiwezi kufikia kamera ya kompyuta kibao kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string>
<string name="system_locale_title" msgid="711882686834677268">"Chaguomsingi la mfumo"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"SIM KADI <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index fbb4884efbf4..b2836cb2f277 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"கைரேகை சென்சாரைப் பயன்படுத்த முடியவில்லை. பழுதுபார்ப்புச் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"சிஸ்டத்தின் இயல்பு"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"கார்டு <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 390cdcfe812e..dbd8472f9ff4 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -64,7 +64,7 @@
<string name="CnirMmi" msgid="885292039284503036">"కాలింగ్ నంబర్ పరిమితం చేయబడింది"</string>
<string name="ThreeWCMmi" msgid="2436550866139999411">"మూడు మార్గాల కాలింగ్"</string>
<string name="RuacMmi" msgid="1876047385848991110">"అవాంఛిత అంతరాయ కాల్స్‌ల తిరస్కరణ"</string>
- <string name="CndMmi" msgid="185136449405618437">"కాలింగ్ నంబర్ బట్వాడా"</string>
+ <string name="CndMmi" msgid="185136449405618437">"కాలింగ్ నంబర్ డెలివరీ"</string>
<string name="DndMmi" msgid="8797375819689129800">"అంతరాయం కలిగించవద్దు"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"కాలర్ ID ఆటోమేటిక్‌లపై పరిమితి ఉంటుంది. తర్వాత కాల్: పరిమితి ఉంటుంది"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"కాలర్ ID ఆటోమేటిక్‌లపై పరిమితి ఉంటుంది. తర్వాత కాల్: పరిమితి లేదు"</string>
@@ -319,7 +319,7 @@
<string name="permgrouplab_phone" msgid="570318944091926620">"ఫోన్"</string>
<string name="permgroupdesc_phone" msgid="270048070781478204">"ఫోన్ కాల్స్‌ చేయడం మరియు నిర్వహించడం"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"శరీర సెన్సార్‌లు"</string>
- <string name="permgroupdesc_sensors" msgid="2610631290633747752">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాని యాక్సెస్ చేస్తుంది"</string>
+ <string name="permgroupdesc_sensors" msgid="2610631290633747752">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాను యాక్సెస్ చేస్తుంది"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"నోటిఫికేషన్‌లు"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"నోటిఫికేషన్‌లను చూపండి"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"విండో కంటెంట్‍ను తిరిగి పొందుతుంది"</string>
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"వేలిముద్ర సెన్సార్‌ను ఉపయోగించడం సాధ్యం కాదు. రిపెయిర్ ప్రొవైడర్‌ను సందర్శించండి"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"వేలిముద్ర లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
@@ -964,7 +966,7 @@
<string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"సైన్ ఇన్ చేయండి"</string>
<string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"వినియోగదారు పేరు లేదా పాస్‌వర్డ్ చెల్లదు."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"మీ వినియోగదారు పేరు లేదా పాస్‌వర్డ్‌ను మర్చిపోయారా?\n"<b>"google.com/accounts/recovery"</b>"ని సందర్శించండి."</string>
- <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"తనిఖీ చేస్తోంది..."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"చెక్ చేస్తోంది..."</string>
<string name="lockscreen_unlock_label" msgid="4648257878373307582">"అన్‌లాక్ చేయండి"</string>
<string name="lockscreen_sound_on_label" msgid="1660281470535492430">"ధ్వని ఆన్‌లో ఉంది"</string>
<string name="lockscreen_sound_off_label" msgid="2331496559245450053">"ధ్వని ఆఫ్‌లో ఉంది"</string>
@@ -1073,7 +1075,7 @@
<string name="search_hint" msgid="455364685740251925">"సెర్చ్ చేయండి..."</string>
<string name="searchview_description_search" msgid="1045552007537359343">"సెర్చ్"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"సెర్చ్ క్వెరీ"</string>
- <string name="searchview_description_clear" msgid="1989371719192982900">"ప్రశ్నను క్లియర్ చేయి"</string>
+ <string name="searchview_description_clear" msgid="1989371719192982900">"ప్రశ్నను క్లియర్ చేయండి"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ప్రశ్నని సమర్పించండి"</string>
<string name="searchview_description_voice" msgid="42360159504884679">"వాయిస్ సెర్చ్"</string>
<string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"తాకడం ద్వారా విశ్లేషణను ప్రారంభించాలా?"</string>
@@ -1128,11 +1130,11 @@
<string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="1532369154488982046">"అన్నింటినీ ఎంచుకోండి"</string>
- <string name="cut" msgid="2561199725874745819">"కత్తిరించు"</string>
+ <string name="cut" msgid="2561199725874745819">"కత్తిరించండి"</string>
<string name="copy" msgid="5472512047143665218">"కాపీ చేయండి"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"క్లిప్‌బోర్డ్‌కు కాపీ చేయడంలో విఫలమైంది"</string>
- <string name="paste" msgid="461843306215520225">"అతికించు"</string>
- <string name="paste_as_plain_text" msgid="7664800665823182587">"సాదా వచనం లాగా అతికించు"</string>
+ <string name="paste" msgid="461843306215520225">"పేస్ట్ చేయండి"</string>
+ <string name="paste_as_plain_text" msgid="7664800665823182587">"సాదా వచనం లాగా పేస్ట్ చేయండి"</string>
<string name="replace" msgid="7842675434546657444">"భర్తీ చేయండి..."</string>
<string name="delete" msgid="1514113991712129054">"తొలగించండి"</string>
<string name="copyUrl" msgid="6229645005987260230">"URLని కాపీ చేయి"</string>
@@ -1193,7 +1195,7 @@
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"చిత్రాన్ని క్యాప్చర్ చేయి"</string>
<string name="alwaysUse" msgid="3153558199076112903">"ఈ చర్యకు ఆటోమేటిక్‌గా ఉపయోగించండి."</string>
<string name="use_a_different_app" msgid="4987790276170972776">"వేరొక యాప్‌ను ఉపయోగించండి"</string>
- <string name="clearDefaultHintMsg" msgid="1325866337702524936">"సిస్టమ్ సెట్టింగ్‌లు &gt; యాప్‌లు &gt; డౌన్‌లోడ్ చేయబడినవిలో ఆటోమేటిక్‌ను క్లియర్ చేయి."</string>
+ <string name="clearDefaultHintMsg" msgid="1325866337702524936">"సిస్టమ్ సెట్టింగ్‌లు &gt; యాప్‌లు &gt; డౌన్‌లోడ్ చేయబడినవిలో ఆటోమేటిక్‌ను క్లియర్ చేయండి."</string>
<string name="chooseActivity" msgid="8563390197659779956">"చర్యను ఎంచుకోండి"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"USB పరికరం కోసం యాప్‌ను ఎంచుకోండి"</string>
<string name="noApplications" msgid="1186909265235544019">"ఈ చర్యను అమలు చేయగల యాప్‌లు ఏవీ లేవు."</string>
@@ -1323,7 +1325,7 @@
<string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"రద్దు చేయండి"</string>
<string name="sms_short_code_remember_choice" msgid="1374526438647744862">"నా ఎంపికను గుర్తుంచుకో"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"మీరు దీన్ని తర్వాత సెట్టింగ్‌లు &gt; అనువర్తనాలులో మార్చవచ్చు"</string>
- <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"ఎల్లప్పుడూ అనుమతించు"</string>
+ <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"ఎల్లప్పుడూ అనుమతించండి"</string>
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"ఎప్పటికీ అనుమతించవద్దు"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"సిమ్ కార్డు తీసివేయబడింది"</string>
<string name="sim_removed_message" msgid="9051174064474904617">"మీరు చెల్లుబాటు అయ్యే సిమ్ కార్డు‌ను చొప్పించి పునఃప్రారంభించే వరకు మొబైల్ నెట్‌వర్క్ అందుబాటులో ఉండదు."</string>
@@ -1366,7 +1368,7 @@
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"పరీక్ష నియంత్రణ మోడ్ ప్రారంభించబడింది"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"పరీక్ష నియంత్రణ మోడ్‌ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్‍‌ను అమలు చేయండి."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"సీరియల్ కన్సోల్ ప్రారంభించబడింది"</string>
- <string name="console_running_notification_message" msgid="7892751888125174039">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్‌లోడర్‌ను తనిఖీ చేయండి."</string>
+ <string name="console_running_notification_message" msgid="7892751888125174039">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్‌లోడర్‌ను చెక్ చేయండి."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ప్రయోగాత్మక MTE ఎనేబుల్ చేయబడింది"</string>
<string name="mte_override_notification_message" msgid="2441170442725738942">"పనితీరు, స్థిరత్వం ప్రభావితం కావచ్చు. డిజేబుల్ చేయడానికి రీబూట్ చేయండి. arm64.memtag.bootctlని ఉపయోగించి ఎనేబుల్ చేసినట్లయితే, దాన్ని ముందుగా ఏదీ లేనిదిగా సెట్ చేయండి."</string>
<string name="usb_contaminant_detected_title" msgid="4359048603069159678">"USB పోర్ట్‌లో ద్రవ లేదా వ్యర్థ పదార్థాలు ఉన్నాయి"</string>
@@ -1391,7 +1393,7 @@
<string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> ఇతర యాప్‌లలో చూపబడుతోంది"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి ట్యాప్ చేసి, దీన్ని ఆఫ్ చేయండి."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ఆఫ్ చేయి"</string>
- <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>ని తనిఖీ చేస్తోంది…"</string>
+ <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>ని చెక్ చేస్తోంది…"</string>
<string name="ext_media_checking_notification_message" msgid="2231566971425375542">"ప్రస్తుత కంటెంట్ సమీక్షించబడుతోంది"</string>
<string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"మీడియా స్టోరేజ్‌ను విశ్లేషిస్తోంది"</string>
<string name="ext_media_new_notification_title" msgid="3517407571407687677">"కొత్త <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1431,7 +1433,7 @@
<string name="ext_media_move_failure_message" msgid="4197306718121869335">"కంటెంట్‌ని తరలించడానికి మళ్లీ ప్రయత్నించండి"</string>
<string name="ext_media_status_removed" msgid="241223931135751691">"తీసివేయబడింది"</string>
<string name="ext_media_status_unmounted" msgid="8145812017295835941">"తొలగించబడింది"</string>
- <string name="ext_media_status_checking" msgid="159013362442090347">"తనిఖీ చేస్తోంది..."</string>
+ <string name="ext_media_status_checking" msgid="159013362442090347">"చెక్ చేస్తోంది..."</string>
<string name="ext_media_status_mounted" msgid="3459448555811203459">"సిద్ధంగా ఉంది"</string>
<string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"చదవడానికి మాత్రమే"</string>
<string name="ext_media_status_bad_removal" msgid="508448566481406245">"అసురక్షితంగా తీసివేయబడింది"</string>
@@ -1578,8 +1580,8 @@
<string name="data_usage_restricted_title" msgid="126711424380051268">"నేపథ్య డేటా పరిమితం చేయబడింది"</string>
<string name="data_usage_restricted_body" msgid="5338694433686077733">"నియంత్రణ తీసివేయడానికి నొక్కండి."</string>
<string name="data_usage_rapid_title" msgid="2950192123248740375">"అధిక మొబైల్ డేటా వినియోగం"</string>
- <string name="data_usage_rapid_body" msgid="3886676853263693432">"మీ యాప్‌లు సాధారణం కంటే ఎక్కువ డేటాని ఉపయోగించాయి"</string>
- <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"<xliff:g id="APP">%s</xliff:g> సాధారణం కంటే ఎక్కువ డేటాని ఉపయోగించింది"</string>
+ <string name="data_usage_rapid_body" msgid="3886676853263693432">"మీ యాప్‌లు సాధారణం కంటే ఎక్కువ డేటాను ఉపయోగించాయి"</string>
+ <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"<xliff:g id="APP">%s</xliff:g> సాధారణం కంటే ఎక్కువ డేటాను ఉపయోగించింది"</string>
<string name="ssl_certificate" msgid="5690020361307261997">"సెక్యూరిటీ సర్టిఫికెట్"</string>
<string name="ssl_certificate_is_valid" msgid="7293675884598527081">"ఈ సర్టిఫికెట్ చెల్లుబాటు అవుతుంది."</string>
<string name="issued_to" msgid="5975877665505297662">"దీనికి జారీ చేయబడింది:"</string>
@@ -1653,7 +1655,7 @@
<string name="kg_login_submit_button" msgid="893611277617096870">"సైన్ ఇన్ చేయండి"</string>
<string name="kg_login_invalid_input" msgid="8292367491901220210">"చెల్లని వినియోగదారు పేరు లేదా పాస్‌వర్డ్."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"మీ వినియోగదారు పేరు లేదా పాస్‌వర్డ్‌ను మర్చిపోయారా?\n"<b>"google.com/accounts/recovery"</b>"ని సందర్శించండి."</string>
- <string name="kg_login_checking_password" msgid="4676010303243317253">"ఖాతాను తనిఖీ చేస్తోంది…"</string>
+ <string name="kg_login_checking_password" msgid="4676010303243317253">"ఖాతాను చెక్ చేస్తోంది…"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"మీరు మీ పిన్‌ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేశారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"మీరు మీ పాస్‌వర్డ్‌ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేశారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
@@ -1667,7 +1669,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీశారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత మీ Android TV పరికరాన్ని ఈమెయిల్‌ ఖాతా ద్వారా అన్‌లాక్ చేయాల్సిందిగా మిమ్మల్ని కోరడం జరుగుతుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈమెయిల్‌ ఖాతాను ఉపయోగించి మీ ఫోన్‌ను అన్‌లాక్ చేయాల్సిందిగా మిమ్మల్ని అడుగుతారు.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
- <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"తీసివేయి"</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"తీసివేయండి"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"వాల్యూమ్‌ను సిఫార్సు చేయబడిన స్థాయి కంటే ఎక్కువగా పెంచాలా?\n\nసుదీర్ఘ వ్యవధుల పాటు అధిక వాల్యూమ్‌లో వినడం వలన మీ వినికిడి శక్తి దెబ్బ తినవచ్చు."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"యాక్సెస్ సామర్థ్యం షార్ట్‌కట్‌ను ఉపయోగించాలా?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"షార్ట్‌కట్ ఆన్ చేసి ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్‌లను 3 సెకన్ల పాటు నొక్కి ఉంచితే యాక్సెస్ సౌలభ్య ఫీచర్ ప్రారంభం అవుతుంది."</string>
@@ -1952,7 +1954,7 @@
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ Android TV పరికరంలో ట్రై చేయండి."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ టాబ్లెట్‌లో ట్రై చేయండి."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ ఫోన్‌లో ట్రై చేయండి."</string>
- <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్‌డేట్‌ల కోసం తనిఖీ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్‌ని సంప్రదించండి."</string>
+ <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్‌డేట్‌ల కోసం చెక్ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్‌ని సంప్రదించండి."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్‌డేట్ కోసం చెక్ చేయండి"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త మెసేజ్‌లు ఉన్నాయి"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"వీక్షించడానికి SMS యాప్‌ను తెరవండి"</string>
@@ -2055,7 +2057,7 @@
<string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"కొత్తది: అంతరాయం కలిగించవద్దు నోటిఫికేషన్‌లను దాస్తోంది"</string>
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"మరింత తెలుసుకోవడానికి మరియు మార్చడానికి నొక్కండి."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"అంతరాయం కలిగించవద్దు మార్చబడింది"</string>
- <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"బ్లాక్ చేయబడిన దాన్ని తనిఖీ చేయడానికి నొక్కండి."</string>
+ <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"బ్లాక్ చేయబడిన దాన్ని చెక్ చేయడానికి నొక్కండి."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"నోటిఫికేషన్ సెట్టింగ్‌లను రివ్యూ చేయండి"</string>
<string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13తో మొదలుకుని, మీరు ఇన్‌స్టాల్ చేసే యాప్‌లకు నోటిఫికేషన్‌లను పంపడానికి మీ అనుమతి అవసరం. ఇప్పటికే ఉన్న యాప్‌ల కోసం ఈ అనుమతిని మార్చడానికి ట్యాప్ చేయండి."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"తర్వాత గుర్తు చేయి"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"సిస్టమ్ ఆటోమేటిక్ సెట్టింగ్"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"కార్డ్ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index e43f84d0fe26..66d85d0c7ee3 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ใช้เซ็นเซอร์ลายนิ้วมือไม่ได้ โปรดติดต่อผู้ให้บริการซ่อม"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"ค่าเริ่มต้นของระบบ"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"ซิมการ์ด <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index bbafd022d64e..543b0aa2b462 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Hindi magamit ang sensor para sa fingerprint. Bumisita sa provider ng pag-aayos"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gumamit ng fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gumamit ng fingerprint o lock ng screen"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"Default ng system"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 349947810b20..fd07f8918b8d 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Parmak izi sensörü kullanılamıyor. Bir onarım hizmeti sağlayıcıyı ziyaret edin"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Parmak izi kullan"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Parmak izi veya ekran kilidi kullan"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına erişilemiyor"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan tabletin kamerasına erişilemiyor"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistem varsayılanı"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"KART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 2b7d9cce7833..4fad265047e4 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не вдається скористатися сканером відбитків пальців. Зверніться до постачальника послуг із ремонту."</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Доступ за відбитком пальця"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або дані для розблокування екрана"</string>
@@ -640,8 +642,8 @@
<string name="face_acquired_too_far" msgid="2922278214231064859">"Тримайте телефон ближче до обличчя"</string>
<string name="face_acquired_too_high" msgid="8278815780046368576">"Підніміть телефон вище"</string>
<string name="face_acquired_too_low" msgid="4075391872960840081">"Опустіть телефон нижче"</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"Тримайте телефон лівіше"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Тримайте телефон правіше"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"Посуньте телефон лівіше"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Посуньте телефон правіше"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Дивіться просто на пристрій."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"Обличчя не видно. Утримуйте телефон на рівні очей."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Забагато рухів. Тримайте телефон нерухомо."</string>
@@ -2288,6 +2290,5 @@
<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="711882686834677268">"Налаштування системи за умовчанням"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"КАРТКА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 90f8d600238f..6caff7181f0f 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"فنگر پرنٹ سینسر کا استعمال نہیں کر سکتے۔ ایک مرمت فراہم کنندہ کو ملاحظہ کریں"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"سسٹم ڈیفالٹ"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"کارڈ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index fc140bb9442c..2d420b16d1c7 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Barmoq izi skaneridan foydalanish imkonsiz. Xizmat koʻrsatish markaziga murojaat qiling"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmoq izi yoki ekran qulfi"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan telefonning kamerasiga kirish imkonsiz"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan planshetning kamerasiga kirish imkonsiz"</string>
<string name="system_locale_title" msgid="711882686834677268">"Tizim standarti"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"SIM KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index b658c9f14a01..bef332933475 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Không thể dùng cảm biến vân tay. Hãy liên hệ với một nhà cung cấp dịch vụ sửa chữa"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Dùng vân tay"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Dùng vân tay hoặc phương thức khóa màn hình"</string>
@@ -654,7 +656,7 @@
<string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"Bạn cần cho thấy toàn bộ khuôn mặt của mình"</string>
<string name="face_acquired_mouth_covering_detected" msgid="615991670821926847">"Toàn bộ khuôn mặt của bạn phải được hiển thị"</string>
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Không thể tạo mẫu khuôn mặt của bạn. Hãy thử lại."</string>
- <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Đã phát hiện đeo kính đen. Toàn bộ khuôn mặt của bạn phải được hiển thị."</string>
+ <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Đã phát hiện thấy kính râm. Toàn bộ khuôn mặt của bạn phải được trông thấy rõ ràng."</string>
<string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Đã phát hiện khuôn mặt bị che khuất. Toàn bộ khuôn mặt của bạn phải được hiển thị."</string>
<string-array name="face_acquired_vendor">
</string-array>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Không truy cập được vào máy ảnh trên điện thoại từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Không truy cập được vào máy ảnh trên máy tính bảng từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string>
<string name="system_locale_title" msgid="711882686834677268">"Theo chế độ mặc định của hệ thống"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"THẺ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 129c5830d1ab..8da18dc3e796 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"无法使用指纹传感器。请联系维修服务提供商"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"系统默认设置"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index ef886c9ab042..0c4d8f82f55a 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"無法使用指紋感應器。請諮詢維修服務供應商"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"系統預設"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 9dbcd4459cf9..20a941fa74df 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋感應器無法使用,請洽詢維修供應商"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定功能"</string>
@@ -2286,6 +2288,5 @@
<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="711882686834677268">"系統預設"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 6a4a4485cc6a..36725e9ff41e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -611,6 +611,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ayikwazi ukusebenzisa inzwa yesigxivizo somunwe. Vakashela umhlinzeki wokulungisa"</string>
+ <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sebenzisa izigxivizo zeminwe"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sebenzisa izigxivizo zeminwe noma ukukhiya isikrini"</string>
@@ -2286,6 +2288,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ayikwazi ukufinyelela ikhamera yefoni kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ayikwazi ukufinyelela ikhamera yethebulethi kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string>
<string name="system_locale_title" msgid="711882686834677268">"Okuzenzakalelayo kwesistimu"</string>
- <!-- no translation found for default_card_name (9198284935962911468) -->
- <skip />
+ <string name="default_card_name" msgid="9198284935962911468">"IKHADI <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f0b86e36d3fd..9d2c3d7b7e0e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -757,6 +757,15 @@
bar for all apps. -->
<bool name="config_remoteInsetsControllerControlsSystemBars">false</bool>
+ <!-- Control whether the system bars can be requested when using a remote insets control target.
+ This allows for specifying whether or not system bars can be shown by the user (via swipe
+ or other means) when they are hidden by the logic defined by the remote insets controller.
+ This is useful for cases where the system provides alternative affordances for showing and
+ hiding the bars or for cases in which it's desired the bars not be shown for any reason.
+ This configuration will only apply when config_remoteInsetsControllerControlsSystemBars.
+ is set to true. -->
+ <bool name="config_remoteInsetsControllerSystemBarsCanBeShownByUserAction">false</bool>
+
<!-- HDMI behavior -->
<!-- The number of degrees to rotate the display when the device has HDMI connected
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d031de464348..d3dc3013b1ed 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1833,9 +1833,9 @@
<!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=100] -->
<string name="face_acquired_sensor_dirty">Clean the top of your screen, including the black bar</string>
<!-- Message shown during acquisition when dark glasses were detected [CHAR LIMIT=75] -->
- <string name="face_acquired_dark_glasses_detected">Your face must be fully visible</string>
+ <string name="face_acquired_dark_glasses_detected">@string/face_acquired_dark_glasses_detected_alt</string>
<!-- Message shown during acquisition when a mouth covering was detected [CHAR LIMIT=75] -->
- <string name="face_acquired_mouth_covering_detected">Your face must be fully visible</string>
+ <string name="face_acquired_mouth_covering_detected">@string/face_acquired_mouth_covering_detected_alt</string>
<!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=75] -->
<string name="face_acquired_recalibrate_alt">Can\u2019t create your face model. Try again.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 66dd7609ceb5..bcf975974094 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1569,6 +1569,7 @@
<java-symbol type="layout" name="time_picker_dialog" />
<java-symbol type="layout" name="tooltip" />
<java-symbol type="layout" name="transient_notification" />
+ <java-symbol type="layout" name="transient_notification_with_icon" />
<java-symbol type="layout" name="voice_interaction_session" />
<java-symbol type="layout" name="web_text_view_dropdown" />
<java-symbol type="layout" name="webview_find" />
@@ -1726,6 +1727,7 @@
<java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
<java-symbol type="bool" name="config_enableLockScreenRotation" />
<java-symbol type="bool" name="config_remoteInsetsControllerControlsSystemBars" />
+ <java-symbol type="bool" name="config_remoteInsetsControllerSystemBarsCanBeShownByUserAction" />
<java-symbol type="bool" name="config_lidControlsScreenLock" />
<java-symbol type="bool" name="config_lidControlsSleep" />
<java-symbol type="bool" name="config_lockDayNightMode" />
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml b/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
index 6639c0241ae2..6e9d4db47c41 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
@@ -21,6 +21,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.BATTERY_STATS"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<application
android:theme="@style/Theme"
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index 50639be57f22..0a5a4d5a9adb 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -32,7 +32,6 @@ import android.app.servertransaction.TestUtils.LaunchActivityItemBuilder;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.Bundle;
@@ -140,7 +139,6 @@ public class ObjectPoolTests {
activityInfo.name = "name";
Configuration overrideConfig = new Configuration();
overrideConfig.assetsSeq = 5;
- CompatibilityInfo compat = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
String referrer = "referrer";
int procState = 4;
Bundle bundle = new Bundle();
@@ -152,7 +150,7 @@ public class ObjectPoolTests {
Supplier<LaunchActivityItem> itemSupplier = () -> new LaunchActivityItemBuilder()
.setIntent(intent).setIdent(ident).setInfo(activityInfo).setCurConfig(config())
- .setOverrideConfig(overrideConfig).setCompatInfo(compat).setReferrer(referrer)
+ .setOverrideConfig(overrideConfig).setReferrer(referrer)
.setProcState(procState).setState(bundle).setPersistentState(persistableBundle)
.setPendingResults(resultInfoList()).setPendingNewIntents(referrerIntentList())
.setIsForward(true).setAssistToken(assistToken)
diff --git a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
index 26d9628ba55b..2cd890cd9d18 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
@@ -23,7 +23,6 @@ import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
@@ -96,7 +95,6 @@ class TestUtils {
private ActivityInfo mInfo;
private Configuration mCurConfig;
private Configuration mOverrideConfig;
- private CompatibilityInfo mCompatInfo;
private String mReferrer;
private IVoiceInteractor mVoiceInteractor;
private int mProcState;
@@ -137,11 +135,6 @@ class TestUtils {
return this;
}
- LaunchActivityItemBuilder setCompatInfo(CompatibilityInfo compatInfo) {
- mCompatInfo = compatInfo;
- return this;
- }
-
LaunchActivityItemBuilder setReferrer(String referrer) {
mReferrer = referrer;
return this;
@@ -214,7 +207,7 @@ class TestUtils {
LaunchActivityItem build() {
return LaunchActivityItem.obtain(mIntent, mIdent, mInfo,
- mCurConfig, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor,
+ mCurConfig, mOverrideConfig, mReferrer, mVoiceInteractor,
mProcState, mState, mPersistentState, mPendingResults, mPendingNewIntents,
mActivityOptions, mIsForward, mProfilerInfo, mAssistToken,
null /* activityClientController */, mShareableActivityToken,
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 0eca0a8cb1a7..e9bbdbee576c 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -187,7 +187,6 @@ public class TransactionParcelTests {
activityInfo.name = "name";
Configuration overrideConfig = new Configuration();
overrideConfig.assetsSeq = 5;
- CompatibilityInfo compat = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
String referrer = "referrer";
int procState = 4;
Bundle bundle = new Bundle();
@@ -198,7 +197,7 @@ public class TransactionParcelTests {
LaunchActivityItem item = new LaunchActivityItemBuilder()
.setIntent(intent).setIdent(ident).setInfo(activityInfo).setCurConfig(config())
- .setOverrideConfig(overrideConfig).setCompatInfo(compat).setReferrer(referrer)
+ .setOverrideConfig(overrideConfig).setReferrer(referrer)
.setProcState(procState).setState(bundle).setPersistentState(persistableBundle)
.setPendingResults(resultInfoList()).setActivityOptions(ActivityOptions.makeBasic())
.setPendingNewIntents(referrerIntentList()).setIsForward(true)
@@ -489,13 +488,13 @@ public class TransactionParcelTests {
@Override
public void scheduleCreateBackupAgent(ApplicationInfo applicationInfo,
- CompatibilityInfo compatibilityInfo, int i, int userId, int operatioType)
+ int i, int userId, int operatioType)
throws RemoteException {
}
@Override
public void scheduleDestroyBackupAgent(ApplicationInfo applicationInfo,
- CompatibilityInfo compatibilityInfo, int userId) throws RemoteException {
+ int userId) throws RemoteException {
}
@Override
diff --git a/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java b/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
index 7338c3a3ea8a..ddc05e09c395 100644
--- a/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
+++ b/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
@@ -204,6 +204,19 @@ public class AdaptiveIconDrawableTest extends AndroidTestCase {
assertEquals(100, Color.alpha(bitmap.getPixel(50, 50)));
}
+ @Test
+ public void testSetBounds() throws Exception {
+ mIconDrawable = new AdaptiveIconDrawable(mBackgroundDrawable, mForegroundDrawable);
+ mIconDrawable.setBounds(0, 0, 100, 100);
+
+ assertEquals(new Rect(-25, -25, 125, 125), mBackgroundDrawable.getBounds());
+ assertEquals(new Rect(-25, -25, 125, 125), mForegroundDrawable.getBounds());
+
+ mIconDrawable.setBounds(10, 10, 110, 110);
+ assertEquals(new Rect(-15, -15, 135, 135), mBackgroundDrawable.getBounds());
+ assertEquals(new Rect(-15, -15, 135, 135), mForegroundDrawable.getBounds());
+ }
+
//
// Utils
//
diff --git a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt
index 6360a2deb544..3ab7fa9bc995 100644
--- a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt
+++ b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt
@@ -22,7 +22,6 @@ import android.net.NetworkTemplate.MATCH_CARRIER
import android.net.NetworkTemplate.MATCH_ETHERNET
import android.net.NetworkTemplate.MATCH_MOBILE
import android.net.NetworkTemplate.MATCH_WIFI
-import android.text.format.Time.TIMEZONE_UTC
import androidx.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
@@ -57,7 +56,7 @@ class NetworkPolicyTest {
}
private fun createTestPolicyForTemplate(template: NetworkTemplate): NetworkPolicy {
- return NetworkPolicy(template, NetworkPolicy.buildRule(5, ZoneId.of(TIMEZONE_UTC)),
+ return NetworkPolicy(template, NetworkPolicy.buildRule(5, ZoneId.of("UTC")),
NetworkPolicy.WARNING_DISABLED, NetworkPolicy.LIMIT_DISABLED,
NetworkPolicy.SNOOZE_NEVER, NetworkPolicy.SNOOZE_NEVER, NetworkPolicy.SNOOZE_NEVER,
/*metered*/ false, /*inferred*/ true)
diff --git a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
index 40bffb898e87..4de27c332d96 100644
--- a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
+++ b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
@@ -198,13 +198,52 @@ public class NtpTrustedTimeTest {
}
@Test
- public void testForceRefresh_nullConfig() {
+ public void testForceRefreshDefaultNetwork_noConnectivity() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.getDefaultNetwork()).thenReturn(network);
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(false);
+
+ assertFalse(ntpTrustedTime.forceRefresh());
+
+ InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).getDefaultNetwork();
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+ inOrder.verifyNoMoreInteractions();
+
+ assertNoCachedTimeValueResult(ntpTrustedTime);
+ }
+
+ @Test
+ public void testForceRefreshDefaultNetwork_noActiveNetwork() {
NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ when(ntpTrustedTime.getDefaultNetwork()).thenReturn(null);
+
+ assertFalse(ntpTrustedTime.forceRefresh());
+
+ InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).getDefaultNetwork();
+ inOrder.verifyNoMoreInteractions();
+
+ assertNoCachedTimeValueResult(ntpTrustedTime);
+ }
+
+ @Test
+ public void testForceRefreshDefaultNetwork_nullConfig() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.getDefaultNetwork()).thenReturn(network);
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(null);
assertFalse(ntpTrustedTime.forceRefresh());
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).getDefaultNetwork();
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
inOrder.verifyNoMoreInteractions();
@@ -212,19 +251,34 @@ public class NtpTrustedTimeTest {
}
@Test
- public void testForceRefresh_noConnectivity() {
+ public void testForceRefresh_nullConfig() {
NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
- List<URI> serverUris = createUris("ntp://ntpserver.name");
- when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
- new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
- when(ntpTrustedTime.getNetwork()).thenReturn(null);
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+ when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(null);
- assertFalse(ntpTrustedTime.forceRefresh());
+ assertFalse(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
+ inOrder.verifyNoMoreInteractions();
+
+ assertNoCachedTimeValueResult(ntpTrustedTime);
+ }
+
+ @Test
+ public void testForceRefresh_noConnectivity() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(false);
+
+ assertFalse(ntpTrustedTime.forceRefresh(network));
+
+ InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verifyNoMoreInteractions();
assertNoCachedTimeValueResult(ntpTrustedTime);
@@ -233,21 +287,20 @@ public class NtpTrustedTimeTest {
@Test
public void testForceRefresh_singleServer_queryFailed() {
NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
List<URI> serverUris = createUris("ntp://ntpserver.name");
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
-
- Network network = mock(Network.class);
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
-
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
.thenReturn(null);
- assertFalse(ntpTrustedTime.forceRefresh());
+ assertFalse(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
inOrder.verifyNoMoreInteractions();
@@ -258,23 +311,22 @@ public class NtpTrustedTimeTest {
@Test
public void testForceRefresh_singleServer_querySucceeded() {
NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
List<URI> serverUris = createUris("ntp://ntpserver.name");
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
-
- Network network = mock(Network.class);
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
-
NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
InetSocketAddress.createUnresolved("placeholder", 123));
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
.thenReturn(successResult);
- assertTrue(ntpTrustedTime.forceRefresh());
+ assertTrue(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
inOrder.verifyNoMoreInteractions();
@@ -285,13 +337,12 @@ public class NtpTrustedTimeTest {
@Test
public void testForceRefresh_multiServer_firstQueryFailed() {
NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
List<URI> serverUris = createUris("ntp://ntpserver1.name", "ntp://ntpserver2.name");
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
-
- Network network = mock(Network.class);
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
-
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
.thenReturn(null);
NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
@@ -299,11 +350,11 @@ public class NtpTrustedTimeTest {
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
.thenReturn(successResult);
- assertTrue(ntpTrustedTime.forceRefresh());
+ assertTrue(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
inOrder.verify(ntpTrustedTime, times(1))
@@ -316,23 +367,22 @@ public class NtpTrustedTimeTest {
@Test
public void testForceRefresh_multiServer_firstQuerySucceeded() {
NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
List<URI> serverUris = createUris("ntp://ntpserver1.name", "ntp://ntpserver2.name");
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
-
- Network network = mock(Network.class);
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
-
NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
InetSocketAddress.createUnresolved("placeholder", 123));
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
.thenReturn(successResult);
- assertTrue(ntpTrustedTime.forceRefresh());
+ assertTrue(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
inOrder.verifyNoMoreInteractions();
@@ -343,25 +393,25 @@ public class NtpTrustedTimeTest {
@Test
public void testForceRefresh_multiServer_keepsOldValueOnFailure() {
NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
- List<URI> serverUris = createUris("ntp://ntpserver1.name", "ntp://ntpserver2.name");
- Network network = mock(Network.class);
+ Network network = mock(Network.class);
+ List<URI> serverUris = createUris("ntp://ntpserver1.name", "ntp://ntpserver2.name");
NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
InetSocketAddress.createUnresolved("placeholder", 123));
// First forceRefresh() succeeds.
{
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
.thenReturn(successResult);
- assertTrue(ntpTrustedTime.forceRefresh());
+ assertTrue(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
inOrder.verifyNoMoreInteractions();
@@ -373,19 +423,19 @@ public class NtpTrustedTimeTest {
// Next forceRefresh() fails, keeping the result of the first forceRefresh().
{
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0),
VALID_TIMEOUT)).thenReturn(null);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1),
VALID_TIMEOUT)).thenReturn(null);
- assertFalse(ntpTrustedTime.forceRefresh());
+ assertFalse(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
inOrder.verify(ntpTrustedTime, times(1))
@@ -405,10 +455,10 @@ public class NtpTrustedTimeTest {
@Test
public void testForceRefresh_multiServer_complex() {
NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+ Network network = mock(Network.class);
List<URI> serverUris = createUris(
"ntp://ntpserver1.name", "ntp://ntpserver2.name", "ntp://ntpserver3.name");
- Network network = mock(Network.class);
-
NtpTrustedTime.TimeResult successResult1 = new NtpTrustedTime.TimeResult(111L, 111L, 111,
InetSocketAddress.createUnresolved("placeholder", 111));
NtpTrustedTime.TimeResult successResult2 = new NtpTrustedTime.TimeResult(222L, 222L, 222,
@@ -419,19 +469,19 @@ public class NtpTrustedTimeTest {
// The first forceRefresh() should the URIs in the original order. Here, we fail the first
// and succeed with the second.
{
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
.thenReturn(null);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
.thenReturn(successResult1);
- assertTrue(ntpTrustedTime.forceRefresh());
+ assertTrue(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
inOrder.verify(ntpTrustedTime, times(1))
@@ -445,17 +495,17 @@ public class NtpTrustedTimeTest {
// forceRefresh() should try starting with the last successful server, which will succeed.
{
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
.thenReturn(successResult2);
- assertTrue(ntpTrustedTime.forceRefresh());
+ assertTrue(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
inOrder.verifyNoMoreInteractions();
@@ -468,9 +518,9 @@ public class NtpTrustedTimeTest {
// forceRefresh() should try starting with the last successful server, but try the others in
// order. It will succeed with the final server.
{
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
.thenReturn(null);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
@@ -478,11 +528,11 @@ public class NtpTrustedTimeTest {
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT))
.thenReturn(successResult3);
- assertTrue(ntpTrustedTime.forceRefresh());
+ assertTrue(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
inOrder.verify(ntpTrustedTime, times(1))
@@ -499,9 +549,9 @@ public class NtpTrustedTimeTest {
// forceRefresh() should try starting with the last successful server, but try the others in
// order. It will fail with all.
{
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT))
.thenReturn(null);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
@@ -509,11 +559,11 @@ public class NtpTrustedTimeTest {
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
.thenReturn(null);
- assertFalse(ntpTrustedTime.forceRefresh());
+ assertFalse(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT);
inOrder.verify(ntpTrustedTime, times(1))
@@ -530,9 +580,9 @@ public class NtpTrustedTimeTest {
// forceRefresh() should try starting with the last successful server, but try the others in
// order. It will succeed on the last.
{
+ when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
- when(ntpTrustedTime.getNetwork()).thenReturn(network);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT))
.thenReturn(null);
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
@@ -540,11 +590,11 @@ public class NtpTrustedTimeTest {
when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
.thenReturn(successResult1);
- assertTrue(ntpTrustedTime.forceRefresh());
+ assertTrue(ntpTrustedTime.forceRefresh(network));
InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+ inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
- inOrder.verify(ntpTrustedTime, times(1)).getNetwork();
inOrder.verify(ntpTrustedTime, times(1))
.queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT);
inOrder.verify(ntpTrustedTime, times(1))
diff --git a/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java
index fe7d28917670..b867e4417439 100644
--- a/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java
@@ -19,6 +19,7 @@ package android.view.inputmethod;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -59,6 +60,28 @@ public class EditorInfoTest {
private static final int TEST_USER_ID = 42;
private static final int LONG_EXP_TEXT_LENGTH = EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH * 2;
+ private static final EditorInfo TEST_EDITOR_INFO = new EditorInfo();
+
+ static {
+ TEST_EDITOR_INFO.inputType = InputType.TYPE_CLASS_TEXT; // 0x1
+ TEST_EDITOR_INFO.imeOptions = EditorInfo.IME_ACTION_GO; // 0x2
+ TEST_EDITOR_INFO.privateImeOptions = "testOptions";
+ TEST_EDITOR_INFO.initialSelStart = 0;
+ TEST_EDITOR_INFO.initialSelEnd = 1;
+ TEST_EDITOR_INFO.initialCapsMode = TextUtils.CAP_MODE_CHARACTERS; // 0x1000
+ TEST_EDITOR_INFO.hintText = "testHintText";
+ TEST_EDITOR_INFO.label = "testLabel";
+ TEST_EDITOR_INFO.packageName = "android.view.inputmethod";
+ TEST_EDITOR_INFO.fieldId = 0;
+ TEST_EDITOR_INFO.autofillId = AutofillId.NO_AUTOFILL_ID;
+ TEST_EDITOR_INFO.fieldName = "testField";
+ TEST_EDITOR_INFO.extras = new Bundle();
+ TEST_EDITOR_INFO.extras.putString("testKey", "testValue");
+ TEST_EDITOR_INFO.hintLocales = LocaleList.forLanguageTags("en,de,ua");
+ TEST_EDITOR_INFO.contentMimeTypes = new String[] {"image/png"};
+ TEST_EDITOR_INFO.targetInputMethodUser = UserHandle.of(TEST_USER_ID);
+ }
+
/**
* Makes sure that {@code null} {@link EditorInfo#targetInputMethodUser} can be copied via
* {@link Parcel}.
@@ -526,4 +549,47 @@ public class EditorInfoTest {
+ "prefix: hintLocales=null\n"
+ "prefix: contentMimeTypes=null\n");
}
+
+ @Test
+ public void testKindofEqualsAfterCopyInternal() {
+ final EditorInfo infoCopy = TEST_EDITOR_INFO.createCopyInternal();
+ assertTrue(TEST_EDITOR_INFO.kindofEquals(infoCopy));
+ }
+
+ @Test
+ public void testKindofEqualsAfterCloneViaParcel() {
+ // This test demonstrates a false negative case when an EditorInfo is
+ // created from a Parcel and its extras are still parcelled, which in turn
+ // runs into the edge case in Bundle.kindofEquals
+ final EditorInfo infoCopy = cloneViaParcel(TEST_EDITOR_INFO);
+ assertFalse(TEST_EDITOR_INFO.kindofEquals(infoCopy));
+ }
+
+ @Test
+ public void testKindofEqualsComparesAutofillId() {
+ final EditorInfo infoCopy = TEST_EDITOR_INFO.createCopyInternal();
+ infoCopy.autofillId = new AutofillId(42);
+ assertFalse(TEST_EDITOR_INFO.kindofEquals(infoCopy));
+ }
+
+ @Test
+ public void testKindofEqualsComparesFieldId() {
+ final EditorInfo infoCopy = TEST_EDITOR_INFO.createCopyInternal();
+ infoCopy.fieldId = 42;
+ assertFalse(TEST_EDITOR_INFO.kindofEquals(infoCopy));
+ }
+
+ @Test
+ public void testKindofEqualsComparesMimeTypes() {
+ final EditorInfo infoCopy = TEST_EDITOR_INFO.createCopyInternal();
+ infoCopy.contentMimeTypes = new String[] {"image/png", "image/gif"};
+ assertFalse(TEST_EDITOR_INFO.kindofEquals(infoCopy));
+ }
+
+ @Test
+ public void testKindofEqualsComparesExtras() {
+ final EditorInfo infoCopy = TEST_EDITOR_INFO.createCopyInternal();
+ infoCopy.extras.putString("testKey2", "testValue");
+ assertFalse(TEST_EDITOR_INFO.kindofEquals(infoCopy));
+ }
}
diff --git a/core/tests/coretests/src/android/view/inputmethod/SurroundingTextTest.java b/core/tests/coretests/src/android/view/inputmethod/SurroundingTextTest.java
index dfbc39c76489..50ce335cbec6 100644
--- a/core/tests/coretests/src/android/view/inputmethod/SurroundingTextTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/SurroundingTextTest.java
@@ -17,7 +17,8 @@
package android.view.inputmethod;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
import android.os.Parcel;
@@ -70,4 +71,11 @@ public class SurroundingTextTest {
assertThat(surroundingTextFromParcel.getSelectionEnd(), is(1));
assertThat(surroundingTextFromParcel.getOffset(), is(2));
}
+
+ @Test
+ public void testIsEqualComparesText() {
+ final SurroundingText text1 = new SurroundingText("hello", 0, 1, 0);
+ final SurroundingText text2 = new SurroundingText("there", 0, 1, 0);
+ assertFalse(text1.isEqualTo(text2));
+ }
}
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 47f70ddf2d42..f4a6f025074e 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -54,7 +54,6 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.IBinder;
import android.os.UserHandle;
@@ -339,8 +338,7 @@ public class ActivityThreadClientTest {
doNothing().when(packageInfo).updateApplicationInfo(any(), any());
return new ActivityClientRecord(mock(IBinder.class), Intent.makeMainActivity(component),
- 0 /* ident */, info, new Configuration(),
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null /* referrer */,
+ 0 /* ident */, info, new Configuration(), null /* referrer */,
null /* voiceInteractor */, null /* state */, null /* persistentState */,
null /* pendingResults */, null /* pendingNewIntents */,
null /* activityOptions */, true /* isForward */, null /* profilerInfo */,
diff --git a/data/etc/com.android.settings.xml b/data/etc/com.android.settings.xml
index 5dcc5998850b..3958bb71bfc9 100644
--- a/data/etc/com.android.settings.xml
+++ b/data/etc/com.android.settings.xml
@@ -23,6 +23,7 @@
<permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
<permission name="android.permission.CHANGE_APP_IDLE_STATE"/>
<permission name="android.permission.CHANGE_CONFIGURATION"/>
+ <permission name="android.permission.CONTROL_UI_TRACING"/>
<permission name="android.permission.DELETE_PACKAGES"/>
<permission name="android.permission.FORCE_STOP_PACKAGES"/>
<permission name="android.permission.LOCAL_MAC_ADDRESS"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index d52c70becf75..ae1c94611355 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -907,6 +907,12 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
},
+ "-1237827119": {
+ "message": "Schedule remove starting %s startingWindow=%s animate=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-1228653755": {
"message": "Launch on display check: displayId=%d callingPid=%d callingUid=%d",
"level": "DEBUG",
@@ -1015,12 +1021,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/WindowState.java"
},
- "-1128015008": {
- "message": "Schedule remove starting %s startingWindow=%s startingView=%s Callers=%s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_STARTING_WINDOW",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"-1117599386": {
"message": "Deferring rotation, display is not enabled.",
"level": "VERBOSE",
@@ -3139,6 +3139,12 @@
"group": "WM_DEBUG_LOCKTASK",
"at": "com\/android\/server\/wm\/LockTaskController.java"
},
+ "956467125": {
+ "message": "Reparenting Activity to embedded TaskFragment, but the Activity is not collected",
+ "level": "WARN",
+ "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/WindowOrganizerController.java"
+ },
"958338552": {
"message": "grantEmbeddedWindowFocus win=%s dropped focus so setting focus to null since no candidate was found",
"level": "VERBOSE",
@@ -3877,12 +3883,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "1742235936": {
- "message": "Removing startingView=%s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_STARTING_WINDOW",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"1746778201": {
"message": "Set freezing of %s: visible=%b freezing=%b visibleRequested=%b. %s",
"level": "INFO",
diff --git a/data/keyboards/Vendor_1038_Product_1434.kl b/data/keyboards/Vendor_1038_Product_1434.kl
new file mode 100644
index 000000000000..8182edd69ad4
--- /dev/null
+++ b/data/keyboards/Vendor_1038_Product_1434.kl
@@ -0,0 +1,58 @@
+# 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.
+
+#
+# SteelSeries Stratus+
+# Autogenerated based on Vendor_045e_Product_02ea.kl (XBox One Controller - Model 1708)
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 304 BUTTON_A
+key 305 BUTTON_B
+key 307 BUTTON_X
+key 308 BUTTON_Y
+
+key 310 BUTTON_L1
+key 311 BUTTON_R1
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Left and right stick.
+# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick actually
+# settles in a flat range of +/- 4096 or so.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x03 Z flat 4096
+axis 0x04 RZ flat 4096
+
+key 317 BUTTON_THUMBL
+key 318 BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 314 BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315 BUTTON_START
+
+# Xbox key
+key 316 BUTTON_MODE
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 596d0617e265..f4f5e1e792ec 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -50,6 +50,7 @@ import android.util.Base64;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.LruCache;
+import android.util.Pair;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
@@ -1396,6 +1397,41 @@ public class Typeface {
}
}
+ /**
+ * Change default typefaces for testing purpose.
+ *
+ * Note: The existing TextView or Paint instance still holds the old Typeface.
+ *
+ * @param defaults array of [default, default_bold, default_italic, default_bolditalic].
+ * @param genericFamilies array of [sans-serif, serif, monospace]
+ * @return return the old defaults and genericFamilies
+ * @hide
+ */
+ @TestApi
+ @NonNull
+ public static Pair<List<Typeface>, List<Typeface>> changeDefaultFontForTest(
+ @NonNull List<Typeface> defaults,
+ @NonNull List<Typeface> genericFamilies
+ ) {
+ synchronized (SYSTEM_FONT_MAP_LOCK) {
+ List<Typeface> oldDefaults = Arrays.asList(sDefaults);
+ sDefaults = defaults.toArray(new Typeface[4]);
+ setDefault(defaults.get(0));
+
+ ArrayList<Typeface> oldGenerics = new ArrayList<>();
+ oldGenerics.add(sSystemFontMap.get("sans-serif"));
+ sSystemFontMap.put("sans-serif", genericFamilies.get(0));
+
+ oldGenerics.add(sSystemFontMap.get("serif"));
+ sSystemFontMap.put("serif", genericFamilies.get(1));
+
+ oldGenerics.add(sSystemFontMap.get("monospace"));
+ sSystemFontMap.put("monospace", genericFamilies.get(2));
+
+ return new Pair<>(oldDefaults, oldGenerics);
+ }
+ }
+
static {
// Preload Roboto-Regular.ttf in Zygote for improving app launch performance.
preloadFontFile("/system/fonts/Roboto-Regular.ttf");
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 2f56b181f455..6939a72019e8 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -26,8 +26,6 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -39,8 +37,6 @@ import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
-import android.graphics.Shader;
-import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.PathParser;
@@ -106,7 +102,8 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
private static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);
/**
- * Clip path defined in R.string.config_icon_mask.
+ * Unused path.
+ * TODO: Remove once the layoutLib is updated
*/
private static Path sMask;
@@ -114,9 +111,10 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
* Scaled mask based on the view bounds.
*/
private final Path mMask;
- private final Path mMaskScaleOnly;
+ private final Path mMaskTransformed;
private final Matrix mMaskMatrix;
private final Region mTransparentRegion;
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
/**
* Indices used to access {@link #mLayerState.mChildDrawable} array for foreground and
@@ -131,19 +129,10 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
*/
LayerState mLayerState;
- private Shader mLayersShader;
- private Bitmap mLayersBitmap;
-
private final Rect mTmpOutRect = new Rect();
private Rect mHotspotBounds;
private boolean mMutated;
- private boolean mSuspendChildInvalidation;
- private boolean mChildRequestedInvalidation;
- private final Canvas mCanvas;
- private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG |
- Paint.FILTER_BITMAP_FLAG);
-
/**
* Constructor used for xml inflation.
*/
@@ -157,19 +146,16 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
*/
AdaptiveIconDrawable(@Nullable LayerState state, @Nullable Resources res) {
mLayerState = createConstantState(state, res);
- // config_icon_mask from context bound resource may have been chaged using
+ // config_icon_mask from context bound resource may have been changed using
// OverlayManager. Read that one first.
Resources r = ActivityThread.currentActivityThread() == null
? Resources.getSystem()
: ActivityThread.currentActivityThread().getApplication().getResources();
- // TODO: either make sMask update only when config_icon_mask changes OR
- // get rid of it all-together in layoutlib
- sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
- mMask = new Path(sMask);
- mMaskScaleOnly = new Path(mMask);
+ mMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
+ mMaskTransformed = new Path();
mMaskMatrix = new Matrix();
- mCanvas = new Canvas();
mTransparentRegion = new Region();
+ mPaint.setColor(Color.BLACK);
}
private ChildDrawable createChildDrawable(Drawable drawable) {
@@ -280,7 +266,7 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
* @return the mask path object used to clip the drawable
*/
public Path getIconMask() {
- return mMask;
+ return mMaskTransformed;
}
/**
@@ -322,92 +308,47 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
if (bounds.isEmpty()) {
return;
}
- updateLayerBounds(bounds);
- }
-
- private void updateLayerBounds(Rect bounds) {
- if (bounds.isEmpty()) {
- return;
- }
- try {
- suspendChildInvalidation();
- updateLayerBoundsInternal(bounds);
- updateMaskBoundsInternal(bounds);
- } finally {
- resumeChildInvalidation();
- }
- }
-
- /**
- * Set the child layer bounds bigger than the view port size by {@link #DEFAULT_VIEW_PORT_SCALE}
- */
- private void updateLayerBoundsInternal(Rect bounds) {
- int cX = bounds.width() / 2;
- int cY = bounds.height() / 2;
+ // Set the child layer bounds bigger than the view port size
+ // by {@link #DEFAULT_VIEW_PORT_SCALE}
+ float cX = bounds.exactCenterX();
+ float cY = bounds.exactCenterY();
+ float insetWidth = bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2);
+ float insetHeight = bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2);
+ final Rect outRect = mTmpOutRect;
+ outRect.set(
+ (int) (cX - insetWidth),
+ (int) (cY - insetHeight),
+ (int) (cX + insetWidth),
+ (int) (cY + insetHeight));
for (int i = 0, count = mLayerState.N_CHILDREN; i < count; i++) {
final ChildDrawable r = mLayerState.mChildren[i];
- final Drawable d = r.mDrawable;
- if (d == null) {
- continue;
+ if (r.mDrawable != null) {
+ r.mDrawable.setBounds(outRect);
}
-
- int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2));
- int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2));
- final Rect outRect = mTmpOutRect;
- outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight);
-
- d.setBounds(outRect);
}
- }
-
- private void updateMaskBoundsInternal(Rect b) {
- // reset everything that depends on the view bounds
- mMaskMatrix.setScale(b.width() / MASK_SIZE, b.height() / MASK_SIZE);
- sMask.transform(mMaskMatrix, mMaskScaleOnly);
- mMaskMatrix.postTranslate(b.left, b.top);
- sMask.transform(mMaskMatrix, mMask);
+ // Update the clipping mask
+ mMaskMatrix.setScale(bounds.width() / MASK_SIZE, bounds.height() / MASK_SIZE);
+ mMaskMatrix.postTranslate(bounds.left, bounds.top);
+ mMask.transform(mMaskMatrix, mMaskTransformed);
- if (mLayersBitmap == null || mLayersBitmap.getWidth() != b.width()
- || mLayersBitmap.getHeight() != b.height()) {
- mLayersBitmap = Bitmap.createBitmap(b.width(), b.height(), Bitmap.Config.ARGB_8888);
- }
-
- mPaint.setShader(null);
+ // Clear the transparent region, it is calculated lazily
mTransparentRegion.setEmpty();
- mLayersShader = null;
}
@Override
public void draw(Canvas canvas) {
- if (mLayersBitmap == null) {
- return;
+ int saveCount = canvas.save();
+ canvas.clipPath(mMaskTransformed);
+ canvas.drawPaint(mPaint);
+ if (mLayerState.mChildren[BACKGROUND_ID].mDrawable != null) {
+ mLayerState.mChildren[BACKGROUND_ID].mDrawable.draw(canvas);
}
- if (mLayersShader == null) {
- mCanvas.setBitmap(mLayersBitmap);
- mCanvas.drawColor(Color.BLACK);
- if (mLayerState.mChildren[BACKGROUND_ID].mDrawable != null) {
- mLayerState.mChildren[BACKGROUND_ID].mDrawable.draw(mCanvas);
- }
- if (mLayerState.mChildren[FOREGROUND_ID].mDrawable != null) {
- mLayerState.mChildren[FOREGROUND_ID].mDrawable.draw(mCanvas);
- }
- mLayersShader = new BitmapShader(mLayersBitmap, TileMode.CLAMP, TileMode.CLAMP);
- mPaint.setShader(mLayersShader);
- }
- if (mMaskScaleOnly != null) {
- Rect bounds = getBounds();
- canvas.translate(bounds.left, bounds.top);
- canvas.drawPath(mMaskScaleOnly, mPaint);
- canvas.translate(-bounds.left, -bounds.top);
+ if (mLayerState.mChildren[FOREGROUND_ID].mDrawable != null) {
+ mLayerState.mChildren[FOREGROUND_ID].mDrawable.draw(canvas);
}
- }
-
- @Override
- public void invalidateSelf() {
- mLayersShader = null;
- super.invalidateSelf();
+ canvas.restoreToCount(saveCount);
}
@Override
@@ -600,37 +541,9 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
return false;
}
- /**
- * Temporarily suspends child invalidation.
- *
- * @see #resumeChildInvalidation()
- */
- private void suspendChildInvalidation() {
- mSuspendChildInvalidation = true;
- }
-
- /**
- * Resumes child invalidation after suspension, immediately performing an
- * invalidation if one was requested by a child during suspension.
- *
- * @see #suspendChildInvalidation()
- */
- private void resumeChildInvalidation() {
- mSuspendChildInvalidation = false;
-
- if (mChildRequestedInvalidation) {
- mChildRequestedInvalidation = false;
- invalidateSelf();
- }
- }
-
@Override
public void invalidateDrawable(@NonNull Drawable who) {
- if (mSuspendChildInvalidation) {
- mChildRequestedInvalidation = true;
- } else {
- invalidateSelf();
- }
+ invalidateSelf();
}
@Override
@@ -714,6 +627,13 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
+ final ChildDrawable[] array = mLayerState.mChildren;
+ for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setAlpha(alpha);
+ }
+ }
}
@Override
@@ -816,10 +736,6 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
}
}
- if (changed) {
- updateLayerBounds(getBounds());
- }
-
return changed;
}
@@ -835,10 +751,6 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
}
}
- if (changed) {
- updateLayerBounds(getBounds());
- }
-
return changed;
}
@@ -979,6 +891,7 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
int mDensity;
// The density to use when inflating/looking up the children drawables. A value of 0 means
+
// use the system's density.
int mSrcDensityOverride = 0;
diff --git a/identity/java/android/security/identity/Util.java b/identity/java/android/security/identity/Util.java
index e56bd5167906..789ff06f064b 100644
--- a/identity/java/android/security/identity/Util.java
+++ b/identity/java/android/security/identity/Util.java
@@ -20,12 +20,12 @@ import android.annotation.NonNull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPoint;
-import java.util.Collection;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -36,15 +36,6 @@ import javax.crypto.spec.SecretKeySpec;
public class Util {
private static final String TAG = "Util";
- static int[] integerCollectionToArray(Collection<Integer> collection) {
- int[] result = new int[collection.size()];
- int n = 0;
- for (int item : collection) {
- result[n++] = item;
- }
- return result;
- }
-
static byte[] stripLeadingZeroes(byte[] value) {
int n = 0;
while (n < value.length && value[n] == 0) {
@@ -61,15 +52,47 @@ public class Util {
static byte[] publicKeyEncodeUncompressedForm(PublicKey publicKey) {
ECPoint w = ((ECPublicKey) publicKey).getW();
- // X and Y are always positive so for interop we remove any leading zeroes
- // inserted by the BigInteger encoder.
- byte[] x = stripLeadingZeroes(w.getAffineX().toByteArray());
- byte[] y = stripLeadingZeroes(w.getAffineY().toByteArray());
+ BigInteger x = w.getAffineX();
+ BigInteger y = w.getAffineY();
+ if (x.compareTo(BigInteger.ZERO) < 0) {
+ throw new RuntimeException("X is negative");
+ }
+ if (y.compareTo(BigInteger.ZERO) < 0) {
+ throw new RuntimeException("Y is negative");
+ }
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(0x04);
- baos.write(x);
- baos.write(y);
+
+ // Each coordinate may be encoded in 33*, 32, or fewer bytes.
+ //
+ // * : it can be 33 bytes because toByteArray() guarantees "The array will contain the
+ // minimum number of bytes required to represent this BigInteger, including at
+ // least one sign bit, which is (ceil((this.bitLength() + 1)/8))" which means that
+ // the MSB is always 0x00. This is taken care of by calling calling
+ // stripLeadingZeroes().
+ //
+ // We need the encoding to be exactly 32 bytes since according to RFC 5480 section 2.2
+ // and SEC 1: Elliptic Curve Cryptography section 2.3.3 the encoding is 0x04 | X | Y
+ // where X and Y are encoded in exactly 32 byte, big endian integer values each.
+ //
+ byte[] xBytes = stripLeadingZeroes(x.toByteArray());
+ if (xBytes.length > 32) {
+ throw new RuntimeException("xBytes is " + xBytes.length + " which is unexpected");
+ }
+ for (int n = 0; n < 32 - xBytes.length; n++) {
+ baos.write(0x00);
+ }
+ baos.write(xBytes);
+
+ byte[] yBytes = stripLeadingZeroes(y.toByteArray());
+ if (yBytes.length > 32) {
+ throw new RuntimeException("yBytes is " + yBytes.length + " which is unexpected");
+ }
+ for (int n = 0; n < 32 - yBytes.length; n++) {
+ baos.write(0x00);
+ }
+ baos.write(yBytes);
return baos.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Unexpected IOException", e);
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index c14c3c534cf4..5ab21bc5f489 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -237,6 +237,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
private final boolean mUnlockedDeviceRequired;
private final boolean mIsStrongBoxBacked;
private final int mMaxUsageCount;
+ private final boolean mRollbackResistant;
private KeyProtection(
Date keyValidityStart,
@@ -259,7 +260,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
boolean userConfirmationRequired,
boolean unlockedDeviceRequired,
boolean isStrongBoxBacked,
- int maxUsageCount) {
+ int maxUsageCount,
+ boolean rollbackResistant) {
mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -283,6 +285,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
mUnlockedDeviceRequired = unlockedDeviceRequired;
mIsStrongBoxBacked = isStrongBoxBacked;
mMaxUsageCount = maxUsageCount;
+ mRollbackResistant = rollbackResistant;
}
/**
@@ -563,6 +566,17 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
}
/**
+ * Returns {@code true} if the key is rollback-resistant, meaning that when deleted it is
+ * guaranteed to be permanently deleted and unusable.
+ *
+ * @see Builder#setRollbackResistant(boolean)
+ * @hide
+ */
+ public boolean isRollbackResistant() {
+ return mRollbackResistant;
+ }
+
+ /**
* Builder of {@link KeyProtection} instances.
*/
public final static class Builder {
@@ -591,6 +605,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
private boolean mIsStrongBoxBacked = false;
private int mMaxUsageCount = KeyProperties.UNRESTRICTED_USAGE_COUNT;
private String mAttestKeyAlias = null;
+ private boolean mRollbackResistant = false;
/**
* Creates a new instance of the {@code Builder}.
@@ -1097,6 +1112,21 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
}
/**
+ * Sets whether the key should be rollback-resistant, meaning that when deleted it is
+ * guaranteed to be permanently deleted and unusable. Not all implementations support
+ * rollback-resistant keys. This method is hidden because implementations only support a
+ * limited number of rollback-resistant keys; currently the available space is reserved for
+ * critical system keys.
+ *
+ * @hide
+ */
+ @NonNull
+ public Builder setRollbackResistant(boolean rollbackResistant) {
+ mRollbackResistant = rollbackResistant;
+ return this;
+ }
+
+ /**
* Builds an instance of {@link KeyProtection}.
*
* @throws IllegalArgumentException if a required field is missing
@@ -1124,7 +1154,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
mUserConfirmationRequired,
mUnlockedDeviceRequired,
mIsStrongBoxBacked,
- mMaxUsageCount);
+ mMaxUsageCount,
+ mRollbackResistant);
}
}
}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index 33411e1ec5b9..dfda356ec35b 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -783,6 +783,12 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
params.getMaxUsageCount()
));
}
+
+ if (params.isRollbackResistant()) {
+ importArgs.add(KeyStore2ParameterUtils.makeBool(
+ KeymasterDefs.KM_TAG_ROLLBACK_RESISTANT
+ ));
+ }
} catch (IllegalArgumentException | IllegalStateException e) {
throw new KeyStoreException(e);
}
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 3ff531573f1f..0dba6b0049c0 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -72,6 +72,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
@NonNull Configuration parentConfig);
void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
@NonNull IBinder activityToken);
+ void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType);
}
/**
@@ -323,4 +324,18 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
mCallback.onActivityReparentToTask(taskId, activityIntent, activityToken);
}
}
+
+ @Override
+ public void onTaskFragmentError(@NonNull IBinder errorCallbackToken,
+ @Nullable TaskFragmentInfo taskFragmentInfo,
+ int opType, @NonNull Throwable exception) {
+ if (taskFragmentInfo != null) {
+ final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
+ mFragmentInfos.put(fragmentToken, taskFragmentInfo);
+ }
+
+ if (mCallback != null) {
+ mCallback.onTaskFragmentError(taskFragmentInfo, opType);
+ }
+ }
}
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 da9fd0c2d96f..c688080ad929 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -19,6 +19,8 @@ package androidx.window.extensions.embedding;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior;
import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior;
@@ -296,6 +298,37 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
}
+ @Override
+ public void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType) {
+ synchronized (mLock) {
+ switch (opType) {
+ case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
+ case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: {
+ final TaskFragmentContainer container;
+ if (taskFragmentInfo != null) {
+ container = getContainer(taskFragmentInfo.getFragmentToken());
+ } else {
+ container = null;
+ }
+ if (container == null) {
+ break;
+ }
+
+ // Update the latest taskFragmentInfo and perform necessary clean-up
+ container.setInfo(taskFragmentInfo);
+ container.clearPendingAppearedActivities();
+ if (container.isEmpty()) {
+ mPresenter.cleanupContainer(container, false /* shouldFinishDependent */);
+ }
+ break;
+ }
+ default:
+ Log.e(TAG, "onTaskFragmentError: taskFragmentInfo = " + taskFragmentInfo
+ + ", opType = " + opType);
+ }
+ }
+ }
+
/** Called on receiving {@link #onTaskFragmentVanished(TaskFragmentInfo)} for cleanup. */
private void cleanupTaskFragment(@NonNull IBinder taskFragmentToken) {
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index a188e2bf4985..37f5b6dc399e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -193,6 +193,11 @@ class TaskFragmentContainer {
mPendingAppearedActivities.remove(pendingAppearedActivity);
}
+ void clearPendingAppearedActivities() {
+ mPendingAppearedActivities.clear();
+ mPendingAppearedIntent = null;
+ }
+
@Nullable
Intent getPendingAppearedIntent() {
return mPendingAppearedIntent;
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 6959a591338c..500ad5e5f977 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Instellings"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Gaan by verdeelde skerm in"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Kieslys"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in beeld-in-beeld"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"As jy nie wil hê dat <xliff:g id="NAME">%s</xliff:g> hierdie kenmerk moet gebruik nie, tik om instellings oop te maak en skakel dit af."</string>
<string name="pip_play" msgid="3496151081459417097">"Speel"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Program steun nie begin op sekondêre skerms nie."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Skermverdeler"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Volskerm links"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Links 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Links 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index fe22b2ce3278..2f4189dda164 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ቅንብሮች"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"የተከፈለ ማያ ገጽን አስገባ"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"ምናሌ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> በስዕል-ላይ-ስዕል ውስጥ ነው"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ይህን ባህሪ እንዲጠቀም ካልፈለጉ ቅንብሮችን ለመክፈት መታ ያድርጉና ያጥፉት።"</string>
<string name="pip_play" msgid="3496151081459417097">"አጫውት"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string>
<string name="accessibility_divider" msgid="703810061635792791">"የተከፈለ የማያ ገጽ ከፋይ"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"የግራ ሙሉ ማያ ገጽ"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ግራ 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ግራ 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 2be6f39f9475..1f5fc9dc0301 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"الإعدادات"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"الدخول في وضع تقسيم الشاشة"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"القائمة"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> يظهر في صورة داخل صورة"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"إذا كنت لا تريد أن يستخدم <xliff:g id="NAME">%s</xliff:g> هذه الميزة، فانقر لفتح الإعدادات، ثم أوقِف تفعيل هذه الميزة."</string>
<string name="pip_play" msgid="3496151081459417097">"تشغيل"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"قد لا يعمل التطبيق على شاشة عرض ثانوية."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"لا يمكن تشغيل التطبيق على شاشات عرض ثانوية."</string>
<string name="accessibility_divider" msgid="703810061635792791">"أداة تقسيم الشاشة"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"عرض النافذة اليسرى بملء الشاشة"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ضبط حجم النافذة اليسرى ليكون ٧٠%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ضبط حجم النافذة اليسرى ليكون ٥٠%"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 098ee84de018..ca3542e59954 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ছেটিং"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"বিভাজিত স্ক্ৰীন ম’ডলৈ যাওক"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"মেনু"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> চিত্ৰৰ ভিতৰৰ চিত্ৰত আছে"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"আপুনি যদি <xliff:g id="NAME">%s</xliff:g> সুবিধাটো ব্যৱহাৰ কৰিব নোখোজে, তেন্তে ছেটিং খুলিবলৈ টিপক আৰু তালৈ গৈ ইয়াক অফ কৰক।"</string>
<string name="pip_play" msgid="3496151081459417097">"প্লে কৰক"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"গৌণ ডিছপ্লেত এপে সঠিকভাৱে কাম নকৰিব পাৰে।"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"গৌণ ডিছপ্লেত এপ্ লঞ্চ কৰিব নোৱাৰি।"</string>
<string name="accessibility_divider" msgid="703810061635792791">"স্প্লিট স্ক্ৰীনৰ বিভাজক"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"বাওঁফালৰ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"বাওঁফালৰ স্ক্ৰীণখন ৭০% কৰক"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"বাওঁফালৰ স্ক্ৰীণখন ৫০% কৰক"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 2f49ae6fdafc..25390bc57c96 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -22,6 +22,7 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Ayarlar"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Bölünmüş ekrana daxil olun"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string>
+ <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Şəkildə Şəkil Menyusu"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> şəkil içində şəkildədir"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> tətbiqinin bu funksiyadan istifadə etməyini istəmirsinizsə, ayarları açmaq və deaktiv etmək üçün klikləyin."</string>
<string name="pip_play" msgid="3496151081459417097">"Oxudun"</string>
@@ -36,6 +37,7 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Tətbiq ikinci ekranda işləməyə bilər."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Tətbiq ikinci ekranda başlamağı dəstəkləmir."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcısı"</string>
+ <string name="divider_title" msgid="5482989479865361192">"Bölünmüş ekran ayırıcısı"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Sol tam ekran"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Sol 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sol 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 0656fe185013..f4cb20ba8811 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Podešavanja"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Uđi na podeljeni ekran"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je slika u slici"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da biste otvorili podešavanja i isključili je."</string>
<string name="pip_play" msgid="3496151081459417097">"Pusti"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Razdelnik podeljenog ekrana"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Režim celog ekrana za levi ekran"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Levi ekran 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi ekran 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 702f0abc07ae..f1b4ca539417 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Налады"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Падзяліць экран"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> з’яўляецца відарысам у відарысе"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Калі вы не хочаце, каб праграма <xliff:g id="NAME">%s</xliff:g> выкарыстоўвала гэту функцыю, дакраніцеся, каб адкрыць налады і адключыць яе."</string>
<string name="pip_play" msgid="3496151081459417097">"Прайграць"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Праграма можа не працаваць на дадатковых экранах."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Праграма не падтрымлівае запуск на дадатковых экранах."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Раздзяляльнік падзеленага экрана"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Левы экран – поўнаэкранны рэжым"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Левы экран – 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левы экран – 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 0de16d37cd69..f7fbb3e794a4 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Настройки"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Преминаване към разделен екран"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> е в режима „Картина в картината“"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ако не искате <xliff:g id="NAME">%s</xliff:g> да използва тази функция, докоснете, за да отворите настройките, и я изключете."</string>
<string name="pip_play" msgid="3496151081459417097">"Пускане"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Възможно е приложението да не работи на алтернативни дисплеи."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложението не поддържа използването на алтернативни дисплеи."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Разделител в режима за разделен екран"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ляв екран: Показване на цял екран"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ляв екран: 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ляв екран: 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 9a48d186b231..0cb2f5e0c59e 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"সেটিংস"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"\'স্প্লিট স্ক্রিন\' মোড চালু করুন"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"মেনু"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"ছবির-মধ্যে-ছবি তে <xliff:g id="NAME">%s</xliff:g> আছেন"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> কে এই বৈশিষ্ট্যটি ব্যবহার করতে দিতে না চাইলে ট্যাপ করে সেটিংসে গিয়ে সেটি বন্ধ করে দিন।"</string>
<string name="pip_play" msgid="3496151081459417097">"চালান"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"সেকেন্ডারি ডিসপ্লেতে অ্যাপটি কাজ নাও করতে পারে।"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"সেকেন্ডারি ডিসপ্লেতে অ্যাপ লঞ্চ করা যাবে না।"</string>
<string name="accessibility_divider" msgid="703810061635792791">"বিভক্ত-স্ক্রিন বিভাজক"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"বাঁ দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"৭০% বাকি আছে"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"৫০% বাকি আছে"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 31e906de7f51..c7086f14eaf9 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Postavke"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Otvori podijeljeni ekran"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je u načinu priakza Slika u slici"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da otvorite postavke i isključite je."</string>
<string name="pip_play" msgid="3496151081459417097">"Reproduciraj"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće raditi na sekundarnom ekranu."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik ekrana"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lijevo cijeli ekran"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Lijevo 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevo 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index ca0a4211c435..1bb1d089be05 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Configuració"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Entra al mode de pantalla dividida"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> està en pantalla en pantalla"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string>
<string name="pip_play" msgid="3496151081459417097">"Reprodueix"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'aplicació no es pot obrir en pantalles secundàries."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalles"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla esquerra completa"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Pantalla esquerra al 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pantalla esquerra al 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index e8772fe269b6..def3f4f67605 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Nastavení"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Aktivovat rozdělenou obrazovku"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Nabídka"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"Aplikace <xliff:g id="NAME">%s</xliff:g> je v režimu obraz v obraze"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Pokud nechcete, aby aplikace <xliff:g id="NAME">%s</xliff:g> tuto funkci používala, klepnutím otevřete nastavení a funkci vypněte."</string>
<string name="pip_play" msgid="3496151081459417097">"Přehrát"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikace na sekundárním displeji nemusí fungovat."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikace nepodporuje spuštění na sekundárních displejích."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Čára rozdělující obrazovku"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Levá část na celou obrazovku"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % vlevo"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % vlevo"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 2b55d4d688ac..6eedb83fcdd1 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Indstillinger"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Åbn opdelt skærm"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> vises som integreret billede"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Hvis du ikke ønsker, at <xliff:g id="NAME">%s</xliff:g> skal benytte denne funktion, kan du åbne indstillingerne og deaktivere den."</string>
<string name="pip_play" msgid="3496151081459417097">"Afspil"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer muligvis ikke på sekundære skærme."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke åbnes på sekundære skærme."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Adskiller til opdelt skærm"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vis venstre del i fuld skærm"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Venstre 70 %"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Venstre 50 %"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 03eee024f3be..fce0bd4c51cc 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Einstellungen"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"„Geteilter Bildschirm“ aktivieren"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ist in Bild im Bild"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Wenn du nicht möchtest, dass <xliff:g id="NAME">%s</xliff:g> diese Funktion verwendet, tippe, um die Einstellungen zu öffnen und die Funktion zu deaktivieren."</string>
<string name="pip_play" msgid="3496151081459417097">"Wiedergeben"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Die App unterstützt den Start auf sekundären Displays nicht."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Bildschirmteiler"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vollbild links"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % links"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % links"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 49bfdf18b1e6..cef433815534 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -22,6 +22,7 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Ρυθμίσεις"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Μετάβαση σε διαχωρισμό οθόνης"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Μενού"</string>
+ <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Μενού λειτουργίας Picture-in-Picture"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"Η λειτουργία picture-in-picture είναι ενεργή σε <xliff:g id="NAME">%s</xliff:g>."</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Εάν δεν θέλετε να χρησιμοποιείται αυτή η λειτουργία από την εφαρμογή <xliff:g id="NAME">%s</xliff:g>, πατήστε για να ανοίξετε τις ρυθμίσεις και απενεργοποιήστε την."</string>
<string name="pip_play" msgid="3496151081459417097">"Αναπαραγωγή"</string>
@@ -36,6 +37,7 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Η εφαρμογή ίσως να μην λειτουργήσει σε δευτερεύουσα οθόνη."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Η εφαρμογή δεν υποστηρίζει την εκκίνηση σε δευτερεύουσες οθόνες."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Διαχωριστικό οθόνης"</string>
+ <string name="divider_title" msgid="5482989479865361192">"Διαχωριστικό οθόνης"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Αριστερή πλήρης οθόνη"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Αριστερή 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Αριστερή 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 081a01a49249..6a226edb7346 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -22,6 +22,7 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
<string name="pip_play" msgid="3496151081459417097">"Play"</string>
@@ -36,6 +37,7 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string>
+ <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 081a01a49249..6a226edb7346 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -22,6 +22,7 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
<string name="pip_play" msgid="3496151081459417097">"Play"</string>
@@ -36,6 +37,7 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string>
+ <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 081a01a49249..6a226edb7346 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -22,6 +22,7 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
<string name="pip_play" msgid="3496151081459417097">"Play"</string>
@@ -36,6 +37,7 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string>
+ <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 081a01a49249..6a226edb7346 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -22,6 +22,7 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
<string name="pip_play" msgid="3496151081459417097">"Play"</string>
@@ -36,6 +37,7 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string>
+ <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index afc14b821d62..7a3738988776 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -22,6 +22,7 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎Settings‎‏‎‎‏‎"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‏‎Enter split screen‎‏‎‎‏‎"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎Menu‎‏‎‎‏‎"</string>
+ <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎Picture-in-Picture Menu‎‏‎‎‏‎"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ is in picture-in-picture‎‏‎‎‏‎"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎If you don\'t want ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ to use this feature, tap to open settings and turn it off.‎‏‎‎‏‎"</string>
<string name="pip_play" msgid="3496151081459417097">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎Play‎‏‎‎‏‎"</string>
@@ -36,6 +37,7 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎App may not work on a secondary display.‎‏‎‎‏‎"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎App does not support launch on secondary displays.‎‏‎‎‏‎"</string>
<string name="accessibility_divider" msgid="703810061635792791">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‏‏‏‎Split-screen divider‎‏‎‎‏‎"</string>
+ <string name="divider_title" msgid="5482989479865361192">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎Split-screen divider‎‏‎‎‏‎"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎Left full screen‎‏‎‎‏‎"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎Left 70%‎‏‎‎‏‎"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎Left 50%‎‏‎‎‏‎"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index b376b7881333..77626afffd6a 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Configuración"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Introducir pantalla dividida"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está en modo de Pantalla en pantalla"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> use esta función, presiona para abrir la configuración y desactivarla."</string>
<string name="pip_play" msgid="3496151081459417097">"Reproducir"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la app no funcione en una pantalla secundaria."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La app no puede iniciarse en pantallas secundarias."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla izquierda completa"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Izquierda: 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda: 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 79c1f90a4b8d..f813324cca4c 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Ajustes"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Introducir pantalla dividida"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está en imagen en imagen"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca la notificación para abrir los ajustes y desactivarla."</string>
<string name="pip_play" msgid="3496151081459417097">"Reproducir"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la aplicación no funcione en una pantalla secundaria."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La aplicación no se puede abrir en pantallas secundarias."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Dividir la pantalla"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla izquierda completa"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Izquierda 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index a7fead6af9aa..9d9e5bc33b8d 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Seaded"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Ava jagatud ekraanikuva"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menüü"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> on režiimis Pilt pildis"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Kui te ei soovi, et rakendus <xliff:g id="NAME">%s</xliff:g> seda funktsiooni kasutaks, puudutage seadete avamiseks ja lülitage see välja."</string>
<string name="pip_play" msgid="3496151081459417097">"Esita"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Rakendus ei pruugi teisesel ekraanil töötada."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Rakendus ei toeta teisestel ekraanidel käivitamist."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Ekraanijagaja"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vasak täisekraan"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vasak: 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasak: 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index e7530c9690a7..5894a0ec731f 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Ezarpenak"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Sartu pantaila zatituan"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menua"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"Pantaila txiki gainjarrian dago <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea nahi ez baduzu, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string>
<string name="pip_play" msgid="3496151081459417097">"Erreproduzitu"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikazioa ezin da abiarazi bigarren mailako pantailatan."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Pantaila-zatitzailea"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ezarri ezkerraldea pantaila osoan"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ezarri ezkerraldea % 70en"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ezarri ezkerraldea % 50en"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 66a657e36c13..bc003ccde4eb 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"تنظیمات"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"ورود به حالت «صفحهٔ دونیمه»"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"منو"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> درحالت تصویر در تصویر است"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"اگر نمی‌خواهید <xliff:g id="NAME">%s</xliff:g> از این قابلیت استفاده کند، با ضربه زدن، تنظیمات را باز کنید و آن را خاموش کنید."</string>
<string name="pip_play" msgid="3496151081459417097">"پخش"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن است برنامه در نمایشگر ثانویه کار نکند."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"برنامه از راه‌اندازی در نمایشگرهای ثانویه پشتیبانی نمی‌کند."</string>
<string name="accessibility_divider" msgid="703810061635792791">"تقسیم‌کننده صفحه"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"تمام‌صفحه چپ"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"٪۷۰ چپ"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"٪۵۰ چپ"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index eaf369ad0486..2735be2d50fc 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Asetukset"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Avaa jaettu näyttö"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Valikko"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> on kuva kuvassa ‑tilassa"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Jos et halua, että <xliff:g id="NAME">%s</xliff:g> voi käyttää tätä ominaisuutta, avaa asetukset napauttamalla ja poista se käytöstä."</string>
<string name="pip_play" msgid="3496151081459417097">"Toista"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Sovellus ei ehkä toimi toissijaisella näytöllä."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Sovellus ei tue käynnistämistä toissijaisilla näytöillä."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Näytön jakaja"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vasen koko näytölle"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vasen 70 %"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasen 50 %"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 8f614c56db14..f016134fbbff 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Paramètres"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Entrer dans l\'écran partagé"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> est en mode d\'incrustation d\'image"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Si vous ne voulez pas que <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalité, touchez l\'écran pour ouvrir les paramètres, puis désactivez-la."</string>
<string name="pip_play" msgid="3496151081459417097">"Lire"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Plein écran à la gauche"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % à la gauche"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % à la gauche"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index ec3e1b33a4fa..f1f8abe77d4c 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Paramètres"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Accéder à l\'écran partagé"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> est en mode Picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Si vous ne voulez pas que l\'application <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalité, appuyez ici pour ouvrir les paramètres et la désactiver."</string>
<string name="pip_play" msgid="3496151081459417097">"Lecture"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Écran de gauche en plein écran"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Écran de gauche à 70 %"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Écran de gauche à 50 %"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 651353d89319..60674249f4d4 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Configuración"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Inserir pantalla dividida"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está na pantalla superposta"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Se non queres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca a configuración para abrir as opcións e desactivar a función."</string>
<string name="pip_play" msgid="3496151081459417097">"Reproducir"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É posible que a aplicación non funcione nunha pantalla secundaria."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A aplicación non se pode iniciar en pantallas secundarias."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla completa á esquerda"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % á esquerda"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % á esquerda"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 3543be0bda07..4e4d41c4faf0 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"સેટિંગ"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"વિભાજિત સ્ક્રીન મોડમાં દાખલ થાઓ"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"મેનૂ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ચિત્રમાં-ચિત્રની અંદર છે"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"જો તમે નથી ઇચ્છતા કે <xliff:g id="NAME">%s</xliff:g> આ સુવિધાનો ઉપયોગ કરે, તો સેટિંગ ખોલવા માટે ટૅપ કરો અને તેને બંધ કરો."</string>
<string name="pip_play" msgid="3496151081459417097">"ચલાવો"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર કદાચ કામ ન કરે."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર લૉન્ચનું સમર્થન કરતી નથી."</string>
<string name="accessibility_divider" msgid="703810061635792791">"સ્પ્લિટ-સ્ક્રીન વિભાજક"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ડાબી પૂર્ણ સ્ક્રીન"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ડાબે 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ડાબે 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 87ac5d64ff85..dad0db833bd3 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"सेटिंग"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रीन मोड में जाएं"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"मेन्यू"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"पिक्चर में पिक्चर\" के अंदर है"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"अगर आप नहीं चाहते कि <xliff:g id="NAME">%s</xliff:g> इस सुविधा का उपयोग करे, तो सेटिंग खोलने के लिए टैप करें और उसे बंद करें ."</string>
<string name="pip_play" msgid="3496151081459417097">"चलाएं"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर ऐप लॉन्च नहीं किया जा सकता."</string>
<string name="accessibility_divider" msgid="703810061635792791">"विभाजित स्क्रीन विभाजक"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"बाईं स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"बाईं स्क्रीन को 70% बनाएं"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बाईं स्क्रीन को 50% बनाएं"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index cb4f424cf317..ad25eb941d99 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Postavke"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Otvorite podijeljeni zaslon"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Izbornik"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> jest na slici u slici"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da aplikacija <xliff:g id="NAME">%s</xliff:g> upotrebljava tu značajku, dodirnite da biste otvorili postavke i isključili je."</string>
<string name="pip_play" msgid="3496151081459417097">"Reproduciraj"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionirati na sekundarnom zaslonu."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim zaslonima."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik podijeljenog zaslona"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lijevi zaslon u cijeli zaslon"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Lijevi zaslon na 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevi zaslon na 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 635f4dad8f89..9b657b140db4 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Beállítások"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Váltás osztott képernyőre"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"A(z) <xliff:g id="NAME">%s</xliff:g> kép a képben funkciót használ"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ha nem szeretné, hogy a(z) <xliff:g id="NAME">%s</xliff:g> használja ezt a funkciót, koppintson a beállítások megnyitásához, és kapcsolja ki."</string>
<string name="pip_play" msgid="3496151081459417097">"Lejátszás"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Elválasztó az osztott nézetben"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Bal oldali teljes képernyőre"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Bal oldali 70%-ra"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Bal oldali 50%-ra"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index da382c113797..41bcb8f16e7a 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Կարգավորումներ"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Մտնել տրոհված էկրանի ռեժիմ"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Ընտրացանկ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>-ը «Նկար նկարի մեջ» ռեժիմում է"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Եթե չեք ցանկանում, որ <xliff:g id="NAME">%s</xliff:g>-ն օգտագործի այս գործառույթը, հպեք՝ կարգավորումները բացելու և այն անջատելու համար։"</string>
<string name="pip_play" msgid="3496151081459417097">"Նվագարկել"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Հավելվածը կարող է չաշխատել լրացուցիչ էկրանի վրա"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Հավելվածը չի աջակցում գործարկումը լրացուցիչ էկրանների վրա"</string>
<string name="accessibility_divider" msgid="703810061635792791">"Տրոհված էկրանի բաժանիչ"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ձախ էկրանը՝ լիաէկրան"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ձախ էկրանը՝ 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ձախ էկրանը՝ 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index cd795390128b..0245b459a763 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Setelan"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Masuk ke mode layar terpisah"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> adalah picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, ketuk untuk membuka setelan dan menonaktifkannya."</string>
<string name="pip_play" msgid="3496151081459417097">"Putar"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikasi mungkin tidak berfungsi pada layar sekunder."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikasi tidak mendukung peluncuran pada layar sekunder."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Pembagi layar terpisah"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Layar penuh di kiri"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kiri 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 37141b74005c..bcae730231f8 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Stillingar"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Opna skjáskiptingu"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Valmynd"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> er með mynd í mynd"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ef þú vilt ekki að <xliff:g id="NAME">%s</xliff:g> noti þennan eiginleika skaltu ýta til að opna stillingarnar og slökkva á því."</string>
<string name="pip_play" msgid="3496151081459417097">"Spila"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Hugsanlegt er að forritið virki ekki á öðrum skjá."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Forrit styður ekki opnun á öðrum skjá."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Skjáskipting"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vinstri á öllum skjánum"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vinstri 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vinstri 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index b63e76466b6e..0f586a722ebf 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Impostazioni"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Accedi a schermo diviso"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> è in Picture in picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Se non desideri che l\'app <xliff:g id="NAME">%s</xliff:g> utilizzi questa funzione, tocca per aprire le impostazioni e disattivarla."</string>
<string name="pip_play" msgid="3496151081459417097">"Riproduci"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"L\'app potrebbe non funzionare su un display secondario."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'app non supporta l\'avvio su display secondari."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Strumento per schermo diviso"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Schermata sinistra a schermo intero"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Schermata sinistra al 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Schermata sinistra al 50%"</string>
@@ -72,8 +76,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestisci"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Fumetto ignorato."</string>
- <!-- no translation found for restart_button_description (6712141648865547958) -->
- <skip />
+ <string name="restart_button_description" msgid="6712141648865547958">"Tocca per riavviare quest\'app per una migliore visualizzazione."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi con la fotocamera?\nTocca per risolverli"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Il problema non si è risolto?\nTocca per ripristinare"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nessun problema con la fotocamera? Tocca per ignorare."</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 0e500eafd805..16aa4df76930 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"הגדרות"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"כניסה למסך המפוצל"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"תפריט"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> במצב תמונה בתוך תמונה"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"אם אינך רוצה שהתכונה הזו תשמש את <xliff:g id="NAME">%s</xliff:g>, יש להקיש כדי לפתוח את ההגדרות ולהשבית את התכונה."</string>
<string name="pip_play" msgid="3496151081459417097">"הפעלה"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ייתכן שהאפליקציה לא תפעל במסך משני."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"האפליקציה אינה תומכת בהפעלה במסכים משניים."</string>
<string name="accessibility_divider" msgid="703810061635792791">"מחלק מסך מפוצל"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"מסך שמאלי מלא"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"שמאלה 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"שמאלה 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 34ed9c72da0e..67f58b8867f9 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"分割画面に切り替え"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"メニュー"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>はピクチャー イン ピクチャーで表示中です"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g>でこの機能を使用しない場合は、タップして設定を開いて OFF にしてください。"</string>
<string name="pip_play" msgid="3496151081459417097">"再生"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"アプリはセカンダリ ディスプレイでは動作しないことがあります。"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"アプリはセカンダリ ディスプレイでの起動に対応していません。"</string>
<string name="accessibility_divider" msgid="703810061635792791">"分割画面の分割線"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"左全画面"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"左 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 14b26c1932cc..9220a36f56be 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"პარამეტრები"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"გაყოფილ ეკრანში შესვლა"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"მენიუ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> იყენებს რეჟიმს „ეკრანი ეკრანში“"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"თუ არ გსურთ, რომ <xliff:g id="NAME">%s</xliff:g> ამ ფუნქციას იყენებდეს, აქ შეხებით შეგიძლიათ გახსნათ პარამეტრები და გამორთოთ ის."</string>
<string name="pip_play" msgid="3496151081459417097">"დაკვრა"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"აპმა შეიძლება არ იმუშაოს მეორეულ ეკრანზე."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"აპს არ გააჩნია მეორეული ეკრანის მხარდაჭერა."</string>
<string name="accessibility_divider" msgid="703810061635792791">"გაყოფილი ეკრანის რეჟიმის გამყოფი"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"მარცხენა ნაწილის სრულ ეკრანზე გაშლა"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"მარცხენა ეკრანი — 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"მარცხენა ეკრანი — 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index c42efdc4cf25..9ccd5f2c7ee5 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Параметрлер"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Бөлінген экранға кіру"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Mәзір"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"суреттегі сурет\" режимінде"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> деген пайдаланушының бұл мүмкіндікті пайдалануын қаламасаңыз, параметрлерді түртіп ашыңыз да, оларды өшіріңіз."</string>
<string name="pip_play" msgid="3496151081459417097">"Ойнату"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Қолданба қосымша дисплейде жұмыс істемеуі мүмкін."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Қолданба қосымша дисплейлерде іске қосуды қолдамайды."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Бөлінген экран бөлгіші"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Сол жағын толық экранға шығару"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% сол жақта"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% сол жақта"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 302b25e5bad2..fbf7add21a39 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ការកំណត់"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"ចូលមុខងារ​បំបែកអេក្រង់"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"ម៉ឺនុយ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ស្ថិតក្នុងមុខងាររូបក្នុងរូប"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"ប្រសិនបើ​អ្នក​មិន​ចង់​ឲ្យ <xliff:g id="NAME">%s</xliff:g> ប្រើ​មុខងារ​នេះ​ សូមចុច​​បើក​ការកំណត់ រួច​បិទ​វា។"</string>
<string name="pip_play" msgid="3496151081459417097">"លេង"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"កម្មវិធីនេះ​ប្រហែល​ជាមិនដំណើរការ​នៅលើ​អេក្រង់បន្ទាប់បន្សំទេ។"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"កម្មវិធី​នេះមិន​អាច​ចាប់ផ្តើម​នៅលើ​អេក្រង់បន្ទាប់បន្សំបានទេ។"</string>
<string name="accessibility_divider" msgid="703810061635792791">"កម្មវិធីចែកអេក្រង់បំបែក"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"អេក្រង់ពេញខាងឆ្វេង"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ឆ្វេង 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ឆ្វេង 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 2b3aa0791336..62a2d52d8265 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"ಸ್ಪ್ಲಿಟ್‌-ಸ್ಕ್ರೀನ್‌ಗೆ ಪ್ರವೇಶಿಸಿ"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"ಮೆನು"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವಾಗಿದೆ"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ಈ ವೈಶಿಷ್ಟ್ಯ ಬಳಸುವುದನ್ನು ನೀವು ಬಯಸದಿದ್ದರೆ, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಲು ಮತ್ತು ಅದನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="pip_play" msgid="3496151081459417097">"ಪ್ಲೇ"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ಸೆಕೆಂಡರಿ ಡಿಸ್‌ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ ಕಾರ್ಯ ನಿರ್ವಹಿಸದೇ ಇರಬಹುದು."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ಸೆಕೆಂಡರಿ ಡಿಸ್‌ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
<string name="accessibility_divider" msgid="703810061635792791">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ಎಡ ಪೂರ್ಣ ಪರದೆ"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% ಎಡಕ್ಕೆ"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% ಎಡಕ್ಕೆ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 5505955db71a..82c80b81adcf 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"설정"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"화면 분할 모드로 전환"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"메뉴"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>에서 PIP 사용 중"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g>에서 이 기능이 사용되는 것을 원하지 않는 경우 탭하여 설정을 열고 기능을 사용 중지하세요."</string>
<string name="pip_play" msgid="3496151081459417097">"재생"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"앱이 보조 디스플레이에서 작동하지 않을 수도 있습니다."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"앱이 보조 디스플레이에서의 실행을 지원하지 않습니다."</string>
<string name="accessibility_divider" msgid="703810061635792791">"화면 분할기"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"왼쪽 화면 전체화면"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"왼쪽 화면 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"왼쪽 화면 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index d45a9848abc4..0b1f83ffcb6e 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Жөндөөлөр"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Экранды бөлүү режимине өтүү"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> – сүрөт ичиндеги сүрөт"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, жөндөөлөрдү ачып туруп, аны өчүрүп коюңуз."</string>
<string name="pip_play" msgid="3496151081459417097">"Ойнотуу"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Колдонмо кошумча экранда иштебей коюшу мүмкүн."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Колдонмону кошумча экрандарда иштетүүгө болбойт."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Экранды бөлгүч"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Сол жактагы экранды толук экран режимине өткөрүү"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Сол жактагы экранды 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Сол жактагы экранды 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 0eeee906070b..ec468a5b625d 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ການຕັ້ງຄ່າ"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"ເຂົ້າການແບ່ງໜ້າຈໍ"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"ເມນູ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ແມ່ນເປັນການສະແດງຜົນຫຼາຍຢ່າງພ້ອມກັນ"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"ຫາກທ່ານບໍ່ຕ້ອງການ <xliff:g id="NAME">%s</xliff:g> ໃຫ້ໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ແຕະເພື່ອເປີດການຕັ້ງຄ່າ ແລ້ວປິດມັນໄວ້."</string>
<string name="pip_play" msgid="3496151081459417097">"ຫຼິ້ນ"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ໃນໜ້າຈໍທີສອງ."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ແອັບບໍ່ຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string>
<string name="accessibility_divider" msgid="703810061635792791">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ເຕັມໜ້າຈໍຊ້າຍ"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ຊ້າຍ 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ຊ້າຍ 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index fc118e217481..fdb51fcca7ee 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Nustatymai"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Įjungti išskaidyto ekrano režimą"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Meniu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> rodom. vaizdo vaizde"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Jei nenorite, kad „<xliff:g id="NAME">%s</xliff:g>“ naudotų šią funkciją, palietę atidarykite nustatymus ir išjunkite ją."</string>
<string name="pip_play" msgid="3496151081459417097">"Leisti"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Programa gali neveikti antriniame ekrane."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programa nepalaiko paleisties antriniuose ekranuose."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Skaidyto ekrano daliklis"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Kairysis ekranas viso ekrano režimu"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kairysis ekranas 70 %"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kairysis ekranas 50 %"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index cd2af07beb7e..ca666cea722b 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Iestatījumi"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Piekļūt ekrāna sadalīšanas režīmam"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Izvēlne"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ir attēlā attēlā"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ja nevēlaties lietotnē <xliff:g id="NAME">%s</xliff:g> izmantot šo funkciju, pieskarieties, lai atvērtu iestatījumus un izslēgtu funkciju."</string>
<string name="pip_play" msgid="3496151081459417097">"Atskaņot"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Lietotne, iespējams, nedarbosies sekundārajā displejā."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Lietotnē netiek atbalstīta palaišana sekundārajos displejos."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Ekrāna sadalītājs"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Kreisā daļa pa visu ekrānu"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Pa kreisi 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pa kreisi 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index c0dff00e6a7c..64b1cbcb5343 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Поставки"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Влези во поделен екран"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Мени"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> е во слика во слика"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ако не сакате <xliff:g id="NAME">%s</xliff:g> да ја користи функцијава, допрете за да ги отворите поставките и да ја исклучите."</string>
<string name="pip_play" msgid="3496151081459417097">"Пушти"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликацијата може да не функционира на друг екран."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликацијата не поддржува стартување на други екрани."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Разделник на поделен екран"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Левиот на цел екран"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Левиот 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левиот 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 52ea1c7c3150..6b6af060f93a 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ക്രമീകരണം"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"സ്ക്രീൻ വിഭജന മോഡിൽ പ്രവേശിക്കുക"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"മെനു"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ചിത്രത്തിനുള്ളിൽ ചിത്രം രീതിയിലാണ്"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ഈ ഫീച്ചർ ഉപയോഗിക്കേണ്ടെങ്കിൽ, ടാപ്പ് ചെയ്‌ത് ക്രമീകരണം തുറന്ന് അത് ഓഫാക്കുക."</string>
<string name="pip_play" msgid="3496151081459417097">"പ്ലേ ചെയ്യുക"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"രണ്ടാം ഡിസ്‌പ്ലേയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"രണ്ടാം ഡിസ്‌പ്ലേകളിൽ സമാരംഭിക്കുന്നതിനെ ആപ്പ് അനുവദിക്കുന്നില്ല."</string>
<string name="accessibility_divider" msgid="703810061635792791">"സ്പ്ലിറ്റ്-സ്ക്രീൻ ഡിവൈഡർ"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ഇടത് പൂർണ്ണ സ്ക്രീൻ"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ഇടത് 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ഇടത് 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index fd4c4aab1832..2cb48c2c81e1 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Тохиргоо"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Хуваасан дэлгэцийг оруулна уу"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Цэс"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> дэлгэцэн доторх дэлгэцэд байна"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Та <xliff:g id="NAME">%s</xliff:g>-д энэ онцлогийг ашиглуулахыг хүсэхгүй байвал тохиргоог нээгээд, үүнийг унтраана уу."</string>
<string name="pip_play" msgid="3496151081459417097">"Тоглуулах"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апп хоёрдогч дэлгэцэд ажиллахгүй."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Аппыг хоёрдогч дэлгэцэд эхлүүлэх боломжгүй."</string>
<string name="accessibility_divider" msgid="703810061635792791">"\"Дэлгэц хуваах\" хуваагч"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Зүүн талын бүтэн дэлгэц"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Зүүн 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Зүүн 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index b9a165eb6b11..73c709f8f6c4 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"सेटिंग्ज"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रीन एंटर करा"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"मेनू"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> चित्रामध्ये चित्र मध्ये आहे"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g>ने हे वैशिष्ट्य वापरू नये असे तुम्हाला वाटत असल्यास, सेटिंग्ज उघडण्यासाठी टॅप करा आणि ते बंद करा."</string>
<string name="pip_play" msgid="3496151081459417097">"प्ले करा"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"दुसऱ्या डिस्प्लेवर अ‍ॅप कदाचित चालणार नाही."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"दुसऱ्या डिस्प्लेवर अ‍ॅप लाँच होणार नाही."</string>
<string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रीन विभाजक"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"डावी फुल स्क्रीन"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"डावी 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"डावी 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 3d81c9a551fa..4368684936ac 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Tetapan"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Masuk skrin pisah"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> terdapat dalam gambar dalam gambar"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Jika anda tidak mahu <xliff:g id="NAME">%s</xliff:g> menggunakan ciri ini, ketik untuk membuka tetapan dan matikan ciri."</string>
<string name="pip_play" msgid="3496151081459417097">"Main"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Apl mungkin tidak berfungsi pada paparan kedua."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Apl tidak menyokong pelancaran pada paparan kedua."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Pembahagi skrin pisah"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Skrin penuh kiri"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kiri 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 50adfe98d8f9..be61336e0383 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ဆက်တင်များ"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသို့ ဝင်ရန်"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"မီနူး"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> သည် နှစ်ခုထပ်၍ကြည့်ခြင်း ဖွင့်ထားသည်"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> အား ဤဝန်ဆောင်မှုကို အသုံးမပြုစေလိုလျှင် ဆက်တင်ကိုဖွင့်ရန် တို့ပြီး ၎င်းဝန်ဆောင်မှုကို ပိတ်လိုက်ပါ။"</string>
<string name="pip_play" msgid="3496151081459417097">"ဖွင့်ရန်"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ဤအက်ပ်အနေဖြင့် ဖွင့်ရန်စနစ်ကို ဒုတိယဖန်သားပြင်မှ အသုံးပြုရန် ပံ့ပိုးမထားပါ။"</string>
<string name="accessibility_divider" msgid="703810061635792791">"မျက်နှာပြင်ခွဲခြမ်း ပိုင်းခြားပေးသည့်စနစ်"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ဘယ်ဘက် မျက်နှာပြင်အပြည့်"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ဘယ်ဘက်မျက်နှာပြင် ၇၀%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ဘယ်ဘက် မျက်နှာပြင် ၅၀%"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 74e066ec11fd..ae771e5dc00d 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Innstillinger"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Aktivér delt skjerm"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Meny"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> er i bilde-i-bilde"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Hvis du ikke vil at <xliff:g id="NAME">%s</xliff:g> skal bruke denne funksjonen, kan du trykke for å åpne innstillingene og slå den av."</string>
<string name="pip_play" msgid="3496151081459417097">"Spill av"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer kanskje ikke på en sekundær skjerm."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke kjøres på sekundære skjermer."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Skilleelement for delt skjerm"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Utvid den venstre delen av skjermen til hele skjermen"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Sett størrelsen på den venstre delen av skjermen til 70 %"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sett størrelsen på den venstre delen av skjermen til 50 %"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index b257f9e6d0d3..692e985ef5ce 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"सेटिङहरू"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रिन मोड प्रयोग गर्नुहोस्"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"मेनु"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> Picture-in-picture मा छ"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"तपाईं <xliff:g id="NAME">%s</xliff:g> ले सुविधा प्रयोग नगरोस् भन्ने चाहनुहुन्छ भने ट्याप गरेर सेटिङहरू खोल्नुहोस् र यसलाई निष्क्रिय पार्नुहोस्।"</string>
<string name="pip_play" msgid="3496151081459417097">"प्ले गर्नुहोस्"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"यो एपले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string>
<string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रिन छुट्याउने"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"बायाँ भाग फुल स्क्रिन"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"बायाँ भाग ७०%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बायाँ भाग ५०%"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 6ea24a8b3808..55c62aec467c 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Instellingen"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Gesplitst scherm openen"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in scherm-in-scherm"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Als je niet wilt dat <xliff:g id="NAME">%s</xliff:g> deze functie gebruikt, tik je om de instellingen te openen en zet je de functie uit."</string>
<string name="pip_play" msgid="3496151081459417097">"Afspelen"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App werkt mogelijk niet op een secundair scherm."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App kan niet op secundaire displays worden gestart."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Scheiding voor gesplitst scherm"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Linkerscherm op volledig scherm"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Linkerscherm 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Linkerscherm 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index f8c924828d50..1cfda264a093 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ସେଟିଂସ୍"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ମୋଡ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"ମେନୁ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"ଛବି-ଭିତରେ-ଛବି\"ରେ ଅଛି"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"ଏହି ବୈଶିଷ୍ଟ୍ୟ <xliff:g id="NAME">%s</xliff:g> ବ୍ୟବହାର ନକରିବାକୁ ଯଦି ଆପଣ ଚାହାଁନ୍ତି, ସେଟିଙ୍ଗ ଖୋଲିବାକୁ ଟାପ୍‍ କରନ୍ତୁ ଏବଂ ଏହା ଅଫ୍‍ କରିଦିଅନ୍ତୁ।"</string>
<string name="pip_play" msgid="3496151081459417097">"ପ୍ଲେ କରନ୍ତୁ"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍‍ କାମ ନକରିପାରେ।"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍‍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string>
<string name="accessibility_divider" msgid="703810061635792791">"ସ୍ପ୍ଲିଟ୍‍-ସ୍କ୍ରୀନ ବିଭାଜକ"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ବାମ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍ କରନ୍ତୁ"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ବାମ ପଟକୁ 70% କରନ୍ତୁ"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ବାମ ପଟକୁ 50% କରନ୍ତୁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index b80da0ba4e57..5c0c60182915 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ਸੈਟਿੰਗਾਂ"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"ਮੀਨੂ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ਤਸਵੀਰ-ਅੰਦਰ-ਤਸਵੀਰ ਵਿੱਚ ਹੈ"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"ਜੇਕਰ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
<string name="pip_play" msgid="3496151081459417097">"ਚਲਾਓ"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
<string name="accessibility_divider" msgid="703810061635792791">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ਖੱਬੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ਖੱਬੇ 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ਖੱਬੇ 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index bdd44dd8a743..1879649ae8bd 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Ustawienia"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Włącz podzielony ekran"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"Aplikacja <xliff:g id="NAME">%s</xliff:g> działa w trybie obraz w obrazie"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Jeśli nie chcesz, by aplikacja <xliff:g id="NAME">%s</xliff:g> korzystała z tej funkcji, otwórz ustawienia i wyłącz ją."</string>
<string name="pip_play" msgid="3496151081459417097">"Odtwórz"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacja może nie działać na dodatkowym ekranie."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Linia dzielenia ekranu"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lewa część ekranu na pełnym ekranie"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% lewej części ekranu"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% lewej części ekranu"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index b9e41eae5de9..d3fb14da2824 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Configurações"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Dividir tela"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está em picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Se você não quer que o app <xliff:g id="NAME">%s</xliff:g> use este recurso, toque para abrir as configurações e desativá-lo."</string>
<string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lado esquerdo em tela cheia"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Esquerda a 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index c1e57d8c9c97..1d78dcb16f2f 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Definições"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Aceder ao ecrã dividido"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"A app <xliff:g id="NAME">%s</xliff:g> está no modo de ecrã no ecrã"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Se não pretende que a app <xliff:g id="NAME">%s</xliff:g> utilize esta funcionalidade, toque para abrir as definições e desative-a."</string>
<string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"A app pode não funcionar num ecrã secundário."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A app não é compatível com o início em ecrãs secundários."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Divisor do ecrã dividido"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ecrã esquerdo inteiro"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% no ecrã esquerdo"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% no ecrã esquerdo"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index b9e41eae5de9..d3fb14da2824 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Configurações"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Dividir tela"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está em picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Se você não quer que o app <xliff:g id="NAME">%s</xliff:g> use este recurso, toque para abrir as configurações e desativá-lo."</string>
<string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lado esquerdo em tela cheia"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Esquerda a 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index c49bf9dc231c..7aaa21b18bd9 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Setări"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Accesați ecranul împărțit"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Meniu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> este în modul picture-in-picture"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Dacă nu doriți ca <xliff:g id="NAME">%s</xliff:g> să utilizeze această funcție, atingeți pentru a deschide setările și dezactivați-o."</string>
<string name="pip_play" msgid="3496151081459417097">"Redați"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplicația nu acceptă lansare pe ecrane secundare."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Separator pentru ecranul împărțit"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Partea stângă pe ecran complet"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Partea stângă: 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Partea stângă: 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index ffe031d86725..7270449bdfea 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Настройки"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Включить разделение экрана"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> находится в режиме \"Картинка в картинке\""</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Чтобы отключить эту функцию для приложения \"<xliff:g id="NAME">%s</xliff:g>\", перейдите в настройки."</string>
<string name="pip_play" msgid="3496151081459417097">"Воспроизвести"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Приложение может не работать на дополнительном экране"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложение не поддерживает запуск на дополнительных экранах"</string>
<string name="accessibility_divider" msgid="703810061635792791">"Разделитель экрана"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Левый во весь экран"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Левый на 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левый на 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index b27e1b9bc94a..ef25c0ad3480 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"සැකසීම්"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"බෙදුම් තිරයට ඇතුළු වන්න"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"මෙනුව"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> පින්තූරය-තුළ-පින්තූරය තුළ වේ"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"ඔබට <xliff:g id="NAME">%s</xliff:g> මෙම විශේෂාංගය භාවිත කිරීමට අවශ්‍ය නැති නම්, සැකසීම් විවෘත කිරීමට තට්ටු කර එය ක්‍රියාවිරහිත කරන්න."</string>
<string name="pip_play" msgid="3496151081459417097">"ධාවනය කරන්න"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"යෙදුම ද්විතියික සංදර්ශකයක ක්‍රියා නොකළ හැකිය."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"යෙදුම ද්විතීයික සංදර්ශක මත දියත් කිරීම සඳහා සහාය නොදක්වයි."</string>
<string name="accessibility_divider" msgid="703810061635792791">"බෙදුම්-තිර වෙන්කරණය"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"වම් පූර්ණ තිරය"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"වම් 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"වම් 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index b5bedf79f3ba..069bd1d2d5b6 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Nastavenia"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Prejsť na rozdelenú obrazovku"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Ponuka"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je v režime obraz v obraze"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ak nechcete, aby aplikácia <xliff:g id="NAME">%s</xliff:g> používala túto funkciu, klepnutím otvorte nastavenia a vypnite ju."</string>
<string name="pip_play" msgid="3496151081459417097">"Prehrať"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikácia nemusí fungovať na sekundárnej obrazovke."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikácia nepodporuje spúšťanie na sekundárnych obrazovkách."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Rozdeľovač obrazovky"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ľavá – na celú obrazovku"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ľavá – 70 %"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ľavá – 50 %"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index ac926b9ee8db..fe5813eb266f 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Nastavitve"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Vklopi razdeljen zaslon"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je v načinu slika v sliki"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Če ne želite, da aplikacija <xliff:g id="NAME">%s</xliff:g> uporablja to funkcijo, se dotaknite, da odprete nastavitve, in funkcijo izklopite."</string>
<string name="pip_play" msgid="3496151081459417097">"Predvajaj"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija morda ne bo delovala na sekundarnem zaslonu."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podpira zagona na sekundarnih zaslonih."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Razdelilnik zaslonov"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Levi v celozaslonski način"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Levi 70 %"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi 50 %"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 07c52fe4251a..79c5334380fe 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Cilësimet"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Hyr në ekranin e ndarë"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menyja"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> është në figurë brenda figurës"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Nëse nuk dëshiron që <xliff:g id="NAME">%s</xliff:g> ta përdorë këtë funksion, trokit për të hapur cilësimet dhe për ta çaktivizuar."</string>
<string name="pip_play" msgid="3496151081459417097">"Luaj"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacioni mund të mos funksionojë në një ekran dytësor."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacioni nuk mbështet nisjen në ekrane dytësore."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Ndarësi i ekranit të ndarë"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ekrani i plotë majtas"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Majtas 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Majtas 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 0289dd105ee5..a1b8e03868ec 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Подешавања"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Уђи на подељени екран"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Мени"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> је слика у слици"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ако не желите да <xliff:g id="NAME">%s</xliff:g> користи ову функцију, додирните да бисте отворили подешавања и искључили је."</string>
<string name="pip_play" msgid="3496151081459417097">"Пусти"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликација можда неће функционисати на секундарном екрану."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликација не подржава покретање на секундарним екранима."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Разделник подељеног екрана"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Режим целог екрана за леви екран"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Леви екран 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Леви екран 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index cfdb1ddcf377..90e2acf40e36 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Inställningar"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Starta delad skärm"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Meny"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> visas i bild-i-bild"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Om du inte vill att den här funktionen används i <xliff:g id="NAME">%s</xliff:g> öppnar du inställningarna genom att trycka. Sedan inaktiverar du funktionen."</string>
<string name="pip_play" msgid="3496151081459417097">"Spela upp"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen kanske inte fungerar på en sekundär skärm."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan inte köras på en sekundär skärm."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Avdelare för delad skärm"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Helskärm på vänster skärm"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vänster 70 %"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vänster 50 %"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 383e9bb6bbfa..b231ce0152d8 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Mipangilio"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Weka skrini iliyogawanywa"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> iko katika hali ya picha ndani ya picha nyingine"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Ikiwa hutaki <xliff:g id="NAME">%s</xliff:g> itumie kipengele hiki, gusa ili ufungue mipangilio na uizime."</string>
<string name="pip_play" msgid="3496151081459417097">"Cheza"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Huenda programu isifanye kazi kwenye dirisha lingine."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Kitenganishi cha skrini inayogawanywa"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Skrini nzima ya kushoto"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kushoto 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kushoto 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index cc512f3c48aa..e12868bc897a 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"அமைப்புகள்"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"திரைப் பிரிப்பு பயன்முறைக்குச் செல்"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"மெனு"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> தற்போது பிக்ச்சர்-இன்-பிக்ச்சரில் உள்ளது"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால் இங்கு தட்டி அமைப்புகளைத் திறந்து இதை முடக்கவும்."</string>
<string name="pip_play" msgid="3496151081459417097">"இயக்கு"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"இரண்டாம்நிலைத் திரையில் ஆப்ஸ் வேலை செய்யாமல் போகக்கூடும்."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"இரண்டாம்நிலைத் திரைகளில் பயன்பாட்டைத் தொடங்க முடியாது."</string>
<string name="accessibility_divider" msgid="703810061635792791">"திரையைப் பிரிக்கும் பிரிப்பான்"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"இடது புறம் முழுத் திரை"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"இடது புறம் 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"இடது புறம் 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index cdbe021add47..305229e8932c 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"సెట్టింగ్‌లు"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"స్ప్లిట్ స్క్రీన్‌ను ఎంటర్ చేయండి"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"మెనూ"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> చిత్రంలో చిత్రం రూపంలో ఉంది"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి ట్యాప్ చేసి, దీన్ని ఆఫ్ చేయండి."</string>
<string name="pip_play" msgid="3496151081459417097">"ప్లే చేయి"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ప్రత్యామ్నాయ డిస్‌ప్లేలో యాప్ పని చేయకపోవచ్చు."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ప్రత్యామ్నాయ డిస్‌ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string>
<string name="accessibility_divider" msgid="703810061635792791">"విభజన స్క్రీన్ విభాగిని"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ఎడమవైపు ఫుల్-స్క్రీన్‌"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ఎడమవైపు 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ఎడమవైపు 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 136a81c06c4f..ed7e75acbac4 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"การตั้งค่า"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"เข้าสู่โหมดแบ่งหน้าจอ"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"เมนู"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ใช้การแสดงภาพซ้อนภาพ"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้ฟีเจอร์นี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดฟีเจอร์"</string>
<string name="pip_play" msgid="3496151081459417097">"เล่น"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"แอปอาจไม่ทำงานในจอแสดงผลรอง"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"แอปไม่รองรับการเรียกใช้ในจอแสดงผลรอง"</string>
<string name="accessibility_divider" msgid="703810061635792791">"เส้นแบ่งหน้าจอ"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"เต็มหน้าจอทางซ้าย"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ซ้าย 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ซ้าย 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 4d32af36cabe..261bc742df72 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Mga Setting"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Pumasok sa split screen"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"Nasa picture-in-picture ang <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Kung ayaw mong magamit ni <xliff:g id="NAME">%s</xliff:g> ang feature na ito, i-tap upang buksan ang mga setting at i-off ito."</string>
<string name="pip_play" msgid="3496151081459417097">"I-play"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Maaaring hindi gumana ang app sa pangalawang display."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Hindi sinusuportahan ng app ang paglulunsad sa mga pangalawang display."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Divider ng split-screen"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"I-full screen ang nasa kaliwa"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Gawing 70% ang nasa kaliwa"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Gawing 50% ang nasa kaliwa"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index f3ab37065270..8c9b2c9508de 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Ayarlar"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Bölünmüş ekrana geç"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>, pencere içinde pencere özelliğini kullanıyor"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> uygulamasının bu özelliği kullanmasını istemiyorsanız dokunarak ayarları açın ve söz konusu özelliği kapatın."</string>
<string name="pip_play" msgid="3496151081459417097">"Oynat"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uygulama ikincil ekranda çalışmayabilir."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uygulama ikincil ekranlarda başlatılmayı desteklemiyor."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcı"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Solda tam ekran"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Solda %70"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Solda %50"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index d7d82cb56ac5..db548ebb8110 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Налаштування"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Розділити екран"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"У додатку <xliff:g id="NAME">%s</xliff:g> є функція \"Картинка в картинці\""</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Щоб додаток <xliff:g id="NAME">%s</xliff:g> не використовував цю функцію, вимкніть її в налаштуваннях."</string>
<string name="pip_play" msgid="3496151081459417097">"Відтворити"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Додаток може не працювати на додатковому екрані."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Додаток не підтримує запуск на додаткових екранах."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Розділювач екрана"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ліве вікно на весь екран"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ліве вікно на 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ліве вікно на 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 4a8476aebe18..ea63e9d55aa3 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"ترتیبات"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"اسپلٹ اسکرین تک رسائی"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"مینو"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> تصویر میں تصویر میں ہے"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"اگر آپ نہیں چاہتے ہیں کہ <xliff:g id="NAME">%s</xliff:g> اس خصوصیت کا استعمال کرے تو ترتیبات کھولنے کے لیے تھپتھپا کر اسے آف کرے۔"</string>
<string name="pip_play" msgid="3496151081459417097">"چلائیں"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن ہے ایپ ثانوی ڈسپلے پر کام نہ کرے۔"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی۔"</string>
<string name="accessibility_divider" msgid="703810061635792791">"سپلٹ اسکرین تقسیم کار"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"بائیں فل اسکرین"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"بائیں %70"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"بائیں %50"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 8a4eac3bb657..a334b0ec6669 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Sozlamalar"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Ajratilgan ekranga kirish"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> tasvir ustida tasvir rejimida"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ilovasi uchun bu funksiyani sozlamalar orqali faolsizlantirish mumkin."</string>
<string name="pip_play" msgid="3496151081459417097">"Ijro"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Ekranni ikkiga bo‘lish chizig‘i"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Chapda to‘liq ekran"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Chapda 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Chapda 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 2f8fe6076c68..03f500ac3ece 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Cài đặt"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Truy cập chế độ chia đôi màn hình"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> đang ở chế độ ảnh trong ảnh"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Nếu bạn không muốn <xliff:g id="NAME">%s</xliff:g> sử dụng tính năng này, hãy nhấn để mở cài đặt và tắt tính năng này."</string>
<string name="pip_play" msgid="3496151081459417097">"Phát"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Ứng dụng có thể không hoạt động trên màn hình phụ."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Ứng dụng không hỗ trợ khởi chạy trên màn hình phụ."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Bộ chia chia đôi màn hình"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Toàn màn hình bên trái"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Trái 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Trái 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index ab44fb1d2488..2b04f6e35c4e 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"设置"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"进入分屏模式"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"菜单"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>目前位于“画中画”中"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"如果您不想让“<xliff:g id="NAME">%s</xliff:g>”使用此功能,请点按以打开设置,然后关闭此功能。"</string>
<string name="pip_play" msgid="3496151081459417097">"播放"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"应用可能无法在辅显示屏上正常运行。"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"应用不支持在辅显示屏上启动。"</string>
<string name="accessibility_divider" msgid="703810061635792791">"分屏分隔线"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"左侧全屏"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"左侧 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左侧 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 8fb7adebe930..253869b0a871 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"進入分割螢幕"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"選單"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"「<xliff:g id="NAME">%s</xliff:g>」目前在畫中畫模式"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"如果您不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string>
<string name="pip_play" msgid="3496151081459417097">"播放"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示屏上運作。"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示屏上啟動。"</string>
<string name="accessibility_divider" msgid="703810061635792791">"分割畫面分隔線"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"左邊全螢幕"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"左邊 70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左邊 50%"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 45de4156084b..6109cbb7f5ab 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"進入分割畫面"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"選單"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"「<xliff:g id="NAME">%s</xliff:g>」目前在子母畫面中"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"如果你不想讓「<xliff:g id="NAME">%s</xliff:g>」使用這項功能,請輕觸開啟設定頁面,然後停用此功能。"</string>
<string name="pip_play" msgid="3496151081459417097">"播放"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示器上運作。"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示器上啟動。"</string>
<string name="accessibility_divider" msgid="703810061635792791">"分割畫面分隔線"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"以全螢幕顯示左側畫面"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"以 70% 的螢幕空間顯示左側畫面"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"以 50% 的螢幕空間顯示左側畫面"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 7c31a166e825..8af4f9fd5be3 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -22,6 +22,8 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Izilungiselelo"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Faka ukuhlukanisa isikrini"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Imenyu"</string>
+ <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+ <skip />
<string name="pip_notification_title" msgid="1347104727641353453">"U-<xliff:g id="NAME">%s</xliff:g> ungaphakathi kwesithombe esiphakathi kwesithombe"</string>
<string name="pip_notification_message" msgid="8854051911700302620">"Uma ungafuni i-<xliff:g id="NAME">%s</xliff:g> ukuthi isebenzise lesi sici, thepha ukuze uvule izilungiselelo uphinde uyivale."</string>
<string name="pip_play" msgid="3496151081459417097">"Dlala"</string>
@@ -36,6 +38,8 @@
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uhlelo lokusebenza kungenzeka lungasebenzi kusibonisi sesibili."</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uhlelo lokusebenza alusekeli ukuqalisa kuzibonisi zesibili."</string>
<string name="accessibility_divider" msgid="703810061635792791">"Isihlukanisi sokuhlukanisa isikrini"</string>
+ <!-- no translation found for divider_title (5482989479865361192) -->
+ <skip />
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Isikrini esigcwele esingakwesokunxele"</string>
<string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kwesokunxele ngo-70%"</string>
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kwesokunxele ngo-50%"</string>
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 f85f9d63a827..5dd51499ef19 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
@@ -411,8 +411,8 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
- static PipSurfaceTransactionHelper providePipSurfaceTransactionHelper() {
- return new PipSurfaceTransactionHelper();
+ static PipSurfaceTransactionHelper providePipSurfaceTransactionHelper(Context context) {
+ return new PipSurfaceTransactionHelper(context);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
index cc741d3896a2..35a309a8352c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
@@ -27,6 +27,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Trace;
+import android.view.Choreographer;
import androidx.annotation.Nullable;
@@ -144,6 +145,25 @@ public abstract class WMShellConcurrencyModule {
}
/**
+ * Provide a Shell main-thread {@link Choreographer} with the app vsync.
+ *
+ * @param executor the executor of the shell main thread
+ */
+ @WMSingleton
+ @Provides
+ @ShellMainThread
+ public static Choreographer provideShellMainChoreographer(
+ @ShellMainThread ShellExecutor executor) {
+ try {
+ final Choreographer[] choreographer = new Choreographer[1];
+ executor.executeBlocking(() -> choreographer[0] = Choreographer.getInstance());
+ return choreographer[0];
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Failed to obtain main Choreographer.", e);
+ }
+ }
+
+ /**
* Provide a Shell animation-thread Executor.
*/
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 0f33f4c08e9c..0dc293b0265f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.pm.LauncherApps;
import android.os.Handler;
import android.os.UserManager;
+import android.view.Choreographer;
import android.view.WindowManager;
import com.android.internal.jank.InteractionJankMonitor;
@@ -173,12 +174,14 @@ public abstract class WMShellModule {
static WindowDecorViewModel<?> provideWindowDecorViewModel(
Context context,
@ShellMainThread Handler mainHandler,
+ @ShellMainThread Choreographer mainChoreographer,
ShellTaskOrganizer taskOrganizer,
DisplayController displayController,
SyncTransactionQueue syncQueue) {
return new CaptionWindowDecorViewModel(
context,
mainHandler,
+ mainChoreographer,
taskOrganizer,
displayController,
syncQueue);
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 c0bc108baada..3ac08a66100a 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
@@ -39,6 +39,10 @@ public class PipSurfaceTransactionHelper {
private int mCornerRadius;
private int mShadowRadius;
+ public PipSurfaceTransactionHelper(Context context) {
+ onDensityOrFontScaleChanged(context);
+ }
+
/**
* Called when display size or font size of settings changed
*
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index da88c2de6c01..1155ea174ed1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -62,6 +62,7 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -444,7 +445,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
// When exit to fullscreen with Shell transition enabled, we update the Task windowing
// mode directly so that it can also trigger display rotation and visibility update in
// the same transition if there will be any.
- wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ wct.setWindowingMode(mToken, getOutPipWindowingMode());
// We can inherit the parent bounds as it is going to be fullscreen. The
// destinationBounds calculated above will be incorrect if this is with rotation.
wct.setBounds(mToken, null);
@@ -543,7 +544,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mToken, null);
- wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ wct.setWindowingMode(mToken, getOutPipWindowingMode());
wct.reorder(mToken, false);
mPipTransitionController.startExitTransition(TRANSIT_REMOVE_PIP, wct,
null /* destinationBounds */);
@@ -930,6 +931,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
/** Called when exiting PIP transition is finished to do the state cleanup. */
void onExitPipFinished(TaskInfo info) {
+ if (mLeash == null) {
+ // TODO(239461594): Remove once the double call to onExitPipFinished() is fixed
+ Log.w(TAG, "Warning, onExitPipFinished() called multiple times in the same sessino");
+ return;
+ }
+
clearWaitForFixedRotation();
if (mSwipePipToHomeOverlay != null) {
removeContentOverlay(mSwipePipToHomeOverlay, null /* callback */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 53ec39d954c4..7fb961fc0761 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -352,41 +352,31 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
public void startIntent(PendingIntent intent, @Nullable Intent fillInIntent,
@SplitPosition int position, @Nullable Bundle options) {
+ if (fillInIntent == null) {
+ fillInIntent = new Intent();
+ }
+ // Flag this as a no-user-action launch to prevent sending user leaving event to the
+ // current top activity since it's going to be put into another side of the split. This
+ // prevents the current top activity from going into pip mode due to user leaving event.
+ fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
+
+ // Flag with MULTIPLE_TASK if this is launching the same activity into both sides of the
+ // split.
+ if (isLaunchingAdjacently(intent.getIntent(), position)) {
+ fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
+ }
+
if (!ENABLE_SHELL_TRANSITIONS) {
startIntentLegacy(intent, fillInIntent, position, options);
return;
}
- try {
- options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options,
- null /* wct */);
-
- if (fillInIntent == null) {
- fillInIntent = new Intent();
- }
- // Flag this as a no-user-action launch to prevent sending user leaving event to the
- // current top activity since it's going to be put into another side of the split. This
- // prevents the current top activity from going into pip mode due to user leaving event.
- fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
-
- // Flag with MULTIPLE_TASK if this is launching the same activity into both sides of the
- // split.
- if (isLaunchingAdjacently(intent.getIntent(), position)) {
- fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
- }
-
- intent.send(mContext, 0, fillInIntent, null /* onFinished */, null /* handler */,
- null /* requiredPermission */, options);
- } catch (PendingIntent.CanceledException e) {
- Slog.e(TAG, "Failed to launch task", e);
- }
+ mStageCoordinator.startIntent(intent, fillInIntent, position, options);
}
- private void startIntentLegacy(PendingIntent intent, @Nullable Intent fillInIntent,
+ private void startIntentLegacy(PendingIntent intent, Intent fillInIntent,
@SplitPosition int position, @Nullable Bundle options) {
- boolean startSameActivityAdjacently = isLaunchingAdjacently(intent.getIntent(), position);
-
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
mStageCoordinator.prepareEvictChildTasks(position, evictWct);
@@ -397,8 +387,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
IRemoteAnimationFinishedCallback finishedCallback,
SurfaceControl.Transaction t) {
if (apps == null || apps.length == 0) {
- if (startSameActivityAdjacently) {
- // Switch split position if dragging the same activity to another side.
+ // Switch the split position if launching as MULTIPLE_TASK failed.
+ if ((fillInIntent.getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
setSideStagePosition(SplitLayout.reversePosition(
mStageCoordinator.getSideStagePosition()));
}
@@ -408,8 +398,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return;
}
- mStageCoordinator.updateSurfaceBounds(null /* layout */, t,
- false /* applyResizingOffset */);
for (int i = 0; i < apps.length; ++i) {
if (apps[i].mode == MODE_OPENING) {
t.show(apps[i].leash);
@@ -432,18 +420,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
final WindowContainerTransaction wct = new WindowContainerTransaction();
options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, wct);
- // Flag this as a no-user-action launch to prevent sending user leaving event to the current
- // top activity since it's going to be put into another side of the split. This prevents the
- // current top activity from going into pip mode due to user leaving event.
- if (fillInIntent == null) {
- fillInIntent = new Intent();
- }
- fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
- if (startSameActivityAdjacently) {
- fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
- }
-
wct.sendPendingIntent(intent, fillInIntent, options);
mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index 056cd5813861..83bdf8bfb727 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -62,13 +62,12 @@ class SplitScreenTransitions {
private final Runnable mOnFinish;
DismissTransition mPendingDismiss = null;
- IBinder mPendingEnter = null;
- IBinder mPendingRecent = null;
+ TransitSession mPendingEnter = null;
+ TransitSession mPendingRecent = null;
private IBinder mAnimatingTransition = null;
OneShotRemoteHandler mPendingRemoteHandler = null;
private OneShotRemoteHandler mActiveRemoteHandler = null;
- private boolean mEnterTransitionMerged;
private final Transitions.TransitionFinishCallback mRemoteFinishCB = this::onFinish;
@@ -145,7 +144,7 @@ class SplitScreenTransitions {
continue;
}
- if (transition == mPendingEnter && (mainRoot.equals(change.getContainer())
+ if (isPendingEnter(transition) && (mainRoot.equals(change.getContainer())
|| sideRoot.equals(change.getContainer()))) {
t.setPosition(leash, change.getEndAbsBounds().left, change.getEndAbsBounds().top);
t.setWindowCrop(leash, change.getEndAbsBounds().width(),
@@ -171,12 +170,40 @@ class SplitScreenTransitions {
onFinish(null /* wct */, null /* wctCB */);
}
+ boolean isPendingTransition(IBinder transition) {
+ return isPendingEnter(transition)
+ || isPendingDismiss(transition)
+ || isPendingRecent(transition);
+ }
+
+ boolean isPendingEnter(IBinder transition) {
+ return mPendingEnter != null && mPendingEnter.mTransition == transition;
+ }
+
+ boolean isPendingRecent(IBinder transition) {
+ return mPendingRecent != null && mPendingRecent.mTransition == transition;
+ }
+
+ boolean isPendingDismiss(IBinder transition) {
+ return mPendingDismiss != null && mPendingDismiss.mTransition == transition;
+ }
+
/** Starts a transition to enter split with a remote transition animator. */
- IBinder startEnterTransition(@WindowManager.TransitionType int transitType,
- @NonNull WindowContainerTransaction wct, @Nullable RemoteTransition remoteTransition,
- @NonNull Transitions.TransitionHandler handler) {
+ IBinder startEnterTransition(
+ @WindowManager.TransitionType int transitType,
+ WindowContainerTransaction wct,
+ @Nullable RemoteTransition remoteTransition,
+ Transitions.TransitionHandler handler,
+ @Nullable TransitionCallback callback) {
final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
- mPendingEnter = transition;
+ setEnterTransition(transition, remoteTransition, callback);
+ return transition;
+ }
+
+ /** Sets a transition to enter split. */
+ void setEnterTransition(@NonNull IBinder transition,
+ @Nullable RemoteTransition remoteTransition, @Nullable TransitionCallback callback) {
+ mPendingEnter = new TransitSession(transition, callback);
if (remoteTransition != null) {
// Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
@@ -184,7 +211,9 @@ class SplitScreenTransitions {
mTransitions.getMainExecutor(), remoteTransition);
mPendingRemoteHandler.setTransition(transition);
}
- return transition;
+
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
+ + " deduced Enter split screen");
}
/** Starts a transition to dismiss split. */
@@ -209,8 +238,8 @@ class SplitScreenTransitions {
}
void setRecentTransition(@NonNull IBinder transition,
- @Nullable RemoteTransition remoteTransition) {
- mPendingRecent = transition;
+ @Nullable RemoteTransition remoteTransition, @Nullable TransitionCallback callback) {
+ mPendingRecent = new TransitSession(transition, callback);
if (remoteTransition != null) {
// Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
@@ -226,6 +255,18 @@ class SplitScreenTransitions {
void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
IBinder mergeTarget, Transitions.TransitionFinishCallback finishCallback) {
if (mergeTarget != mAnimatingTransition) return;
+
+ if (isPendingEnter(transition) && isPendingRecent(mergeTarget)) {
+ mPendingRecent.mCallback = new TransitionCallback() {
+ @Override
+ public void onTransitionFinished(WindowContainerTransaction finishWct,
+ SurfaceControl.Transaction finishT) {
+ // Since there's an entering transition merged, recent transition no longer
+ // need to handle entering split screen after the transition finished.
+ }
+ };
+ }
+
if (mActiveRemoteHandler != null) {
mActiveRemoteHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
} else {
@@ -247,38 +288,55 @@ class SplitScreenTransitions {
}
void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
- if (aborted) return;
+ if (isPendingEnter(transition)) {
+ if (!aborted) {
+ // An enter transition got merged, appends the rest operations to finish entering
+ // split screen.
+ // TODO (b/238856352): Passed-in the proper finish transition to merge instead.
+ if (mFinishTransaction == null) {
+ mFinishTransaction = mTransactionPool.acquire();
+ }
+ mStageCoordinator.finishEnterSplitScreen(mFinishTransaction);
+ }
- // Once a pending enter transition got merged, make sure to append the reset of finishing
- // operations to the finish transition.
- if (transition == mPendingEnter) {
- mFinishTransaction = mTransactionPool.acquire();
- mStageCoordinator.finishEnterSplitScreen(mFinishTransaction);
+ mPendingEnter.mCallback.onTransitionConsumed(aborted);
mPendingEnter = null;
mPendingRemoteHandler = null;
- mEnterTransitionMerged = true;
+ } else if (isPendingDismiss(transition)) {
+ mPendingDismiss.mCallback.onTransitionConsumed(aborted);
+ mPendingDismiss = null;
+ } else if (isPendingRecent(transition)) {
+ mPendingRecent.mCallback.onTransitionConsumed(aborted);
+ mPendingRecent = null;
+ mPendingRemoteHandler = null;
}
}
void onFinish(WindowContainerTransaction wct, WindowContainerTransactionCallback wctCB) {
if (!mAnimations.isEmpty()) return;
- if (mAnimatingTransition == mPendingEnter) {
+
+ TransitionCallback callback = null;
+ if (isPendingEnter(mAnimatingTransition)) {
+ callback = mPendingEnter.mCallback;
mPendingEnter = null;
}
- if (mPendingDismiss != null && mPendingDismiss.mTransition == mAnimatingTransition) {
+ if (isPendingDismiss(mAnimatingTransition)) {
+ callback = mPendingDismiss.mCallback;
mPendingDismiss = null;
}
- if (mAnimatingTransition == mPendingRecent) {
- if (!mEnterTransitionMerged) {
- if (wct == null) wct = new WindowContainerTransaction();
- mStageCoordinator.onRecentTransitionFinished(wct, mFinishTransaction);
- }
+ if (isPendingRecent(mAnimatingTransition)) {
+ callback = mPendingRecent.mCallback;
mPendingRecent = null;
}
+
+ if (callback != null) {
+ if (wct == null) wct = new WindowContainerTransaction();
+ callback.onTransitionFinished(wct, mFinishTransaction);
+ }
+
mPendingRemoteHandler = null;
mActiveRemoteHandler = null;
mAnimatingTransition = null;
- mEnterTransitionMerged = false;
mOnFinish.run();
if (mFinishTransaction != null) {
@@ -382,17 +440,34 @@ class SplitScreenTransitions {
|| info.getType() == TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
}
- /** Bundled information of dismiss transition. */
- static class DismissTransition {
- IBinder mTransition;
+ /** Clean-up callbacks for transition. */
+ interface TransitionCallback {
+ /** Calls when the transition got consumed. */
+ default void onTransitionConsumed(boolean aborted) {}
+
+ /** Calls when the transition finished. */
+ default void onTransitionFinished(WindowContainerTransaction finishWct,
+ SurfaceControl.Transaction finishT) {}
+ }
- int mReason;
+ /** Session for a transition and its clean-up callback. */
+ static class TransitSession {
+ final IBinder mTransition;
+ TransitionCallback mCallback;
- @SplitScreen.StageType
- int mDismissTop;
+ TransitSession(IBinder transition, @Nullable TransitionCallback callback) {
+ mTransition = transition;
+ mCallback = callback != null ? callback : new TransitionCallback() {};
+ }
+ }
+
+ /** Bundled information of dismiss transition. */
+ static class DismissTransition extends TransitSession {
+ final int mReason;
+ final @SplitScreen.StageType int mDismissTop;
DismissTransition(IBinder transition, int reason, int dismissTop) {
- this.mTransition = transition;
+ super(transition, null /* callback */);
this.mReason = reason;
this.mDismissTop = dismissTop;
}
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 2229e26b9343..3c7db33bccf2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -24,6 +24,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.TRANSIT_CHANGE;
@@ -214,6 +215,33 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
};
+ private final SplitScreenTransitions.TransitionCallback mRecentTransitionCallback =
+ new SplitScreenTransitions.TransitionCallback() {
+ @Override
+ public void onTransitionFinished(WindowContainerTransaction finishWct,
+ SurfaceControl.Transaction finishT) {
+ // Check if the recent transition is finished by returning to the current split, so we
+ // can restore the divider bar.
+ for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
+ final WindowContainerTransaction.HierarchyOp op =
+ finishWct.getHierarchyOps().get(i);
+ final IBinder container = op.getContainer();
+ if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
+ && (mMainStage.containsContainer(container)
+ || mSideStage.containsContainer(container))) {
+ setDividerVisibility(true, finishT);
+ return;
+ }
+ }
+
+ // Dismiss the split screen if it's not returning to split.
+ prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, finishWct);
+ setSplitsVisible(false);
+ setDividerVisibility(false, finishT);
+ logExit(EXIT_REASON_UNKNOWN);
+ }
+ };
+
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
ShellTaskOrganizer taskOrganizer, DisplayController displayController,
DisplayImeController displayImeController,
@@ -337,15 +365,23 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
targetStage.evictAllChildren(evictWct);
targetStage.addTask(task, wct);
- if (!evictWct.isEmpty()) {
- wct.merge(evictWct, true /* transfer */);
- }
if (ENABLE_SHELL_TRANSITIONS) {
prepareEnterSplitScreen(wct);
- mSplitTransitions.startEnterTransition(TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE,
- wct, null, this);
+ mSplitTransitions.startEnterTransition(TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct,
+ null, this, new SplitScreenTransitions.TransitionCallback() {
+ @Override
+ public void onTransitionFinished(WindowContainerTransaction finishWct,
+ SurfaceControl.Transaction finishT) {
+ if (!evictWct.isEmpty()) {
+ finishWct.merge(evictWct, true);
+ }
+ }
+ });
} else {
+ if (!evictWct.isEmpty()) {
+ wct.merge(evictWct, true /* transfer */);
+ }
mTaskOrganizer.applyTransaction(wct);
}
return true;
@@ -365,6 +401,39 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return result;
}
+ /** Launches an activity into split. */
+ void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
+ @Nullable Bundle options) {
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ final WindowContainerTransaction evictWct = new WindowContainerTransaction();
+ prepareEvictChildTasks(position, evictWct);
+
+ options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+ wct.sendPendingIntent(intent, fillInIntent, options);
+ prepareEnterSplitScreen(wct, null /* taskInfo */, position);
+
+ mSplitTransitions.startEnterTransition(TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct, null, this,
+ new SplitScreenTransitions.TransitionCallback() {
+ @Override
+ public void onTransitionConsumed(boolean aborted) {
+ // Switch the split position if launching as MULTIPLE_TASK failed.
+ if (aborted
+ && (fillInIntent.getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
+ setSideStagePositionAnimated(
+ SplitLayout.reversePosition(mSideStagePosition));
+ }
+ }
+
+ @Override
+ public void onTransitionFinished(WindowContainerTransaction finishWct,
+ SurfaceControl.Transaction finishT) {
+ if (!evictWct.isEmpty()) {
+ finishWct.merge(evictWct, true);
+ }
+ }
+ });
+ }
+
/** Starts 2 tasks in one transition. */
void startTasks(int mainTaskId, @Nullable Bundle mainOptions, int sideTaskId,
@Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio,
@@ -395,7 +464,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
wct.startTask(sideTaskId, sideOptions);
mSplitTransitions.startEnterTransition(
- TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this);
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this, null);
}
/** Starts 2 tasks in one legacy transition. */
@@ -617,11 +686,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
int getTaskId(@SplitPosition int splitPosition) {
- if (mSideStagePosition == splitPosition) {
- return mSideStage.getTopVisibleChildTaskId();
- } else {
- return mMainStage.getTopVisibleChildTaskId();
+ if (splitPosition == SPLIT_POSITION_UNDEFINED) {
+ return INVALID_TASK_ID;
}
+
+ return mSideStagePosition == splitPosition
+ ? mSideStage.getTopVisibleChildTaskId()
+ : mMainStage.getTopVisibleChildTaskId();
}
void setSideStagePositionAnimated(@SplitPosition int sideStagePosition) {
@@ -861,6 +932,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.init();
setDividerVisibility(true, t);
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
+ t.show(mRootTaskLeash);
setSplitsVisible(true);
mShouldUpdateRecents = true;
updateRecentTasksSplitPair();
@@ -1211,7 +1283,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
final boolean hasChildren = stageListener.mHasChildren;
final boolean isSideStage = stageListener == mSideStageListener;
- if (!hasChildren && !mIsExiting) {
+ if (!hasChildren && !mIsExiting && mMainStage.isActive()) {
if (isSideStage && mMainStageListener.mVisible) {
// Exit to main stage if side stage no longer has children.
if (ENABLE_SHELL_TRANSITIONS) {
@@ -1231,7 +1303,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
EXIT_REASON_APP_FINISHED);
}
}
- } else if (isSideStage && !mMainStage.isActive()) {
+ } else if (isSideStage && hasChildren && !mMainStage.isActive()) {
if (mFocusingTaskInfo != null && !isValidToEnterSplitScreen(mFocusingTaskInfo)) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mSideStage.removeAllTasks(wct, true);
@@ -1543,14 +1615,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
} else if (activityType == ACTIVITY_TYPE_HOME
|| activityType == ACTIVITY_TYPE_RECENTS) {
// Enter overview panel, so start recent transition.
- mSplitTransitions.setRecentTransition(transition,
- request.getRemoteTransition());
+ mSplitTransitions.setRecentTransition(transition, request.getRemoteTransition(),
+ mRecentTransitionCallback);
} else if (mSplitTransitions.mPendingRecent == null) {
// If split-task is not controlled by recents animation
// and occluded by the other fullscreen task, dismiss both.
prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, out);
- mSplitTransitions.setDismissTransition(transition,
- STAGE_TYPE_UNDEFINED, EXIT_REASON_UNKNOWN);
+ mSplitTransitions.setDismissTransition(
+ transition, STAGE_TYPE_UNDEFINED, EXIT_REASON_UNKNOWN);
}
}
} else {
@@ -1558,7 +1630,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// One task is appearing into split, prepare to enter split screen.
out = new WindowContainerTransaction();
prepareEnterSplitScreen(out);
- mSplitTransitions.mPendingEnter = transition;
+ mSplitTransitions.setEnterTransition(
+ transition, request.getRemoteTransition(), null /* callback */);
}
}
return out;
@@ -1614,10 +1687,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
- if (transition != mSplitTransitions.mPendingEnter
- && transition != mSplitTransitions.mPendingRecent
- && (mSplitTransitions.mPendingDismiss == null
- || mSplitTransitions.mPendingDismiss.mTransition != transition)) {
+ if (!mSplitTransitions.isPendingTransition(transition)) {
// Not entering or exiting, so just do some house-keeping and validation.
// If we're not in split-mode, just abort so something else can handle it.
@@ -1664,12 +1734,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
boolean shouldAnimate = true;
- if (mSplitTransitions.mPendingEnter == transition) {
+ if (mSplitTransitions.isPendingEnter(transition)) {
shouldAnimate = startPendingEnterAnimation(transition, info, startTransaction);
- } else if (mSplitTransitions.mPendingRecent == transition) {
+ } else if (mSplitTransitions.isPendingRecent(transition)) {
shouldAnimate = startPendingRecentAnimation(transition, info, startTransaction);
- } else if (mSplitTransitions.mPendingDismiss != null
- && mSplitTransitions.mPendingDismiss.mTransition == transition) {
+ } else if (mSplitTransitions.isPendingDismiss(transition)) {
shouldAnimate = startPendingDismissAnimation(
mSplitTransitions.mPendingDismiss, info, startTransaction, finishTransaction);
}
@@ -1837,28 +1906,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return true;
}
- void onRecentTransitionFinished(WindowContainerTransaction wct,
- SurfaceControl.Transaction finishT) {
- // Check if the recent transition is finished by returning to the current split so we can
- // restore the divider bar.
- for (int i = 0; i < wct.getHierarchyOps().size(); ++i) {
- final WindowContainerTransaction.HierarchyOp op = wct.getHierarchyOps().get(i);
- final IBinder container = op.getContainer();
- if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
- && (mMainStage.containsContainer(container)
- || mSideStage.containsContainer(container))) {
- setDividerVisibility(true, finishT);
- return;
- }
- }
-
- // Dismiss the split screen is it's not returning to split.
- prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, wct);
- setSplitsVisible(false);
- setDividerVisibility(false, finishT);
- logExit(EXIT_REASON_UNKNOWN);
- }
-
private void addDividerBarToTransition(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, boolean show) {
final SurfaceControl leash = mSplitLayout.getDividerLeash();
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 dcd6277966dd..0bec54399dd8 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
@@ -483,11 +483,11 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
postStartTransactionCallbacks.add(t ->
startSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish,
mTransactionPool, mMainExecutor, mAnimExecutor,
- null /* position */, cornerRadius, clipRect));
+ change.getEndRelOffset(), cornerRadius, clipRect));
} else {
startSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish,
- mTransactionPool, mMainExecutor, mAnimExecutor, null /* position */,
- cornerRadius, clipRect);
+ mTransactionPool, mMainExecutor, mAnimExecutor,
+ change.getEndRelOffset(), cornerRadius, clipRect);
}
if (info.getAnimationOptions() != null) {
@@ -934,7 +934,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
a.restrictDuration(MAX_ANIMATION_DURATION);
a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
startSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool,
- mMainExecutor, mAnimExecutor, new Point(bounds.left, bounds.top),
+ mMainExecutor, mAnimExecutor, change.getEndRelOffset(),
cornerRadius, change.getEndAbsBounds());
}
@@ -959,7 +959,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
a.restrictDuration(MAX_ANIMATION_DURATION);
a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
startSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool,
- mMainExecutor, mAnimExecutor, null /* position */,
+ mMainExecutor, mAnimExecutor, change.getEndRelOffset(),
cornerRadius, change.getEndAbsBounds());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 6d28d73996f0..fe3724b4ec1b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -25,6 +25,7 @@ import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
import android.content.Context;
import android.os.Handler;
+import android.view.Choreographer;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
@@ -45,17 +46,20 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel<Caption
private final ShellTaskOrganizer mTaskOrganizer;
private final Context mContext;
private final Handler mMainHandler;
+ private final Choreographer mMainChoreographer;
private final DisplayController mDisplayController;
private final SyncTransactionQueue mSyncQueue;
public CaptionWindowDecorViewModel(
Context context,
Handler mainHandler,
+ Choreographer mainChoreographer,
ShellTaskOrganizer taskOrganizer,
DisplayController displayController,
SyncTransactionQueue syncQueue) {
mContext = context;
mMainHandler = mainHandler;
+ mMainChoreographer = mainChoreographer;
mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
mTaskOrganizer = taskOrganizer;
mDisplayController = displayController;
@@ -72,6 +76,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel<Caption
taskInfo,
taskSurface,
mMainHandler,
+ mMainChoreographer,
mSyncQueue);
TaskPositioner taskPositioner = new TaskPositioner(mTaskOrganizer, windowDecoration);
CaptionTouchEventListener touchEventListener =
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index cdca051a4ee5..2df71041595d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -25,6 +25,7 @@ import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
+import android.view.Choreographer;
import android.view.SurfaceControl;
import android.view.View;
import android.window.WindowContainerTransaction;
@@ -59,6 +60,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP);
private final Handler mHandler;
+ private final Choreographer mChoreographer;
private final SyncTransactionQueue mSyncQueue;
private View.OnClickListener mOnCaptionButtonClickListener;
@@ -77,10 +79,12 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
Handler handler,
+ Choreographer choreographer,
SyncTransactionQueue syncQueue) {
super(context, displayController, taskOrganizer, taskInfo, taskSurface);
mHandler = handler;
+ mChoreographer = choreographer;
mSyncQueue = syncQueue;
}
@@ -138,6 +142,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
mDragResizeListener = new DragResizeInputListener(
mContext,
mHandler,
+ mChoreographer,
mDisplay.getDisplayId(),
mDecorationContainerSurface,
mDragResizeCallback);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index c6bbb027c8e6..f512b0d4fe10 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -27,8 +27,8 @@ import android.hardware.input.InputManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
+import android.view.Choreographer;
import android.view.IWindowSession;
import android.view.InputChannel;
import android.view.InputEvent;
@@ -49,6 +49,7 @@ class DragResizeInputListener implements AutoCloseable {
private final IWindowSession mWindowSession = WindowManagerGlobal.getWindowSession();
private final Handler mHandler;
+ private final Choreographer mChoreographer;
private final InputManager mInputManager;
private final int mDisplayId;
@@ -68,11 +69,13 @@ class DragResizeInputListener implements AutoCloseable {
DragResizeInputListener(
Context context,
Handler handler,
+ Choreographer choreographer,
int displayId,
SurfaceControl decorationSurface,
DragResizeCallback callback) {
mInputManager = context.getSystemService(InputManager.class);
mHandler = handler;
+ mChoreographer = choreographer;
mDisplayId = displayId;
mDecorationSurface = decorationSurface;
// Use a fake window as the backing surface is a container layer and we don't want to create
@@ -97,7 +100,8 @@ class DragResizeInputListener implements AutoCloseable {
e.rethrowFromSystemServer();
}
- mInputEventReceiver = new TaskResizeInputEventReceiver(mInputChannel, mHandler.getLooper());
+ mInputEventReceiver = new TaskResizeInputEventReceiver(
+ mInputChannel, mHandler, mChoreographer);
mCallback = callback;
}
@@ -154,10 +158,6 @@ class DragResizeInputListener implements AutoCloseable {
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
-
- // This marks all relevant components have handled the previous resize event and can take
- // the next one now.
- mInputEventReceiver.onHandledLastResizeEvent();
}
@Override
@@ -171,28 +171,39 @@ class DragResizeInputListener implements AutoCloseable {
}
private class TaskResizeInputEventReceiver extends InputEventReceiver {
- private boolean mWaitingForLastResizeEventHandled;
+ private final Choreographer mChoreographer;
+ private final Runnable mConsumeBatchEventRunnable;
+ private boolean mConsumeBatchEventScheduled;
- private TaskResizeInputEventReceiver(InputChannel inputChannel, Looper looper) {
- super(inputChannel, looper);
- }
+ private TaskResizeInputEventReceiver(
+ InputChannel inputChannel, Handler handler, Choreographer choreographer) {
+ super(inputChannel, handler.getLooper());
+ mChoreographer = choreographer;
- private void onHandledLastResizeEvent() {
- mWaitingForLastResizeEventHandled = false;
- consumeBatchedInputEvents(-1);
+ mConsumeBatchEventRunnable = () -> {
+ mConsumeBatchEventScheduled = false;
+ if (consumeBatchedInputEvents(mChoreographer.getFrameTimeNanos())) {
+ // If we consumed a batch here, we want to go ahead and schedule the
+ // consumption of batched input events on the next frame. Otherwise, we would
+ // wait until we have more input events pending and might get starved by other
+ // things occurring in the process.
+ scheduleConsumeBatchEvent();
+ }
+ };
}
@Override
public void onBatchedInputEventPending(int source) {
- // InputEventReceiver keeps continuous move events in a batched event until explicitly
- // consuming it or an incompatible event shows up (likely an up event in this case). We
- // continue to keep move events in the next batched event until we receive a geometry
- // update so that we don't put too much pressure on the framework with excessive number
- // of input events if it can't handle them fast enough. It's more responsive to always
- // resize the task to the latest received coordinates.
- if (!mWaitingForLastResizeEventHandled) {
- consumeBatchedInputEvents(-1);
+ scheduleConsumeBatchEvent();
+ }
+
+ private void scheduleConsumeBatchEvent() {
+ if (mConsumeBatchEventScheduled) {
+ return;
}
+ mChoreographer.postCallback(
+ Choreographer.CALLBACK_INPUT, mConsumeBatchEventRunnable, null);
+ mConsumeBatchEventScheduled = true;
}
@Override
@@ -211,14 +222,12 @@ class DragResizeInputListener implements AutoCloseable {
mDragPointerId = e.getPointerId(0);
mCallback.onDragResizeStart(
calculateCtrlType(e.getX(0), e.getY(0)), e.getRawX(0), e.getRawY(0));
- mWaitingForLastResizeEventHandled = false;
break;
}
case MotionEvent.ACTION_MOVE: {
int dragPointerIndex = e.findPointerIndex(mDragPointerId);
mCallback.onDragResizeMove(
e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
- mWaitingForLastResizeEventHandled = true;
break;
}
case MotionEvent.ACTION_UP:
@@ -226,7 +235,6 @@ class DragResizeInputListener implements AutoCloseable {
int dragPointerIndex = e.findPointerIndex(mDragPointerId);
mCallback.onDragResizeEnd(
e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
- mWaitingForLastResizeEventHandled = false;
mDragPointerId = -1;
break;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index c19a33abf8a4..4855fbd5ba7a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -222,10 +222,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
float shadowRadius = outResult.mDensity * shadowRadiusDp;
int backgroundColorInt = mTaskInfo.taskDescription.getBackgroundColor();
- mTmpColor[0] = Color.red(backgroundColorInt);
- mTmpColor[1] = Color.green(backgroundColorInt);
- mTmpColor[2] = Color.blue(backgroundColorInt);
- t.setCrop(mTaskBackgroundSurface, taskBounds)
+ mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f;
+ mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
+ mTmpColor[2] = (float) Color.blue(backgroundColorInt) / 255.f;
+ t.setWindowCrop(mTaskBackgroundSurface, taskBounds.width(), taskBounds.height())
.setShadowRadius(mTaskBackgroundSurface, shadowRadius)
.setColor(mTaskBackgroundSurface, mTmpColor);
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
index 319de8e4e310..293eb7cd5581 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
@@ -101,6 +101,12 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr
}
/** {@inheritDoc} */
+ @FlakyTest
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
override fun navBarLayerIsVisibleAtStartAndEnd() =
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index edfa63a7e97c..045022414fe0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -89,7 +89,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
/**
* Checks [pipApp] layer remains visible throughout the animation
*/
- @FlakyTest
+ @FlakyTest(bugId = 239807171)
@Test
open fun pipAppLayerAlwaysVisible() {
testSpec.assertLayers {
@@ -113,7 +113,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
* Checks that the pip app layer remains inside the display bounds throughout the whole
* animation
*/
- @Presubmit
+ @FlakyTest(bugId = 239807171)
@Test
open fun pipLayerRemainInsideVisibleBounds() {
testSpec.assertLayersVisibleRegion(pipApp) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java
index 49228720b81d..f8b3fb3def62 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java
@@ -34,13 +34,12 @@ public class MockSurfaceControlHelper {
* given {@link SurfaceControl} when calling {@link SurfaceControl.Builder#build()}.
*
* @param mockSurfaceControl the first {@link SurfaceControl} to return
- * @param mockSurfaceControls following {@link SurfaceControl} to return
* @return the mock of {@link SurfaceControl.Builder}
*/
public static SurfaceControl.Builder createMockSurfaceControlBuilder(
- SurfaceControl mockSurfaceControl, SurfaceControl... mockSurfaceControls) {
+ SurfaceControl mockSurfaceControl) {
final SurfaceControl.Builder mockBuilder = mock(SurfaceControl.Builder.class, RETURNS_SELF);
- doReturn(mockSurfaceControl, (Object[]) mockSurfaceControls)
+ doReturn(mockSurfaceControl)
.when(mockBuilder)
.build();
return mockBuilder;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
index 0972cf2c032f..1636c5f73133 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
@@ -25,6 +25,7 @@ import com.android.wm.shell.bubbles.storage.BubbleXmlHelperTest.Companion.sparse
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertNotNull
import junit.framework.Assert.assertTrue
+import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -61,6 +62,12 @@ class BubblePersistentRepositoryTest : ShellTestCase() {
bubbles.put(1, user1Bubbles)
}
+ @After
+ fun teardown() {
+ // Clean up the any persisted bubbles for the next run
+ repository.persistsToDisk(SparseArray())
+ }
+
@Test
fun testReadWriteOperation() {
// Verify read before write doesn't cause FileNotFoundException
@@ -71,4 +78,4 @@ class BubblePersistentRepositoryTest : ShellTestCase() {
repository.persistsToDisk(bubbles)
assertTrue(sparseArraysEqual(bubbles, repository.readFromDisk()))
}
-} \ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index 52d78ca7a004..5880ffb0dce2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -37,6 +37,7 @@ import android.testing.TestableLooper;
import android.view.SurfaceControl;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.wm.shell.MockSurfaceControlHelper;
import com.android.wm.shell.ShellTestCase;
@@ -62,19 +63,18 @@ public class PipAnimationControllerTest extends ShellTestCase {
@Mock
private TaskInfo mTaskInfo;
-
@Mock
private PipAnimationController.PipAnimationCallback mPipAnimationCallback;
@Before
public void setUp() throws Exception {
- mPipAnimationController = new PipAnimationController(
- new PipSurfaceTransactionHelper());
+ MockitoAnnotations.initMocks(this);
+ mPipAnimationController = new PipAnimationController(new PipSurfaceTransactionHelper(
+ InstrumentationRegistry.getInstrumentation().getTargetContext()));
mLeash = new SurfaceControl.Builder()
.setContainerLayer()
.setName("FakeLeash")
.build();
- MockitoAnnotations.initMocks(this);
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index b351f8fcf838..857f578fd8ed 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -42,6 +42,7 @@ import android.testing.TestableLooper;
import android.util.Rational;
import android.util.Size;
import android.view.DisplayInfo;
+import android.view.SurfaceControl;
import android.window.WindowContainerToken;
import com.android.wm.shell.MockSurfaceControlHelper;
@@ -150,7 +151,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
final Rational aspectRatio = new Rational(2, 1);
mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1,
- createPipParams(aspectRatio)), null /* leash */);
+ createPipParams(aspectRatio)), mock(SurfaceControl.class));
assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f);
}
@@ -158,7 +159,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
@Test
public void onTaskAppeared_updatesLastPipComponentName() {
mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)),
- null /* leash */);
+ mock(SurfaceControl.class));
assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName());
}
@@ -169,7 +170,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
mSpiedPipTaskOrganizer.onTaskAppeared(
createTaskInfo(mComponent1, createPipParams(null), minSize),
- null /* leash */);
+ mock(SurfaceControl.class));
assertEquals(minSize, mPipBoundsState.getOverrideMinSize());
}
@@ -179,7 +180,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
final Rational startAspectRatio = new Rational(2, 1);
final Rational newAspectRatio = new Rational(1, 2);
mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1,
- createPipParams(startAspectRatio)), null /* leash */);
+ createPipParams(startAspectRatio)), mock(SurfaceControl.class));
// It is in entering transition, should defer onTaskInfoChanged callback in this case.
mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1,
@@ -197,7 +198,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
final Rational startAspectRatio = new Rational(2, 1);
final Rational newAspectRatio = new Rational(1, 2);
mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1,
- createPipParams(startAspectRatio)), null /* leash */);
+ createPipParams(startAspectRatio)), mock(SurfaceControl.class));
mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1,
@@ -210,7 +211,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
@Test
public void onTaskInfoChanged_inPip_updatesLastPipComponentName() {
mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1,
- createPipParams(null)), null /* leash */);
+ createPipParams(null)), mock(SurfaceControl.class));
mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2,
@@ -222,7 +223,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
@Test
public void onTaskInfoChanged_inPip_updatesOverrideMinSize() {
mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1,
- createPipParams(null)), null /* leash */);
+ createPipParams(null)), mock(SurfaceControl.class));
mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
final Size minSize = new Size(400, 320);
@@ -235,7 +236,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
@Test
public void onTaskVanished_clearsPipBounds() {
mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1,
- createPipParams(null)), null /* leash */);
+ createPipParams(null)), mock(SurfaceControl.class));
mPipBoundsState.setBounds(new Rect(100, 100, 200, 150));
mSpiedPipTaskOrganizer.onTaskVanished(createTaskInfo(mComponent1, createPipParams(null)));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index 304ca66dd3bb..1d038f4ee377 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -182,7 +182,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder transition = mSplitScreenTransitions.startEnterTransition(
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, new WindowContainerTransaction(),
- new RemoteTransition(testRemote), mStageCoordinator);
+ new RemoteTransition(testRemote), mStageCoordinator, null);
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
boolean accepted = mStageCoordinator.startAnimation(transition, info,
@@ -422,7 +422,7 @@ public class SplitTransitionTests extends ShellTestCase {
TransitionInfo enterInfo = createEnterPairInfo();
IBinder enterTransit = mSplitScreenTransitions.startEnterTransition(
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, new WindowContainerTransaction(),
- new RemoteTransition(new TestRemoteTransition()), mStageCoordinator);
+ new RemoteTransition(new TestRemoteTransition()), mStageCoordinator, null);
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
mStageCoordinator.startAnimation(enterTransit, enterInfo,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index 680034bd2ea5..d1b837ef42f1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -21,23 +21,32 @@ import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceCon
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.same;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Color;
+import android.graphics.Point;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
+import android.util.DisplayMetrics;
import android.view.Display;
+import android.view.InsetsState;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.View;
+import android.view.ViewRootImpl;
+import android.view.WindowManager.LayoutParams;
import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
@@ -53,6 +62,8 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import java.util.ArrayList;
+import java.util.List;
import java.util.function.Supplier;
/**
@@ -66,6 +77,8 @@ import java.util.function.Supplier;
public class WindowDecorationTests extends ShellTestCase {
private static final int CAPTION_HEIGHT_DP = 32;
private static final int SHADOW_RADIUS_DP = 5;
+ private static final Rect TASK_BOUNDS = new Rect(100, 300, 400, 400);
+ private static final Point TASK_POSITION_IN_PARENT = new Point(40, 60);
private final Rect mOutsetsDp = new Rect();
private final WindowDecoration.RelayoutResult<TestView> mRelayoutResult =
@@ -84,12 +97,11 @@ public class WindowDecorationTests extends ShellTestCase {
@Mock
private WindowContainerTransaction mMockWindowContainerTransaction;
- private SurfaceControl.Builder mMockSurfaceControlBuilder;
+ private final List<SurfaceControl.Builder> mMockSurfaceControlBuilders = new ArrayList<>();
private SurfaceControl.Transaction mMockSurfaceControlTransaction;
@Before
public void setUp() {
- mMockSurfaceControlBuilder = createMockSurfaceControlBuilder(mock(SurfaceControl.class));
mMockSurfaceControlTransaction = createMockSurfaceControlTransaction();
doReturn(mMockSurfaceControlViewHost).when(mMockSurfaceControlViewHostFactory)
@@ -97,6 +109,128 @@ public class WindowDecorationTests extends ShellTestCase {
}
@Test
+ public void testLayoutResultCalculation_invisibleTask() {
+ final Display defaultDisplay = mock(Display.class);
+ doReturn(defaultDisplay).when(mMockDisplayController)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+
+ final SurfaceControl decorContainerSurface = mock(SurfaceControl.class);
+ final SurfaceControl.Builder decorContainerSurfaceBuilder =
+ createMockSurfaceControlBuilder(decorContainerSurface);
+ mMockSurfaceControlBuilders.add(decorContainerSurfaceBuilder);
+ final SurfaceControl taskBackgroundSurface = mock(SurfaceControl.class);
+ final SurfaceControl.Builder taskBackgroundSurfaceBuilder =
+ createMockSurfaceControlBuilder(taskBackgroundSurface);
+ mMockSurfaceControlBuilders.add(taskBackgroundSurfaceBuilder);
+
+ final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
+ new ActivityManager.TaskDescription.Builder()
+ .setBackgroundColor(Color.YELLOW);
+ final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .setTaskDescriptionBuilder(taskDescriptionBuilder)
+ .setBounds(TASK_BOUNDS)
+ .setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
+ .setVisible(false)
+ .build();
+ taskInfo.isFocused = false;
+ // Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is
+ // 64px.
+ taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
+ mOutsetsDp.set(10, 20, 30, 40);
+
+ final SurfaceControl taskSurface = mock(SurfaceControl.class);
+ final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
+
+ windowDecor.relayout(taskInfo);
+
+ verify(decorContainerSurfaceBuilder, never()).build();
+ verify(taskBackgroundSurfaceBuilder, never()).build();
+ verify(mMockSurfaceControlViewHostFactory, never())
+ .create(any(), any(), any(), anyBoolean());
+
+ verify(mMockSurfaceControlTransaction).hide(taskSurface);
+
+ assertNull(mRelayoutResult.mRootView);
+ }
+
+ @Test
+ public void testLayoutResultCalculation_visibleFocusedTask() {
+ final Display defaultDisplay = mock(Display.class);
+ doReturn(defaultDisplay).when(mMockDisplayController)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+
+ final SurfaceControl decorContainerSurface = mock(SurfaceControl.class);
+ final SurfaceControl.Builder decorContainerSurfaceBuilder =
+ createMockSurfaceControlBuilder(decorContainerSurface);
+ mMockSurfaceControlBuilders.add(decorContainerSurfaceBuilder);
+ final SurfaceControl taskBackgroundSurface = mock(SurfaceControl.class);
+ final SurfaceControl.Builder taskBackgroundSurfaceBuilder =
+ createMockSurfaceControlBuilder(taskBackgroundSurface);
+ mMockSurfaceControlBuilders.add(taskBackgroundSurfaceBuilder);
+
+ final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
+ new ActivityManager.TaskDescription.Builder()
+ .setBackgroundColor(Color.YELLOW);
+ final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .setTaskDescriptionBuilder(taskDescriptionBuilder)
+ .setBounds(TASK_BOUNDS)
+ .setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
+ .setVisible(true)
+ .build();
+ taskInfo.isFocused = true;
+ // Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is
+ // 64px.
+ taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
+ mOutsetsDp.set(10, 20, 30, 40);
+
+ final SurfaceControl taskSurface = mock(SurfaceControl.class);
+ final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
+
+ windowDecor.relayout(taskInfo);
+
+ verify(decorContainerSurfaceBuilder).setParent(taskSurface);
+ verify(decorContainerSurfaceBuilder).setContainerLayer();
+ verify(mMockSurfaceControlTransaction).setTrustedOverlay(decorContainerSurface, true);
+ verify(mMockSurfaceControlTransaction).setPosition(decorContainerSurface, -20, -40);
+ verify(mMockSurfaceControlTransaction).setWindowCrop(decorContainerSurface, 380, 220);
+
+ verify(taskBackgroundSurfaceBuilder).setParent(taskSurface);
+ verify(taskBackgroundSurfaceBuilder).setEffectLayer();
+ verify(mMockSurfaceControlTransaction).setWindowCrop(taskBackgroundSurface, 300, 100);
+ verify(mMockSurfaceControlTransaction)
+ .setColor(taskBackgroundSurface, new float[] {1.f, 1.f, 0.f});
+ verify(mMockSurfaceControlTransaction).setShadowRadius(taskBackgroundSurface, 10);
+
+ verify(mMockSurfaceControlViewHostFactory)
+ .create(any(), eq(defaultDisplay), any(), anyBoolean());
+ verify(mMockSurfaceControlViewHost)
+ .setView(same(mMockView),
+ argThat(lp -> lp.height == 64
+ && lp.width == 300
+ && (lp.flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0));
+ if (ViewRootImpl.CAPTION_ON_SHELL) {
+ verify(mMockView).setTaskFocusState(true);
+ verify(mMockWindowContainerTransaction)
+ .addRectInsetsProvider(taskInfo.token,
+ new Rect(100, 300, 400, 364),
+ new int[] { InsetsState.ITYPE_CAPTION_BAR });
+ }
+
+ verify(mMockSurfaceControlTransaction)
+ .setPosition(taskSurface, TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y);
+ verify(mMockSurfaceControlTransaction)
+ .setCrop(taskSurface, new Rect(-20, -40, 360, 180));
+ verify(mMockSurfaceControlTransaction)
+ .show(taskSurface);
+
+ assertEquals(380, mRelayoutResult.mWidth);
+ assertEquals(220, mRelayoutResult.mHeight);
+ assertEquals(2, mRelayoutResult.mDensity, 0.f);
+ }
+
+ @Test
public void testNotCrashWhenDisplayAppearsAfterTask() {
doReturn(mock(Display.class)).when(mMockDisplayController)
.getDisplay(Display.DEFAULT_DISPLAY);
@@ -145,10 +279,24 @@ public class WindowDecorationTests extends ShellTestCase {
private TestWindowDecoration createWindowDecoration(
ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) {
return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer,
- taskInfo, testSurface, () -> mMockSurfaceControlBuilder,
+ taskInfo, testSurface, new MockSurfaceControlBuilderSupplier(),
mMockSurfaceControlViewHostFactory);
}
+ private class MockSurfaceControlBuilderSupplier implements Supplier<SurfaceControl.Builder> {
+ private int mNumOfCalls = 0;
+
+ @Override
+ public SurfaceControl.Builder get() {
+ final SurfaceControl.Builder builder =
+ mNumOfCalls < mMockSurfaceControlBuilders.size()
+ ? mMockSurfaceControlBuilders.get(mNumOfCalls)
+ : createMockSurfaceControlBuilder(mock(SurfaceControl.class));
+ ++mNumOfCalls;
+ return builder;
+ }
+ }
+
private static class TestView extends View implements TaskFocusStateConsumer {
private TestView(Context context) {
super(context);
diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp
index 30d6d0009d3b..19efc5f09d11 100644
--- a/libs/hwui/jni/Typeface.cpp
+++ b/libs/hwui/jni/Typeface.cpp
@@ -21,6 +21,7 @@
#include <minikin/FontFamily.h>
#include <minikin/FontFileParser.h>
#include <minikin/LocaleList.h>
+#include <minikin/MinikinFontFactory.h>
#include <minikin/SystemFonts.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedUtfChars.h>
@@ -206,9 +207,18 @@ static sk_sp<SkData> makeSkDataCached(const std::string& path, bool hasVerity) {
return entry;
}
-static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::BufferReader);
+class MinikinFontSkiaFactory : minikin::MinikinFontFactory {
+private:
+ MinikinFontSkiaFactory() : MinikinFontFactory() { MinikinFontFactory::setInstance(this); }
-static minikin::Font::TypefaceLoader* readMinikinFontSkia(minikin::BufferReader* reader) {
+public:
+ static void init() { static MinikinFontSkiaFactory factory; }
+ void skip(minikin::BufferReader* reader) const override;
+ std::shared_ptr<minikin::MinikinFont> create(minikin::BufferReader reader) const override;
+ void write(minikin::BufferWriter* writer, const minikin::MinikinFont* typeface) const override;
+};
+
+void MinikinFontSkiaFactory::skip(minikin::BufferReader* reader) const {
// Advance reader's position.
reader->skipString(); // fontPath
reader->skip<int>(); // fontIndex
@@ -218,10 +228,10 @@ static minikin::Font::TypefaceLoader* readMinikinFontSkia(minikin::BufferReader*
reader->skip<uint32_t>(); // expectedFontRevision
reader->skipString(); // expectedPostScriptName
}
- return &loadMinikinFontSkia;
}
-static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::BufferReader reader) {
+std::shared_ptr<minikin::MinikinFont> MinikinFontSkiaFactory::create(
+ minikin::BufferReader reader) const {
std::string_view fontPath = reader.readString();
std::string path(fontPath.data(), fontPath.size());
ATRACE_FORMAT("Loading font %s", path.c_str());
@@ -270,8 +280,8 @@ static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::Buffer
return minikinFont;
}
-static void writeMinikinFontSkia(minikin::BufferWriter* writer,
- const minikin::MinikinFont* typeface) {
+void MinikinFontSkiaFactory::write(minikin::BufferWriter* writer,
+ const minikin::MinikinFont* typeface) const {
// When you change the format of font metadata, please update code to parse
// typefaceMetadataReader() in
// frameworks/base/libs/hwui/jni/fonts/Font.cpp too.
@@ -296,6 +306,7 @@ static void writeMinikinFontSkia(minikin::BufferWriter* writer,
}
static jint Typeface_writeTypefaces(JNIEnv *env, jobject, jobject buffer, jlongArray faceHandles) {
+ MinikinFontSkiaFactory::init();
ScopedLongArrayRO faces(env, faceHandles);
std::vector<Typeface*> typefaces;
typefaces.reserve(faces.size());
@@ -312,7 +323,7 @@ static jint Typeface_writeTypefaces(JNIEnv *env, jobject, jobject buffer, jlongA
fontCollections.push_back(typeface->fFontCollection);
}
}
- minikin::FontCollection::writeVector<writeMinikinFontSkia>(&writer, fontCollections);
+ minikin::FontCollection::writeVector(&writer, fontCollections);
writer.write<uint32_t>(typefaces.size());
for (Typeface* typeface : typefaces) {
writer.write<uint32_t>(fcToIndex.find(typeface->fFontCollection)->second);
@@ -324,11 +335,12 @@ static jint Typeface_writeTypefaces(JNIEnv *env, jobject, jobject buffer, jlongA
}
static jlongArray Typeface_readTypefaces(JNIEnv *env, jobject, jobject buffer) {
+ MinikinFontSkiaFactory::init();
void* addr = buffer == nullptr ? nullptr : env->GetDirectBufferAddress(buffer);
if (addr == nullptr) return nullptr;
minikin::BufferReader reader(addr);
std::vector<std::shared_ptr<minikin::FontCollection>> fontCollections =
- minikin::FontCollection::readVector<readMinikinFontSkia>(&reader);
+ minikin::FontCollection::readVector(&reader);
uint32_t typefaceCount = reader.read<uint32_t>();
std::vector<jlong> faceHandles;
faceHandles.reserve(typefaceCount);
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 190e1cc083bd..fba4249260ef 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -142,6 +142,14 @@ public class GpsNetInitiatedHandler {
public int textEncoding;
}
+ /** Callbacks for Emergency call events. */
+ public interface EmergencyCallCallback {
+ /** Callback invoked when an emergency call starts */
+ void onEmergencyCallStart(int subId);
+ /** Callback invoked when an emergency call ends */
+ void onEmergencyCallEnd();
+ }
+
private class EmergencyCallListener extends TelephonyCallback implements
TelephonyCallback.OutgoingEmergencyCallListener,
TelephonyCallback.CallStateListener {
@@ -152,6 +160,7 @@ public class GpsNetInitiatedHandler {
int subscriptionId) {
mIsInEmergencyCall = true;
if (DEBUG) Log.d(TAG, "onOutgoingEmergencyCall(): inEmergency = " + getInEmergency());
+ mEmergencyCallCallback.onEmergencyCallStart(subscriptionId);
}
@Override
@@ -163,6 +172,7 @@ public class GpsNetInitiatedHandler {
if (mIsInEmergencyCall) {
mCallEndElapsedRealtimeMillis = SystemClock.elapsedRealtime();
mIsInEmergencyCall = false;
+ mEmergencyCallCallback.onEmergencyCallEnd();
}
}
}
@@ -180,8 +190,11 @@ public class GpsNetInitiatedHandler {
*/
private Notification.Builder mNiNotificationBuilder;
+ private final EmergencyCallCallback mEmergencyCallCallback;
+
public GpsNetInitiatedHandler(Context context,
INetInitiatedListener netInitiatedListener,
+ EmergencyCallCallback emergencyCallCallback,
boolean isSuplEsEnabled) {
mContext = context;
@@ -190,6 +203,7 @@ public class GpsNetInitiatedHandler {
} else {
mNetInitiatedListener = netInitiatedListener;
}
+ mEmergencyCallCallback = emergencyCallCallback;
setSuplEsEnabled(isSuplEsEnabled);
mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 57f105671ed4..a7a21e7a2013 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -48,6 +48,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@@ -124,6 +125,7 @@ public final class MediaRouter2 {
private final Map<String, RoutingController> mNonSystemRoutingControllers = new ArrayMap<>();
private final AtomicInteger mNextRequestId = new AtomicInteger(1);
+ private final AtomicBoolean mIsScanning = new AtomicBoolean(/* initialValue= */ false);
final Handler mHandler;
@@ -255,7 +257,9 @@ public final class MediaRouter2 {
@RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
public void startScan() {
if (isSystemRouter()) {
- sManager.startScan();
+ if (!mIsScanning.getAndSet(true)) {
+ sManager.registerScanRequest();
+ }
}
}
@@ -281,7 +285,9 @@ public final class MediaRouter2 {
@RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
public void stopScan() {
if (isSystemRouter()) {
- sManager.stopScan();
+ if (mIsScanning.getAndSet(false)) {
+ sManager.unregisterScanRequest();
+ }
}
}
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index c84f5b09f166..44c0b54546be 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -82,6 +82,7 @@ public final class MediaRouter2Manager {
@GuardedBy("sLock")
private Client mClient;
private final IMediaRouterService mMediaRouterService;
+ private final AtomicInteger mScanRequestCount = new AtomicInteger(/* initialValue= */ 0);
final Handler mHandler;
final CopyOnWriteArrayList<CallbackRecord> mCallbackRecords = new CopyOnWriteArrayList<>();
@@ -155,22 +156,18 @@ public final class MediaRouter2Manager {
}
/**
- * Starts scanning remote routes.
- * <p>
- * Route discovery can happen even when the {@link #startScan()} is not called.
- * This is because the scanning could be started before by other apps.
- * Therefore, calling this method after calling {@link #stopScan()} does not necessarily mean
- * that the routes found before are removed and added again.
- * <p>
- * Use {@link Callback} to get the route related events.
- * <p>
- * @see #stopScan()
+ * Registers a request to scan for remote routes.
+ *
+ * <p>Increases the count of active scanning requests. When the count transitions from zero to
+ * one, sends a request to the system server to start scanning.
+ *
+ * <p>Clients must {@link #unregisterScanRequest() unregister their scan requests} when scanning
+ * is no longer needed, to avoid unnecessary resource usage.
*/
- public void startScan() {
- Client client = getOrCreateClient();
- if (client != null) {
+ public void registerScanRequest() {
+ if (mScanRequestCount.getAndIncrement() == 0) {
try {
- mMediaRouterService.startScan(client);
+ mMediaRouterService.startScan(getOrCreateClient());
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -178,23 +175,26 @@ public final class MediaRouter2Manager {
}
/**
- * Stops scanning remote routes to reduce resource consumption.
- * <p>
- * Route discovery can be continued even after this method is called.
- * This is because the scanning is only turned off when all the apps stop scanning.
- * Therefore, calling this method does not necessarily mean the routes are removed.
- * Also, for the same reason it does not mean that {@link Callback#onRoutesAdded(List)}
- * is not called afterwards.
- * <p>
- * Use {@link Callback} to get the route related events.
+ * Unregisters a scan request made by {@link #registerScanRequest()}.
+ *
+ * <p>Decreases the count of active scanning requests. When the count transitions from one to
+ * zero, sends a request to the system server to stop scanning.
*
- * @see #startScan()
+ * @throws IllegalStateException If called while there are no active scan requests.
*/
- public void stopScan() {
- Client client = getOrCreateClient();
- if (client != null) {
+ public void unregisterScanRequest() {
+ if (mScanRequestCount.updateAndGet(
+ count -> {
+ if (count == 0) {
+ throw new IllegalStateException(
+ "No active scan requests to unregister.");
+ } else {
+ return --count;
+ }
+ })
+ == 0) {
try {
- mMediaRouterService.stopScan(client);
+ mMediaRouterService.stopScan(getOrCreateClient());
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -423,15 +423,11 @@ public final class MediaRouter2Manager {
*/
@NonNull
public List<RoutingSessionInfo> getRemoteSessions() {
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- return mMediaRouterService.getRemoteSessions(client);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ try {
+ return mMediaRouterService.getRemoteSessions(getOrCreateClient());
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
}
- return Collections.emptyList();
}
/**
@@ -514,14 +510,12 @@ public final class MediaRouter2Manager {
return;
}
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- int requestId = mNextRequestId.getAndIncrement();
- mMediaRouterService.setRouteVolumeWithManager(client, requestId, route, volume);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ try {
+ int requestId = mNextRequestId.getAndIncrement();
+ mMediaRouterService.setRouteVolumeWithManager(
+ getOrCreateClient(), requestId, route, volume);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
}
}
@@ -543,15 +537,12 @@ public final class MediaRouter2Manager {
return;
}
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- int requestId = mNextRequestId.getAndIncrement();
- mMediaRouterService.setSessionVolumeWithManager(
- client, requestId, sessionInfo.getId(), volume);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ try {
+ int requestId = mNextRequestId.getAndIncrement();
+ mMediaRouterService.setSessionVolumeWithManager(
+ getOrCreateClient(), requestId, sessionInfo.getId(), volume);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
}
}
@@ -808,15 +799,12 @@ public final class MediaRouter2Manager {
return;
}
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- int requestId = mNextRequestId.getAndIncrement();
- mMediaRouterService.selectRouteWithManager(
- client, requestId, sessionInfo.getId(), route);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ try {
+ int requestId = mNextRequestId.getAndIncrement();
+ mMediaRouterService.selectRouteWithManager(
+ getOrCreateClient(), requestId, sessionInfo.getId(), route);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
}
}
@@ -850,15 +838,12 @@ public final class MediaRouter2Manager {
return;
}
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- int requestId = mNextRequestId.getAndIncrement();
- mMediaRouterService.deselectRouteWithManager(
- client, requestId, sessionInfo.getId(), route);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ try {
+ int requestId = mNextRequestId.getAndIncrement();
+ mMediaRouterService.deselectRouteWithManager(
+ getOrCreateClient(), requestId, sessionInfo.getId(), route);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
}
}
@@ -875,15 +860,12 @@ public final class MediaRouter2Manager {
public void releaseSession(@NonNull RoutingSessionInfo sessionInfo) {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- int requestId = mNextRequestId.getAndIncrement();
- mMediaRouterService.releaseSessionWithManager(
- client, requestId, sessionInfo.getId());
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ try {
+ int requestId = mNextRequestId.getAndIncrement();
+ mMediaRouterService.releaseSessionWithManager(
+ getOrCreateClient(), requestId, sessionInfo.getId());
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
}
}
@@ -896,14 +878,11 @@ public final class MediaRouter2Manager {
@NonNull MediaRoute2Info route) {
int requestId = createTransferRequest(session, route);
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- mMediaRouterService.transferToRouteWithManager(
- client, requestId, session.getId(), route);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ try {
+ mMediaRouterService.transferToRouteWithManager(
+ getOrCreateClient(), requestId, session.getId(), route);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
}
}
@@ -916,14 +895,11 @@ public final class MediaRouter2Manager {
int requestId = createTransferRequest(oldSession, route);
- Client client = getOrCreateClient();
- if (client != null) {
- try {
- mMediaRouterService.requestCreateSessionWithManager(
- client, requestId, oldSession, route);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ try {
+ mMediaRouterService.requestCreateSessionWithManager(
+ getOrCreateClient(), requestId, oldSession, route);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
}
}
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
index b4aad9df64a7..4086dec99218 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
@@ -39,6 +39,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import android.Manifest;
@@ -121,7 +122,7 @@ public class MediaRouter2ManagerTest {
MediaRouter2ManagerTestActivity.startActivity(mContext);
mManager = MediaRouter2Manager.getInstance(mContext);
- mManager.startScan();
+ mManager.registerScanRequest();
mRouter2 = MediaRouter2.getInstance(mContext);
// If we need to support thread pool executors, change this to thread pool executor.
@@ -152,7 +153,7 @@ public class MediaRouter2ManagerTest {
@After
public void tearDown() {
- mManager.stopScan();
+ mManager.unregisterScanRequest();
// order matters (callbacks should be cleared at the last)
releaseAllSessions();
@@ -818,6 +819,13 @@ public class MediaRouter2ManagerTest {
assertFalse(failureLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
}
+ @Test
+ public void unregisterScanRequest_enforcesANonNegativeCount() {
+ mManager.unregisterScanRequest(); // One request was made in the test setup.
+ assertThrows(IllegalStateException.class, () -> mManager.unregisterScanRequest());
+ mManager.registerScanRequest(); // So that the cleanup doesn't fail.
+ }
+
/**
* Tests if getSelectableRoutes and getDeselectableRoutes filter routes based on
* selected routes
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index b84ba922f5e0..15b39d2143ab 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index 7c2f0fffb73b..13dcb69f76ba 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"يطلب تطبيق <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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"يطلب تطبيق <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>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index e79780c05955..9df589a4a4da 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index cab8068609f7..1644110bfe16 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"Праграма \"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Праграма \"<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>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 16a785353d5d..101098cf9bd7 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index b9b130f02388..1eaf1424ed91 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <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>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index eee184cc9580..5cc72ae55e74 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> per reproduir en continu aplicacions entre els dispositius"</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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <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="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index aff0cdaa93b6..0d445287ef58 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"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="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index a136841a64f6..51b9a896699b 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -25,8 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Smartphone-Apps streamen"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string>
- <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</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; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
@@ -36,8 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos und Medien"</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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Zugriff auf die Fotos, Medien und Benachrichtigungen deines Smartphones"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 6bf4f6f124f6..b7511ba79e16 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index a8c6be3ddcb7..bce46e87d28a 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index e56b6236735a..40a55b5e2215 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"seade"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 31ebe978b3b9..28aaa87756b2 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -25,8 +25,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 baterako baino gehiagotarako zerbitzuak"</string>
- <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"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="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 09fd7e48346b..e52db88a3f06 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index 6f44de6fce7b..67252c501b66 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia laitteidesi välillä"</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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</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>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index a10136bd43bb..b85099ad2ca2 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 836d56201b94..8a13866a5a07 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -25,8 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Diffuser en streaming 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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 48110c45a83e..ccec06c62cc9 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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 contido de aplicacións entre os teus aparellos"</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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 2f552ad1738d..c6a8330b0482 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index e49b6537ce9a..867d70f568d0 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index b39854a9211a..ac458b377d36 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"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="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>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index dfd18e49ca92..b4b29cb05f2a 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 86c678e8feb5..82fa00aa45b4 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -25,8 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikasi ponsel"</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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index cf622e65e734..a2c628ffbc23 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index baaf53e952a9..793f0b89a34a 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -25,8 +25,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 a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a queste informazioni dal tuo telefono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string>
- <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index cf25568adad1..494c7eb22c22 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 514cefe66921..dbb1760d39bf 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index e4027de705bc..0d92a97b640e 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index a4e59110a977..4d85cfd9c3e7 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 72d9318210cf..a8a790a92eaf 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"ನಿಮ್ಮ ಫೋನ್‌ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index ed6fc63b2b21..2e4ef58a6f53 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 63318cbd5fbd..bc140a2d3a48 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index af79fab4dcd6..6a9197e84933 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index f88eba907db8..f2cbfa0adb11 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"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="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index f058e54df179..e8947c7eea44 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 23ced12a3338..6769b6c69928 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index 17f304536485..07e6a43a407d 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"നിങ്ങളുടെ ഫോണിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 3f83446133ce..1cc0412998de 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"तुमच्या फोनमधील फोटो, मीडिया आणि सूचना ॲक्सेस करण्यासाठी <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>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index bf1b537e9e7b..02743f00783d 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -25,8 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Strim apl telefon anda"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses maklumat ini daripada telefon anda"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string>
- <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses maklumat ini daripada telefon anda"</string>
@@ -36,8 +35,7 @@
<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">"Perkhidmatan Google Play"</string>
- <!-- no translation found for helper_summary_computer (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk mengakses foto, media dan pemberitahuan telefon anda"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 5a4b911dc8e7..6df06c13c155 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å strømme apper mellom enhetene dine, på vegne av <xliff:g id="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">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å få tilgang til bilder, medier og varsler på telefonen din, på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</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>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 9184bf576057..fc225088b916 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index f7b22ca46cbc..e56780607c71 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"ଆପଣଙ୍କ ଫୋନର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <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>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 804574cae147..dba72eb9260e 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index d7fd7b405fc9..360560ac7f37 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"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 treści z aplikacji na innym urządzeniu"</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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"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="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index dcc98502535a..f519239234d5 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"Приложение \"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Приложение \"<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>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 2c4e8ba2c07c..14feef6fee19 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"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="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index ae35c027190e..cefbff8e1ffb 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 928201742978..e2799b5aeeff 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 4e281a85bc28..9cb5f57eb038 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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 itiririshe programu kati ya vifaa vyako"</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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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 ifikie picha, maudhui na arifa za simu yako"</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>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index a7eeae73182d..fca9e0a23040 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 37bfea581050..8a3df03d3050 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -25,8 +25,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">"Cross-device services"</string>
- <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"మీ పరికరాల మధ్య యాప్‌లను స్ట్రీమ్ చేయడానికి <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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index 9be02097688a..7c31a21aef60 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 008a02f6af8e..756bcbbf855a 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -25,8 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun uygulamalarını yayınlama"</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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 062820e1cc6d..cc9f6b508208 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"Додаток <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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Додаток <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>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index 8b6a14ae4d2c..074049882b5c 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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">"‏اپنے فون سے اس معلومات تک رسائی حاصل Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کرنے کی اجازت دیں"</string>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 5c1262c85304..befb37050927 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"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="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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"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="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 7b95bad7adaf..7b3be4451d06 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"“<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"“<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>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index cb32f8b4b9b3..12dd892efb8a 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"「<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"「<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>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index bafeaaf8c975..eef3009e4ccf 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -25,8 +25,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 (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"「<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>
@@ -36,8 +35,7 @@
<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 (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"「<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>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index e148d0a82739..ec87f2dc2f27 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -25,8 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Sakaza ama-app wefoni yakho"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifinyelele lolu lwazi kusukela efonini yakho"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string>
- <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
- <skip />
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Vumela &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukufinyelela lolu lwazi kusuka efonini yakho"</string>
@@ -36,8 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Izithombe nemidiya"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Amasevisi we-Google Play"</string>
- <!-- no translation found for helper_summary_computer (9050724687678157852) -->
- <skip />
+ <string name="helper_summary_computer" msgid="9050724687678157852">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze ifinyelele izithombe zefoni yakho, imidiya nezaziso"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
index 614fa9072706..c6a1f401d946 100644
--- a/packages/PackageInstaller/res/values-hi/strings.xml
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -74,7 +74,7 @@
<string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"आपकी प्रोफ़ाइल के लिए यह ऐप्लिकेशन ज़रूरी है और उसे अनइंस्टॉल नहीं किया जा सकता."</string>
<string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"आपके डिवाइस एडमिन के लिए यह ऐप्लिकेशन ज़रूरी है और इसे अनइंस्टॉल नहीं किया जा सकता."</string>
<string name="manage_device_administrators" msgid="3092696419363842816">"डिवाइस एडमिन ऐप्लिकेशन प्रबंधित करें"</string>
- <string name="manage_users" msgid="1243995386982560813">"उपयोगकर्ताओं को प्रबंधित करें"</string>
+ <string name="manage_users" msgid="1243995386982560813">"उपयोगकर्ताओं को मैनेज करें"</string>
<string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> को अनइंस्‍टॉल नहीं किया जा सका."</string>
<string name="Parse_error_dlg_text" msgid="1661404001063076789">"पैकेज को पार्स करने में कोई समस्‍या थी."</string>
<string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml
index ebc43c4b5eb5..c016bfc1f8bb 100644
--- a/packages/PackageInstaller/res/values-te/strings.xml
+++ b/packages/PackageInstaller/res/values-te/strings.xml
@@ -59,7 +59,7 @@
<string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"మీ వర్క్ ప్రొఫైల్ నుండి ఈ యాప్‌ను మీరు అన్‌ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా?"</string>
<string name="uninstall_update_text" msgid="863648314632448705">"ఈ యాప్‌ను ఫ్యాక్టరీ వెర్షన్‌తో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది."</string>
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ఈ యాప్‌ను ఫ్యాక్టరీ వెర్షన్‌తో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది. దీని ప్రభావం కార్యాలయ ప్రొఫైళ్లు కలిగి ఉన్నవారితో సహా ఈ పరికర వినియోగదారులందరిపై ఉంటుంది."</string>
- <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> యాప్ డేటాని ఉంచండి."</string>
+ <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> యాప్ డేటాను ఉంచండి."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"అన్ఇన్‌స్టాల్ చేయబడుతున్నవి"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"విఫలమైన అన్‌ఇన్‌స్టాల్‌లు"</string>
<string name="uninstalling" msgid="8709566347688966845">"అన్ఇన్‌స్టాల్ చేస్తోంది…"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index af05078b4f3a..ac1a574f12cc 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -19,6 +19,7 @@ package com.android.packageinstaller;
import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
@@ -28,12 +29,12 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
-import android.os.UserManager;
import android.util.Log;
import java.util.Arrays;
@@ -47,14 +48,12 @@ public class InstallStart extends Activity {
private static final String DOWNLOADS_AUTHORITY = "downloads";
private PackageManager mPackageManager;
- private UserManager mUserManager;
private boolean mAbortInstall = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPackageManager = getPackageManager();
- mUserManager = getSystemService(UserManager.class);
Intent intent = getIntent();
String callingPackage = getCallingPackage();
String callingAttributionTag = null;
@@ -119,8 +118,9 @@ public class InstallStart extends Activity {
} else {
Uri packageUri = intent.getData();
- if (packageUri != null && packageUri.getScheme().equals(
- ContentResolver.SCHEME_CONTENT)) {
+ if (packageUri != null
+ && packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)
+ && canPackageQuery(originatingUid, packageUri)) {
// [IMPORTANT] This path is deprecated, but should still work. Only necessary
// features should be added.
@@ -140,7 +140,14 @@ public class InstallStart extends Activity {
}
if (nextActivity != null) {
- startActivity(nextActivity);
+ try {
+ startActivity(nextActivity);
+ } catch (SecurityException e) {
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT,
+ PackageManager.INSTALL_FAILED_INVALID_URI);
+ setResult(RESULT_FIRST_USER, result);
+ }
}
finish();
}
@@ -229,4 +236,21 @@ public class InstallStart extends Activity {
final ApplicationInfo appInfo = downloadProviderPackage.applicationInfo;
return (appInfo.isSystemApp() && uid == appInfo.uid);
}
+
+ @NonNull
+ private boolean canPackageQuery(int originatingUid, Uri packageUri) {
+ String callingPackage = mPackageManager.getPackagesForUid(originatingUid)[0];
+ ProviderInfo info = mPackageManager.resolveContentProvider(packageUri.getAuthority(),
+ PackageManager.ComponentInfoFlags.of(0));
+ if (info == null) {
+ return false;
+ }
+ String targetPackage = info.packageName;
+
+ try {
+ return mPackageManager.canPackageQuery(callingPackage, targetPackage);
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
}
diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index 62cfcc4fa99e..500a47211da8 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -43,7 +43,7 @@
<string name="summary_template" msgid="8899734908625669193">"సారాంశం, కాపీలు <xliff:g id="COPIES">%1$s</xliff:g>, కాగితం పరిమాణం <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
<string name="expand_handle" msgid="7282974448109280522">"విస్తరణ హ్యాండిల్"</string>
<string name="collapse_handle" msgid="6886637989442507451">"కుదింపు హ్యాండిల్"</string>
- <string name="print_button" msgid="645164566271246268">"ముద్రించు"</string>
+ <string name="print_button" msgid="645164566271246268">"ప్రింట్ చేయండి"</string>
<string name="savetopdf_button" msgid="2976186791686924743">"PDF లాగా సేవ్ చేయి"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"ముద్రణ ఎంపికలు విస్తరించబడ్డాయి"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"ముద్రణ ఎంపికలు కుదించబడ్డాయి"</string>
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
index 238e65ec9a3c..7968e96009b5 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -25,6 +25,7 @@ android_library {
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
+ "com.android.adservices",
"com.android.cellbroadcast",
"com.android.permission",
],
diff --git a/packages/SettingsLib/MainSwitchPreference/Android.bp b/packages/SettingsLib/MainSwitchPreference/Android.bp
index fc06fdcce131..dd29827917da 100644
--- a/packages/SettingsLib/MainSwitchPreference/Android.bp
+++ b/packages/SettingsLib/MainSwitchPreference/Android.bp
@@ -23,6 +23,7 @@ android_library {
min_sdk_version: "28",
apex_available: [
"//apex_available:platform",
+ "com.android.adservices",
"com.android.cellbroadcast",
],
}
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
index 32260a44b783..ca84db854bdd 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
@@ -19,6 +19,11 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingTop="@dimen/settingslib_switchbar_margin"
+ android:paddingBottom="@dimen/settingslib_switchbar_margin"
android:orientation="vertical">
<LinearLayout
@@ -26,7 +31,6 @@
android:minHeight="@dimen/settingslib_min_switch_bar_height"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:layout_margin="@dimen/settingslib_switchbar_margin"
android:paddingStart="@dimen/settingslib_switchbar_padding_left"
android:paddingEnd="@dimen/settingslib_switchbar_padding_right">
diff --git a/packages/SettingsLib/SettingsTransition/Android.bp b/packages/SettingsLib/SettingsTransition/Android.bp
index f06a9a7c0f43..708141b7090c 100644
--- a/packages/SettingsLib/SettingsTransition/Android.bp
+++ b/packages/SettingsLib/SettingsTransition/Android.bp
@@ -20,6 +20,7 @@ android_library {
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
+ "com.android.adservices",
"com.android.cellbroadcast",
"com.android.permission",
],
diff --git a/packages/SettingsLib/Utils/Android.bp b/packages/SettingsLib/Utils/Android.bp
index 7d5eb69190b6..1b002613f90a 100644
--- a/packages/SettingsLib/Utils/Android.bp
+++ b/packages/SettingsLib/Utils/Android.bp
@@ -23,6 +23,7 @@ android_library {
apex_available: [
"//apex_available:platform",
+ "com.android.adservices",
"com.android.permission",
"com.android.cellbroadcast",
],
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index e933aab86b25..264faad485c1 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Lêeroordrag"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Invoertoestel"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internettoegang"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontakdeling"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gebruik vir kontakdeling"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deling van internetverbinding"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Teksboodskappe"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-toegang"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 6eef0534e61b..b68cbd745e01 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ፋይል ማስተላለፍ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ግቤት መሣሪያ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"የበይነመረብ ድረስ"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"እውቂያ ማጋራት"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"እውቂያን ለማጋራት ተጠቀም"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"የበይነ መረብ ተያያዥ ማጋሪያ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"የጽሑፍ መልዕክቶች"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"የሲም መዳረሻ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index cf6040e0509e..c8b263bcb196 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"نقل الملف"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"جهاز الإرسال"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"استخدام الإنترنت"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"مشاركة جهات الاتصال"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"استخدام مع مشاركة جهة الاتصال"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"مشاركة اتصال الإنترنت"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"الرسائل النصية"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"‏الوصول إلى شريحة SIM"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 222b6caf3fde..ea1aff001aa5 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ফাইল স্থানান্তৰণ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ইনপুট ডিভাইচ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ইণ্টাৰনেট সংযোগ"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"সম্পৰ্ক শ্বেয়াৰ কৰা"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"সম্পৰ্ক শ্বেয়াৰ কৰিবলৈ ব্যৱহাৰ কৰক"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ইণ্টাৰনেট সংযোগ শ্বেয়াৰ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"পাঠ বাৰ্তা"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"ছিম প্ৰৱেশ"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 4efc63c59aeb..88333e82782e 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fayl transferi"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Daxiletmə cihazı"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"İnternetə giriş"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontakt paylaşımı"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kontakt paylaşımı üçün istifadə edin"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"internet bağlantı paylaşımı"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mətn Mesajları"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-karta giriş"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 2a19d647da8b..a84d0190607a 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup Internetu"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deljenje kontakata"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Koristite za deljenje kontakata"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deljenje internet veze"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ovi"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Pristup SIM kartici"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 1892ec9c55e0..37f8410dd87c 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Перадача файлаў"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Прылада ўводу"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Доступ у інтэрнэт"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Абагульванне кантактаў"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Выкарыстоўваць для абагульвання кантактаў"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Прадастаўленне доступу да Інтэрнэту"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Тэкставыя паведамленні"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Доступ да SIM-карты"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index a309c8e86312..f2cf69ea5b1c 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Прехвърляне на файл"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Входно устройство"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Достъп до интернет"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Споделяне на контакти"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Използване за споделяне на контакти"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Споделяне на връзката с интернет"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Текстови съобщения"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Достъп до SIM картата"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index a99a90c7ef33..801fb347a4ac 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ফাইল স্থানান্তর"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ইনপুট ডিভাইস"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ইন্টারনেট অ্যাক্সেস"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"পরিচিতি শেয়ার করা"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"পরিচিতি শেয়ার করার কাজে ব্যবহার করুন"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ইন্টারনেট কানেকশন শেয়ার করা হচ্ছে"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"এসএমএস"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"সিম অ্যাক্সেস"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index db3220adc1de..61082f6dd7f5 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenošenje fajla"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup internetu"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Dijeljenje kontakata"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Koristi za dijeljenje kontakta"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Dijeljenje internet veze"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ovi"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Pristup SIM-u"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 4fe6187c8861..881f9d4ea193 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferència de fitxers"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositiu d\'entrada"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accés a Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartició de contactes"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"S\'utilitza per compartir contactes."</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartició de connexió d\'Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Missatges de text"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accés a la SIM"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 872e38e73435..7f314bde25c4 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Přenos souborů"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vstupní zařízení"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Přístup k internetu"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Sdílení kontaktů"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Použít ke sdílení kontaktů"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Sdílení internetového připojení"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Textové zprávy"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Přístup k SIM kartě"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index bb7bee2af0bc..c470b8193fbd 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filoverførsel"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Inputenhed"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetadgang"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deling af kontakter"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Brug til deling af kontakter"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deling af internetforbindelse"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Sms-beskeder"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Adgang til SIM-kort"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index a1693ce0773e..34a622bcb925 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dateiübertragung"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Eingabegerät"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetzugriff"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktfreigabe"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Für Kontaktfreigabe nutzen"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Freigabe der Internetverbindung"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Zugriff auf SIM"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index d775dd7890a6..fdc7419359b5 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Μεταφορά αρχείου"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Συσκευή εισόδου"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Πρόσβαση στο Διαδίκτυο"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Κοινή χρήση επαφών"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Για κοινή χρήση επαφών"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Κοινή χρήση σύνδεσης στο Διαδίκτυο"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Μηνύματα κειμένου"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Πρόσβαση SIM"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 8cad471ee41a..234109bd401c 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Input device"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internet access"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contact sharing"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 2614f7107a76..d88bb0e776cf 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Input device"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internet access"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contact sharing"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 8cad471ee41a..234109bd401c 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Input device"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internet access"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contact sharing"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 8cad471ee41a..234109bd401c 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Input device"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internet access"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contact sharing"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index c956bd4a384d..5d775d3a356b 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -117,8 +117,8 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎File transfer‎‏‎‎‏‎"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎Input device‎‏‎‎‏‎"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎Internet access‎‏‎‎‏‎"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎Contact sharing‎‏‎‎‏‎"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎Use for contact sharing‎‏‎‎‏‎"</string>
+ <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎Contacts and call history sharing‎‏‎‎‏‎"</string>
+ <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎Use for contacts and call history sharing‎‏‎‎‏‎"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎Internet connection sharing‎‏‎‎‏‎"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‏‏‎Text Messages‎‏‎‎‏‎"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎SIM Access‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index f7783a49dafc..98c140045b23 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de archivos"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acceso a Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartir contactos"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utilizar para compartir contactos"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartir conexión a Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensajes de texto"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acceso a SIM"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 1116134c13f9..90c4fb8e938a 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de archivos"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acceso a Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartir contactos"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Usar para compartir contactos"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartir conexión a Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensajes de texto"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acceso a tarjeta SIM"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 64b524999200..a6c787af5146 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failiedastus"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Sisendseade"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Juurdepääs internetile"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktide jagamine"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kasutamine kontaktide jagamiseks"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneti-ühenduse jagamine"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Tekstsõnumid"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Juurdepääs SIM-ile"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 1cfec2c82c55..87cfaa8dac95 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fitxategi-transferentzia"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Sarrerako gailua"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Interneteko konexioa"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktuak partekatzea"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Erabili kontaktuak partekatzeko"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneteko konexioa partekatzea"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Testu-mezuak"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIMerako sarbidea"</string>
@@ -389,7 +391,7 @@
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Gaitu GPUaren arazketa-geruzak"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Eman GPUaren arazketa-geruzak kargatzeko baimena arazketa-aplikazioei"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Gaitu saltzaileen erregistro xehatuak"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sartu gailuaren berariazko saltzaileen erregistro gehigarriak akatsen txostenetan; baliteke haiek informazio pribatua izatea, bateria gehiago erabiltzea edo biltegiratzeko toki gehiago hartzea."</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sartu gailuaren berariazko saltzaileen erregistro gehigarriak akatsen txostenetan; baliteke haiek informazio pribatua izatea, bateria gehiago erabiltzea eta/edo biltegiratzeko toki gehiago hartzea."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Leihoen animazio-eskala"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Trantsizioen animazio-eskala"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatzailearen iraupen-eskala"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 8e702dbabdbe..51d74dd86ea9 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"انتقال فایل"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"دستگاه ورودی"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"دسترسی به اینترنت"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"هم‌رسانی مخاطب"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"استفاده برای هم‌رسانی مخاطب"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"اشتراک‌گذاری اتصال اینترنت"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"پیام‌های نوشتاری"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"دسترسی سیم‌کارت"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 03c72bcdc2e0..c0f90b8e5a4c 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Tiedostonsiirto"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Syöttölaite"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetyhteys"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Yhteystietojen jakaminen"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Käytä yhteystietojen jakamiseen"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internetyhteyden jakaminen"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Tekstiviestit"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-kortin käyttö"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 6b5102c5b662..14515cd4ec7d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfert de fichier"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Périphérique d\'entrée"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accès Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Partage de contacts"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utiliser pour le partage de contacts"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partage de connexion Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Messages texte"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accès à la carte SIM"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 47026629c7ee..19ea6ddf2c9b 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfert de fichiers"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Périphérique d\'entrée"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accès Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Partage de contacts"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utiliser pour le partage de contacts"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partage de connexion Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accès à la carte SIM"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index ec636618e59f..94fa72a260b1 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de ficheiros"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acceso a Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartir contactos"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utilizar para compartir contactos"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Uso compartido da conexión a Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensaxes de texto"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acceso á SIM"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index af5465660ce2..a474d8226364 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ફાઇલ સ્થાનાંતરણ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ઇનપુટ ડિવાઇસ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ઇન્ટરનેટ ઍક્સેસ"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"સંપર્ક શેરિંગ"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"સંપર્ક શેરિંગ માટે ઉપયોગ કરો"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ઇન્ટરનેટ કનેક્શન શેરિંગ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"ટેક્સ્ટ સંદેશા"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"સિમ ઍક્સેસ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 96fba8f5eba9..55fc547444cd 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"फ़ाइल स्थानांतरण"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"इनपुट डिवाइस"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"इंटरनेट ऐक्सेस"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"संपर्क शेयर करना"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"संपर्क साझाकरण के लिए उपयोग करें"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इंटरनेट कनेक्शन साझाकरण"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"लेख संदेश"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"सिम ऐक्सेस"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index c9be92ed4f06..55a3e5ed7b4a 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prijenos datoteke"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup internetu"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Dijeljenje kontakata"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Upotrijebi za dijeljenje kontakata"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Dijeljenje internetske veze"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ovi"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Pristup SIM-u"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 232a9638b65b..2454d1cc5f90 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fájlátvitel"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Beviteli eszköz"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetelérés"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Névjegyek megosztása"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Használja a névjegyek megosztására"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internetkapcsolat megosztása"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Szöveges üzenetek"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-elérés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 94c4abd2abbc..896655119ab7 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Ֆայլերի փոխանցում"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ներմուծման սարք"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ինտերնետի հասանելիություն"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Կոնտակտների փոխանակում"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Օգտագործել կոնտակտի համօգտագործման համար"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Ինտերնետ կապի տարածում"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS հաղորդագրություններ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM քարտի հասանելիություն"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index cd74fea2fb2b..c525317c65ec 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfer file"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Perangkat masukan"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Akses Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Berbagi kontak"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gunakan untuk berbagi kontak"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Berbagi koneksi internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Akses SIM"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index d5b438033b95..c06d2f0cc497 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Skráaflutningur"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Inntakstæki"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetaðgangur"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deiling tengiliða"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Nota til að deila tengiliðum"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deiling nettengingar"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Textaskilaboð"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Aðgangur að SIM-korti"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 7130c80ada14..b3ac25aaeafc 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Trasferimento file"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo di input"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accesso a Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Condivisione contatti"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Usa per condivisione contatti"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Condivisione connessione Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accesso alla SIM"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 3e7b7d85b7b8..f021b3742399 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"העברת קבצים"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"מכשיר קלט"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"גישה לאינטרנט"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"שיתוף אנשי קשר"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"שימוש עבור שיתוף אנשי קשר"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"שיתוף חיבור לאינטרנט"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"הודעות טקסט"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"‏גישה ל-SIM"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index abbb7608ebb4..2994e4d41559 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ファイル転送"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"入力デバイス"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"インターネットアクセス"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"連絡先の共有"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"連絡先の共有に使用"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"インターネット接続の共有"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"テキスト メッセージ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIMアクセス"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 87222c24de1d..0c3277bacc31 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ფაილების გადაცემა"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"შეყვანის მოწყობილობა"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ინტერნეტზე წვდომა"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"კონტაქტის გაზიარება"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"კონტაქტის გაზიარებისთვის გამოყენება"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ინტერნეტ კავშირის გაზიარება"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"ტექსტური შეტყობინებები"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM წვდომა"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 4e6c576c707f..63c95759a1ba 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл жіберу"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Кіріс құрылғысы"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Интернетке қосылу"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Контакт бөлісу"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Контактіні бөлісу үшін пайдалану"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Интернет байланысын ортақ қолдану"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Мәтіндік хабарлар"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM картасына кіру"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 71c0f2061a52..9b9228a6d862 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ផ្ទេរ​ឯកសារ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ឧបករណ៍​បញ្ចូល"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ការចូលប្រើ​អ៊ីនធឺណិត"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ការ​ចែករំលែក​​ទំនាក់ទំនង"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ប្រើ​សម្រាប់​ការ​ចែករំលែក​ទំនាក់ទំនង"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ចែករំលែក​ការ​តភ្ជាប់​អ៊ីនធឺណិត"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"សារ​ជាអក្សរ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"ការចូលដំណើរការស៊ីម"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 2dacee0bbd05..7071598a6b0e 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ಫೈಲ್ ವರ್ಗಾವಣೆ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ಇನ್‌ಪುಟ್‌ ಸಾಧನ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ಸಂಪರ್ಕ ಹಂಚಿಕೆ"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ಸಂಪರ್ಕ ಹಂಚಿಕೆಗಾಗಿ ಬಳಸಿ"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"ಪಠ್ಯ ಸಂದೇಶಗಳು"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"ಸಿಮ್ ಪ್ರವೇಶ"</string>
@@ -232,7 +234,7 @@
<string name="vpn_settings_not_available" msgid="2894137119965668920">"VPN ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="tethering_settings_not_available" msgid="266821736434699780">"ಟೆಥರಿಂಗ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"ಪ್ರವೇಶ ಬಿಂದು ಹೆಸರಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="enable_adb" msgid="8072776357237289039">"USB ಡೀಬಗಿಂಗ್‌"</string>
+ <string name="enable_adb" msgid="8072776357237289039">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
<string name="enable_adb_summary" msgid="3711526030096574316">"USB ಸಂಪರ್ಕಗೊಂಡಾಗ ಡೀಬಗ್ ಮೋಡ್"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯ ಅಧಿಕೃತಗೊಳಿಸುವಿಕೆಗಳನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಿ"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗಿಂಗ್"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 899f2de80157..6ba289da9ba7 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"파일 전송"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"입력 장치"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"인터넷 액세스"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"연락처 공유"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"연락처 공유용"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"인터넷 연결 공유"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"문자 메시지"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 액세스"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 5b9485a79b52..3eb43fac9151 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл алмашуу"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Киргизүү түзмөгү"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Интернетке мүмкүнчүлүк алуу"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Байланышты бөлүшүү"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Байланышты бөлүшүү үчүн колдонуу"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Интернет байланышын бөлүшүү"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS билдирүүлөрү"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM картаны пайдалануу мүмкүнчүлүгү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index a65ada07b821..2dcad1fb774c 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ການໂອນຍ້າຍໄຟລ໌"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ອຸປະກອນປ້ອນຂໍ້ມູນ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ການເຂົ້າເຖິງອິນເຕີເນັດ"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ການ​ແບ່ງ​ປັນ​ລາຍ​ຊື່​ຜູ້​ຕິດ​ຕໍ່"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"​ໃຊ້​ສຳ​ລັບການ​ແບ່ງ​ປັນ​ລາຍ​ຊື່​ຜູ່​ຕິດ​ຕໍ່"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ການແບ່ງປັນການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"ຂໍ້ຄວາມ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"ການ​ເຂົ້າ​ເຖິງ SIM"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 79856785d627..8aaec470c3bb 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failo perkėlimas"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Įvesties įrenginys"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Prieiga prie interneto"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktų bendrinimas"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Naudoti kontaktams bendrinti"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneto ryšio bendrinimas"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Teksto pranešimai"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM prieiga"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 63af239f69a9..fcfb9b895313 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failu pārsūtīšana"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ievades ierīce"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Interneta piekļuve"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktpersonas informācijas kopīgošana"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Izmantot kontaktpersonas informācijas kopīgošanai"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneta savienojuma koplietošana"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Īsziņas"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Piekļuve SIM kartei"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 46458cd56c9a..144de00caa6b 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос на датотека"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Влезен уред"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Пристап до интернет"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Споделување контакти"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Користи за споделување контакти"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Споделување конекција на интернет"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Текстуални пораки"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Пристап до SIM"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 0d093bd1748b..59cd6bcee94f 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ഫയൽ കൈമാറൽ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ഇൻപുട്ട് ഉപകരണം"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ഇന്‍റർനെറ്റ് ആക്‌സസ്"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"കോൺടാക്‌റ്റ് പങ്കിടൽ"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"കോൺടാക്‌റ്റ് പങ്കിടലിനായി ഉപയോഗിക്കുക"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ഇന്റർനെറ്റ് കണക്ഷൻ പങ്കിടൽ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"അക്ഷര സന്ദേശങ്ങൾ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"സിം ആക്സസ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 75abf997a8cf..1bd6beaacee5 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл дамжуулалт"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Оруулах төхөөрөмж"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Интернэт хандалт"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Харилцагч хуваалцах"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Харилцагч хуваалцахад ашиглах"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Интернэт холболтыг хуваалцах"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Мессеж"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM Хандалт"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 42832f18afef..c163219be81c 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"फाइल स्थानांतरण"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"इनपुट डिव्हाइस"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"इंटरनेट अ‍ॅक्सेस"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"संपर्क शेअरिंग"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"संपर्क सामायिकरणासाठी वापरा"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इंटरनेट कनेक्शन शेअररण"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"मजकूर मेसेज"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"सिम अ‍ॅक्सेस"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 41fdec6ee639..55c881403bff 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Pemindahan fail"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Peranti input"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Akses Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Perkongsian kenalan"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gunakan untuk perkongsian kenalan"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Perkongsian sambungan Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mesej Teks"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Akses SIM"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 3c7e5b3a883f..38b1fe82456a 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ဖိုင်လွဲပြောင်းခြင်း"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ထည့်သွင်းသော စက်"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"အင်တာနက်ချိတ်ဆက်ခြင်း"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"အဆက်အသွယ်ကို မျှဝေခြင်း"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"အဆက်အသွယ်ကို မျှဝေရန် အတွက် သုံးရန်"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"အင်တာနက်ဆက်သွယ်မှု မျှဝေခြင်း"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"မိုဘိုင်းမက်ဆေ့ဂျ်များ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM အသုံးပြုခြင်း"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 838e96139c8e..ef2111d1c7d4 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filoverføring"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Inndataenhet"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internett-tilgang"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktdeling"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Bruk til kontaktdeling"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deling av internettilkobling"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Tekstmeldinger"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Tilgang til SIM-kortet"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index d3678d30145c..9fa7749359e8 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"फाइल स्थानान्तरण"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"इनपुट उपकरण"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"इन्टरनेट पहुँच"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"कन्ट्याक्ट सेयरिङ"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"सम्पर्क साझेदारीका लागि प्रयोग"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इन्टरनेट जडान साझेदारी गर्दै"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"टेक्स्ट म्यासेजहरू"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM पहुँच"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index b0a5afdd1090..f4cbfd50ff69 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Bestandsoverdracht"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Invoerapparaat"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internettoegang"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contacten delen"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gebruiken voor contacten delen"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internetverbinding delen"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Sms-berichten"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Sim-toegang"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index fbe89e399ec7..76c367195a9c 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ଇନ୍‌ପୁଟ୍‌ ଡିଭାଇସ୍"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ଆକ୍ସେସ୍"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ଯୋଗାଯୋଗ ସେୟାରିଂ"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ଯୋଗାଯୋଗ ସେୟାର୍‌ କରିବା ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ସଂଯୋଗ ଶେୟାରିଙ୍ଗ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"ଟେକ୍ସଟ୍ ମେସେଜ୍"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM ଆକ୍ସେସ୍‌"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 1330fa747a00..e34ece84d8ee 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ਇਨਪੁੱਟ ਡੀਵਾਈਸ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ਸੰਪਰਕ ਸਾਂਝਾਕਰਨ"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ਸੰਪਰਕ ਸ਼ੇਅਰਿੰਗ ਲਈ ਵਰਤੋ"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਸਾਂਝਾਕਰਨ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"ਲਿਖਤ ਸੁਨੇਹੇ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"ਸਿਮ ਪਹੁੰਚ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index d700e5506139..fe56c6170224 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Przesyłanie pliku"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Urządzenie wejściowe"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Dostęp do internetu"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Udostępnianie kontaktów"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Używaj do udostępniania kontaktów"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Udostępnianie połączenia internetowego"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-y"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Dostęp do karty SIM"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 2ae177dc35ad..aa66c604304b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência de arquivo"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acesso à Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartilhar contatos"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Usar para compartilhar contatos"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartilhamento de conexão à Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensagens de texto"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acesso ao chip"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 8d9a61980dc1..cf767809da05 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência do ficheiro"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acesso à internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Partilha de contactos"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utilizar para a partilha de contactos"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partilha da ligação à internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensagens de texto"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acesso ao SIM"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 2ae177dc35ad..aa66c604304b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência de arquivo"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acesso à Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartilhar contatos"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Usar para compartilhar contatos"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartilhamento de conexão à Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensagens de texto"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acesso ao chip"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 20b39a54de99..946f4b7e1afa 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfer de fișiere"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispozitiv de intrare"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acces la internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Acces la Agendă"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utilizați pentru a permite accesul la Agendă"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Distribuirea conexiunii la internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mesaje text"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acces la SIM"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index aa467ace3350..bcd83cf4cd79 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Профиль OPP"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Профиль HID"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Доступ к интернету"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Обмен контактами"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Использовать для обмена контактами"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Профиль PAN"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Текстовые сообщения"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Доступ к SIM-карте"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 748a93f7d9e4..7f5eb4921ed7 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ගොනු හුවමාරුව"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ආදාන උපාංගය"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"අන්තර්ජාල ප්‍රවේශය"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"සම්බන්ධතා බෙදාගැනීම"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"සම්බන්ධතා බෙදාගැනීම සඳහා භාවිතා කිරීම"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"අන්තර්ජාල සම්බන්ධතා බෙදාගැනීම"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"පෙළ පණිවිඩ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM ප්‍රවේශය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 3845951eca9a..31925eaf0844 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos súborov"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vstupné zariadenie"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Prístup na internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Zdieľanie kontaktov"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Použiť na zdieľanie kontaktov"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Zdieľanie pripojenia na Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Textové správy"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Prístup k SIM karte"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 1d87352361fa..687ff38d4fc2 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vnosna naprava"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetni dostop"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deljenje stikov"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Uporabi za deljenje stikov"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deljenje internetne povezave"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Sporočila SMS"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Dostop do kartice SIM"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 647c2e19a919..7e96990af569 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferimi i skedarëve"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Pajisja e hyrjes"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Qasje në internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Ndarja e kontakteve"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Përdore për ndarjen e kontakteve"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Ndarja e lidhjes së internetit"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mesazhet me tekst"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Qasje në kartën SIM"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 6ff020cd7e78..2842223032c0 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос датотеке"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Улазни уређај"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Приступ Интернету"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Дељење контаката"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Користите за дељење контаката"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Дељење интернет везе"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ови"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Приступ SIM картици"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index ea284d537220..b0f8df59be3c 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filöverföring"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Indataenhet"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetåtkomst"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktdelning"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Använd för kontaktdelning"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Delning av Internetanslutning"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Sms"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-åtkomst"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 50ca8d92730d..7e62d3fdb644 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Uhamishaji wa faili"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Kifaa cha kuingiza"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ufikiaji wa intaneti"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kushiriki anwani"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Tumia kwa kushiriki anwani"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Kushiriki muunganisho wa tovuti"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Ufikiaji wa SIM"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 5b8ae38d7508..abab3fb54361 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ஃபைல் இடமாற்றம்"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"உள்ளீட்டுச் சாதனம்"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"இணைய அணுகல்"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"தொடர்பைப் பகிர்தல்"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"தொடர்புப் பகிர்தலுக்குப் பயன்படுத்து"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"இணைய இணைப்பு பகிர்தல்"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"உரைச் செய்திகள்"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"சிம் அணுகல்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 3f82d47ddb66..a362f24a75b6 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ఫైల్ బదిలీ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ఇన్‌పుట్ పరికరం"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ఇంటర్నెట్ యాక్సెస్"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"కాంటాక్ట్ షేరింగ్"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"కాంటాక్ట్ షేరింగ్ కోసం ఉపయోగించండి"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ఇంటర్నెట్ కనెక్షన్ షేరింగ్"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"టెక్స్ట్ మెసేజ్‌లు"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM యాక్సెస్"</string>
@@ -270,7 +272,7 @@
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"బ్లూటూత్ HCI రహస్య లాగ్‌ను ఎనేబుల్ చేయి"</string>
<string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"బ్లూటూత్‌ ప్యాకెట్‌లను క్యాప్చర్ చేయి. (ఈ సెట్టింగ్‌ని మార్చిన తర్వాత బ్లూటూత్‌ని టోగుల్ చేయండి)"</string>
<string name="oem_unlock_enable" msgid="5334869171871566731">"OEM అన్‌లాకింగ్"</string>
- <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"బూట్‌లోడర్ అన్‌లాక్ కావడానికి అనుమతించు"</string>
+ <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"బూట్‌లోడర్ అన్‌లాక్ కావడానికి అనుమతించండి"</string>
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM అన్‌లాకింగ్‌ను అనుమతించాలా?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"హెచ్చరిక: ఈ సెట్టింగ్ ఆన్ చేయబడినప్పుడు పరికరం రక్షణ లక్షణాలు ఈ పరికరంలో పని చేయవు."</string>
<string name="mock_location_app" msgid="6269380172542248304">"డమ్మీ లొకేష‌న్‌ యాప్‌ను ఎంచుకోండి"</string>
@@ -281,7 +283,7 @@
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi విశదీకృత లాగింగ్‌ను ప్రారంభించండి"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi స్కాన్ కుదింపు"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Wi‑Fi నిరంతరం కాని MAC ర్యాండమైజేషన్"</string>
- <string name="mobile_data_always_on" msgid="8275958101875563572">"మొబైల్ డేటాని ఎల్లప్పుడూ యాక్టివ్‌గా ఉంచు"</string>
+ <string name="mobile_data_always_on" msgid="8275958101875563572">"మొబైల్ డేటాను ఎల్లప్పుడూ యాక్టివ్‌గా ఉంచు"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"టెథెరింగ్ హార్డ్‌వేర్ యాగ్జిలరేషన్"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"పేర్లు లేని బ్లూటూత్ పరికరాలు చూపించు"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"సంపూర్ణ వాల్యూమ్‌‍ను డిజేబుల్ చేయి"</string>
@@ -381,7 +383,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"క్లిప్ సరిహద్దులు, అంచులు మొ. చూపు"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL లేఅవుట్ దిశను నిర్బంధం చేయండి"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"అన్ని లొకేల్‌ల కోసం RTLకి స్క్రీన్ లేఅవుట్ దిశను నిర్భందించు"</string>
- <string name="window_blurs" msgid="6831008984828425106">"విండో-స్థాయి బ్లర్ అనుమతించు"</string>
+ <string name="window_blurs" msgid="6831008984828425106">"విండో-స్థాయి బ్లర్ అనుమతించండి"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA అమలు తప్పనిసరి"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 యాప్‌లలో 4x MSAAను ప్రారంభించండి"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"దీర్ఘ చతురస్రం కాని క్లిప్ చర్యలను డీబగ్ చేయండి"</string>
@@ -402,7 +404,7 @@
<string name="show_all_anrs_summary" msgid="8562788834431971392">"బ్యాక్‌గ్రౌండ్ యాప్‌ల కోసం యాప్ ప్రతిస్పందించడం లేదు అనే డైలాగ్‌ను చూపు"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"ఛానెల్ హెచ్చరికల నోటిఫికేషన్‌‌ను చూపు"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"చెల్లుబాటు అయ్యే ఛానెల్ లేకుండా యాప్ నోటిఫికేషన్‌ను పోస్ట్ చేస్తున్నప్పుడు స్క్రీన్‌పై హెచ్చరికను చూపిస్తుంది"</string>
- <string name="force_allow_on_external" msgid="9187902444231637880">"యాప్‌లను బాహ్య స్టోరేజ్‌లో తప్పనిసరిగా అనుమతించు"</string>
+ <string name="force_allow_on_external" msgid="9187902444231637880">"యాప్‌లను బాహ్య స్టోరేజ్‌లో తప్పనిసరిగా అనుమతించండి"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ఏ యాప్‌ను అయినా మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా బాహ్య స్టోరేజ్‌లో సేవ్ చేయడానికి అనుమతిస్తుంది"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"యాక్టివిటీ విండోల సైజ్‌ మార్చ‌గ‌లిగేలా నిర్బంధించు"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా అన్ని యాక్టివిటీస్‌ను పలు రకాల విండోల్లో సరిపోయేటట్లు సైజ్‌ మార్చగలిగేలా చేస్తుంది."</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index c513ae794948..a4e050867f40 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"การถ่ายโอนไฟล์"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"อุปกรณ์อินพุต"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"การเข้าถึงอินเทอร์เน็ต"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"การแชร์รายชื่อผู้ติดต่อ"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ใช้สำหรับการแชร์รายชื่อผู้ติดต่อ"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"การแชร์การเชื่อมต่ออินเทอร์เน็ต"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"ข้อความ"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"การเข้าถึงซิม"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 9872bec1bc1f..e28fd961340c 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Paglilipat ng file"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Device sa pag-input"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Access sa internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Pagbabahagi ng contact"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gamitin para sa pagbabahagi ng contact"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Pagbabahagi ng koneksyon sa internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Mga Text Message"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Access sa SIM"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index ca4ccbd32df6..05ec1cc1255b 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dosya aktarımı"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Giriş cihazı"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"İnternet erişimi"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kişi paylaşma"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kişi paylaşmak için kullan"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"İnternet bağlantısı paylaşımı"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Kısa Mesajlar"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM Erişimi"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index b9599b79d3fa..184d0c118b22 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Передавання файлів"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Пристрій введення"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Доступ до Інтернету"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Надсилання контактів"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Використовувати для надсилання контактів"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Надання доступу до Інтернету"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Текстові повідомлення"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Доступ до SIM-карти"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index c67c8e74575e..419833a457e3 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"فائل کی منتقلی"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ان پٹ آلہ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"انٹرنیٹ تک رسائی"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"رابطہ کا اشتراک"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"رابطہ کے اشتراک کیلئے استعمال کریں"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"انٹرنیٹ کنکشن کا اشتراک کرنا"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"ٹیکسٹ پیغامات"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"‏SIM رسائی"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index e0f2897dd1ba..b1e22af84503 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fayl uzatish"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Kiritish qurilmasi"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetga ulanish"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktlarni ulashish"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kontaktlarni ulashish uchun ishlatilsin"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet aloqasi ulashmasi"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS xabarlari"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM kartaga kirish"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index fa9e57fa9747..71bb08e94539 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Chuyển tệp"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Thiết bị đầu vào"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Truy cập Internet"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Chia sẻ người liên hệ"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Sử dụng để chia sẻ người liên hệ"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Chia sẻ kết nối internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Tin nhắn văn bản"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Truy cập SIM"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index cca21edcf42c..f9e087b9b212 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"文件传输"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"输入设备"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"互联网连接"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"共享联系人"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"用于共享联系人"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"共享互联网连接"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"短信"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡存取权限"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index a65f77b004c1..cd93f71e1e3e 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"檔案傳輸"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"輸入裝置"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"互聯網連線"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"共用聯絡人"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"用於共用聯絡人"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"互聯網連線分享"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"短訊"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡存取"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index b207326259bd..4f36742f59f2 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"檔案傳輸"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"輸入裝置"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"網際網路連線"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"聯絡人共用"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"用於聯絡人共用"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"網際網路連線分享"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"簡訊"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡存取權"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 040dfaa57aae..88c41c580617 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -117,8 +117,10 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dlulisa ifayela"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Idivaysi yokufakwayo"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ukufinyelela i-Inthanethi"</string>
- <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Ukwabelana kokuxhumana"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Sebenzisela ukwabelana kokuxhumana"</string>
+ <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+ <skip />
+ <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+ <skip />
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Ukwabelana ngoxhumano lwe-Inthanethi"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Imilayezo yombhalo"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Ukufinyelela kwe-SIM"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 58944f653869..4714ff93625b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -576,6 +576,15 @@ public class LocalBluetoothProfileManager {
return;
}
+ // The profiles list's sequence will affect the bluetooth icon at
+ // BluetoothUtils.getBtClassDrawableWithDescription(Context,CachedBluetoothDevice).
+
+ // Moving the LE audio profile to be the first priority if the device supports LE audio.
+ if (ArrayUtils.contains(uuids, BluetoothUuid.LE_AUDIO) && mLeAudioProfile != null) {
+ profiles.add(mLeAudioProfile);
+ removedProfiles.remove(mLeAudioProfile);
+ }
+
if (mHeadsetProfile != null) {
if ((ArrayUtils.contains(localUuids, BluetoothUuid.HSP_AG)
&& ArrayUtils.contains(uuids, BluetoothUuid.HSP))
@@ -660,11 +669,6 @@ public class LocalBluetoothProfileManager {
removedProfiles.remove(mHearingAidProfile);
}
- if (ArrayUtils.contains(uuids, BluetoothUuid.LE_AUDIO) && mLeAudioProfile != null) {
- profiles.add(mLeAudioProfile);
- removedProfiles.remove(mLeAudioProfile);
- }
-
if (mSapProfile != null && ArrayUtils.contains(uuids, BluetoothUuid.SAP)) {
profiles.add(mSapProfile);
removedProfiles.remove(mSapProfile);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 192872f5f926..d9262cce3cb9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -92,14 +92,14 @@ public class InfoMediaManager extends MediaManager {
public void startScan() {
mMediaDevices.clear();
mRouterManager.registerCallback(mExecutor, mMediaRouterCallback);
- mRouterManager.startScan();
+ mRouterManager.registerScanRequest();
refreshDevices();
}
@Override
public void stopScan() {
mRouterManager.unregisterCallback(mMediaRouterCallback);
- mRouterManager.stopScan();
+ mRouterManager.unregisterScanRequest();
}
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index 281501e6043c..f4355c39819f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -84,7 +84,8 @@ public class LocalMediaManager implements BluetoothCallback {
private InfoMediaManager mInfoMediaManager;
private String mPackageName;
private MediaDevice mOnTransferBluetoothDevice;
- private AudioManager mAudioManager;
+ @VisibleForTesting
+ AudioManager mAudioManager;
@VisibleForTesting
List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 4332bd24e1d1..45c0d7823e99 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -57,6 +57,7 @@ public class WifiStatusTracker {
private final Handler mHandler;
private final Handler mMainThreadHandler;
private final Set<Integer> mNetworks = new HashSet<>();
+ private int mPrimaryNetworkId;
// Save the previous HISTORY_SIZE states for logging.
private final String[] mHistory = new String[HISTORY_SIZE];
// Where to copy the next state into.
@@ -106,6 +107,7 @@ public class WifiStatusTracker {
if (!mNetworks.contains(network.getNetId())) {
mNetworks.add(network.getNetId());
}
+ mPrimaryNetworkId = network.getNetId();
updateWifiInfo(wifiInfo);
updateStatusLabel();
mMainThreadHandler.post(() -> postResults());
@@ -121,10 +123,13 @@ public class WifiStatusTracker {
recordLastWifiNetwork(log);
if (mNetworks.contains(network.getNetId())) {
mNetworks.remove(network.getNetId());
- updateWifiInfo(null);
- updateStatusLabel();
- mMainThreadHandler.post(() -> postResults());
}
+ if (network.getNetId() != mPrimaryNetworkId) {
+ return;
+ }
+ updateWifiInfo(null);
+ updateStatusLabel();
+ mMainThreadHandler.post(() -> postResults());
}
};
private final NetworkCallback mDefaultNetworkCallback =
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
index 8e850b25159c..24bb1bc9ac67 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
@@ -16,7 +16,6 @@
package com.android.settingslib.media;
-import static android.bluetooth.BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES;
import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
import static com.google.common.truth.Truth.assertThat;
@@ -29,10 +28,12 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioManager;
+import android.media.AudioSystem;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
import android.media.RoutingSessionInfo;
@@ -71,6 +72,7 @@ public class LocalMediaManagerTest {
private static final String TEST_CURRENT_DEVICE_ID = "currentDevice_id";
private static final String TEST_PACKAGE_NAME = "com.test.playmusic";
private static final String TEST_SESSION_ID = "session_id";
+ private static final String TEST_ADDRESS = "00:01:02:03:04:05";
@Mock
private InfoMediaManager mInfoMediaManager;
@@ -90,6 +92,8 @@ public class LocalMediaManagerTest {
private MediaRoute2Info mRouteInfo1;
@Mock
private MediaRoute2Info mRouteInfo2;
+ @Mock
+ private AudioManager mAudioManager;
private Context mContext;
private LocalMediaManager mLocalMediaManager;
@@ -118,6 +122,7 @@ public class LocalMediaManagerTest {
TEST_PACKAGE_NAME);
mLocalMediaManager = new LocalMediaManager(mContext, mLocalBluetoothManager,
mInfoMediaManager, "com.test.packagename");
+ mLocalMediaManager.mAudioManager = mAudioManager;
}
@Test
@@ -551,16 +556,12 @@ public class LocalMediaManagerTest {
}
@Test
- public void onDeviceListAdded_haveDisconnectedDevice_addDisconnectedDevice() {
+ public void onDeviceListAdded_haveMutingExpectedDevice_addMutingExpectedDevice() {
final List<MediaDevice> devices = new ArrayList<>();
final MediaDevice device1 = mock(MediaDevice.class);
- final MediaDevice device2 = mock(MediaDevice.class);
- final MediaDevice device3 = mock(MediaDevice.class);
mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
devices.add(device1);
- devices.add(device2);
- mLocalMediaManager.mMediaDevices.add(device3);
- mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
+ devices.add(mLocalMediaManager.mPhoneDevice);
final List<LocalBluetoothProfile> profiles = new ArrayList<>();
final A2dpProfile a2dpProfile = mock(A2dpProfile.class);
@@ -573,22 +574,25 @@ public class LocalMediaManagerTest {
bluetoothDevices.add(bluetoothDevice);
mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(bluetoothDevices);
+ AudioDeviceAttributes audioDeviceAttributes = new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, TEST_ADDRESS);
+
+ when(mAudioManager.getMutingExpectedDevice()).thenReturn(audioDeviceAttributes);
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(cachedManager);
when(cachedManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
when(cachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(cachedDevice.isConnected()).thenReturn(false);
when(cachedDevice.getConnectableProfiles()).thenReturn(profiles);
when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
+ when(cachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
when(mA2dpProfile.getActiveDevice()).thenReturn(bluetoothDevice);
when(mHapProfile.getActiveDevices()).thenReturn(new ArrayList<>());
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
- when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
- when(device3.getId()).thenReturn(TEST_DEVICE_ID_3);
when(device1.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE);
when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id");
- assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
+ assertThat(mLocalMediaManager.mMediaDevices).hasSize(0);
mLocalMediaManager.registerCallback(mCallback);
mLocalMediaManager.mMediaDeviceCallback.onDeviceListAdded(devices);
@@ -634,68 +638,6 @@ public class LocalMediaManagerTest {
}
@Test
- public void onDeviceListAdded_haveDisconnectedDevice_list5DisconnectedDevice() {
- final List<MediaDevice> devices = new ArrayList<>();
- final MediaDevice device1 = mock(MediaDevice.class);
- final MediaDevice device2 = mock(MediaDevice.class);
- final MediaDevice device3 = mock(MediaDevice.class);
- mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
- devices.add(device1);
- devices.add(device2);
- mLocalMediaManager.mMediaDevices.add(device3);
- mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
-
- final List<LocalBluetoothProfile> profiles = new ArrayList<>();
- final A2dpProfile a2dpProfile = mock(A2dpProfile.class);
- profiles.add(a2dpProfile);
-
- final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
- final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
- final BluetoothDevice bluetoothDevice2 = mock(BluetoothDevice.class);
- final BluetoothDevice bluetoothDevice3 = mock(BluetoothDevice.class);
- final BluetoothDevice bluetoothDevice4 = mock(BluetoothDevice.class);
- final BluetoothDevice bluetoothDevice5 = mock(BluetoothDevice.class);
- final BluetoothDevice bluetoothDevice6 = mock(BluetoothDevice.class);
- final BluetoothClass bluetoothClass = mock(BluetoothClass.class);
- final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
- final CachedBluetoothDeviceManager cachedManager = mock(CachedBluetoothDeviceManager.class);
- bluetoothDevices.add(bluetoothDevice);
- bluetoothDevices.add(bluetoothDevice2);
- bluetoothDevices.add(bluetoothDevice3);
- bluetoothDevices.add(bluetoothDevice4);
- bluetoothDevices.add(bluetoothDevice5);
- bluetoothDevices.add(bluetoothDevice6);
- mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(bluetoothDevices);
-
- when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(cachedManager);
- when(cachedManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
- when(cachedManager.findDevice(bluetoothDevice2)).thenReturn(cachedDevice);
- when(cachedManager.findDevice(bluetoothDevice3)).thenReturn(cachedDevice);
- when(cachedManager.findDevice(bluetoothDevice4)).thenReturn(cachedDevice);
- when(cachedManager.findDevice(bluetoothDevice5)).thenReturn(cachedDevice);
- when(cachedManager.findDevice(bluetoothDevice6)).thenReturn(cachedDevice);
- when(cachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
- when(cachedDevice.isConnected()).thenReturn(false);
- when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
- when(cachedDevice.getConnectableProfiles()).thenReturn(profiles);
- when(bluetoothDevice.getBluetoothClass()).thenReturn(bluetoothClass);
- when(bluetoothClass.getDeviceClass()).thenReturn(AUDIO_VIDEO_HEADPHONES);
-
- when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
- when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
- when(device3.getId()).thenReturn(TEST_DEVICE_ID_3);
- when(device1.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE);
- when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id");
-
- assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
- mLocalMediaManager.registerCallback(mCallback);
- mLocalMediaManager.mMediaDeviceCallback.onDeviceListAdded(devices);
-
- assertThat(mLocalMediaManager.mMediaDevices).hasSize(7);
- verify(mCallback).onDeviceListUpdate(any());
- }
-
- @Test
public void onDeviceListAdded_bluetoothAdapterIsNull_noDisconnectedDeviceAdded() {
final List<MediaDevice> devices = new ArrayList<>();
final MediaDevice device1 = mock(MediaDevice.class);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java
new file mode 100644
index 000000000000..dc7e313dfcfa
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java
@@ -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.settingslib.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkScoreManager;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiStatusTrackerTest {
+ @Mock Context mContext;
+ @Mock WifiManager mWifiManager;
+ @Mock NetworkScoreManager mNetworkScoreManager;
+ @Mock ConnectivityManager mConnectivityManager;
+ @Mock Runnable mCallback;
+
+ private final ArgumentCaptor<ConnectivityManager.NetworkCallback>
+ mNetworkCallbackCaptor =
+ ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ /**
+ * Verify that we only clear the WifiInfo if the primary network was lost.
+ */
+ @Test
+ public void testWifiInfoClearedOnPrimaryNetworkLost() {
+ WifiStatusTracker wifiStatusTracker = new WifiStatusTracker(mContext, mWifiManager,
+ mNetworkScoreManager, mConnectivityManager, mCallback);
+ wifiStatusTracker.setListening(true);
+
+ verify(mConnectivityManager)
+ .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any());
+
+ // Trigger a validation callback for the primary Wifi network.
+ WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+ when(primaryWifiInfo.makeCopy(anyLong())).thenReturn(primaryWifiInfo);
+ when(primaryWifiInfo.isPrimary()).thenReturn(true);
+ int primaryRssi = -55;
+ when(primaryWifiInfo.getRssi()).thenReturn(primaryRssi);
+ NetworkCapabilities primaryCap = new NetworkCapabilities.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .setTransportInfo(primaryWifiInfo)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+ .build();
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+ mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+ // Verify primary wifi info is the one being used.
+ assertThat(wifiStatusTracker.connected).isTrue();
+ assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+
+ // Trigger a validation callback for the non-primary Wifi network.
+ WifiInfo nonPrimaryWifiInfo = Mockito.mock(WifiInfo.class);
+ when(nonPrimaryWifiInfo.makeCopy(anyLong())).thenReturn(nonPrimaryWifiInfo);
+ when(nonPrimaryWifiInfo.isPrimary()).thenReturn(false);
+ int nonPrimaryRssi = -75;
+ when(primaryWifiInfo.getRssi()).thenReturn(nonPrimaryRssi);
+ NetworkCapabilities nonPrimaryCap = new NetworkCapabilities.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .setTransportInfo(nonPrimaryWifiInfo)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+ .build();
+ Network nonPrimaryNetwork = Mockito.mock(Network.class);
+ int nonPrimaryNetworkId = 2;
+ when(nonPrimaryNetwork.getNetId()).thenReturn(nonPrimaryNetworkId);
+ mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(nonPrimaryNetwork, nonPrimaryCap);
+
+ // Verify primary wifi info is still the one being used.
+ assertThat(wifiStatusTracker.connected).isTrue();
+ assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+
+ // Lose the non-primary network.
+ mNetworkCallbackCaptor.getValue().onLost(nonPrimaryNetwork);
+
+ // Verify primary wifi info is still the one being used.
+ assertThat(wifiStatusTracker.connected).isTrue();
+ assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+
+ // Lose the primary network.
+ mNetworkCallbackCaptor.getValue().onLost(primaryNetwork);
+
+ // Verify we aren't connected anymore.
+ assertThat(wifiStatusTracker.connected).isFalse();
+ }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 8683eac73c6c..4e2bce226d6c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2364,6 +2364,12 @@ class SettingsProtoDumpUtil {
SecureSettingsProto.PowerMenuPrivacy.SHOW);
p.end(powerMenuPrivacyToken);
+ final long extraLowPowerModeToken = p.start(SecureSettingsProto.EXTRA_LOW_POWER_MODE);
+ dumpSetting(s, p,
+ Settings.Secure.EXTRA_AUTOMATIC_POWER_SAVE_MODE,
+ SecureSettingsProto.ExtraLowPowerMode.EXTRA_AUTOMATIC_POWER_SAVE_MODE);
+ p.end(extraLowPowerModeToken);
+
final long printServiceToken = p.start(SecureSettingsProto.PRINT_SERVICE);
dumpSetting(s, p,
Settings.Secure.PRINT_SERVICE_SEARCH_URI,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
index 77640f1992e1..163cab468fc0 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
@@ -1,12 +1,11 @@
package com.android.systemui.animation
import android.view.View
-import android.window.SurfaceSyncer
+import android.window.SurfaceSyncGroup
/** A util class to synchronize 2 view roots. */
// TODO(b/200284684): Remove this class.
object ViewRootSync {
- private var surfaceSyncer: SurfaceSyncer? = null
/**
* Synchronize the next draw between the view roots of [view] and [otherView], then run [then].
@@ -29,13 +28,11 @@ object ViewRootSync {
return
}
- surfaceSyncer =
- SurfaceSyncer().apply {
- val syncId = setupSync(Runnable { then() })
- addToSync(syncId, view)
- addToSync(syncId, otherView)
- markSyncReady(syncId)
- }
+ val syncGroup = SurfaceSyncGroup()
+ syncGroup.addSyncCompleteCallback(view.context.mainExecutor) { then() }
+ syncGroup.addToSync(view.rootSurfaceControl)
+ syncGroup.addToSync(otherView.rootSurfaceControl)
+ syncGroup.markSyncReady()
}
/** A Java-friendly API for [synchronizeNextDraw]. */
diff --git a/packages/SystemUI/checks/Android.bp b/packages/SystemUI/checks/Android.bp
index 61fc48f6c2f9..9671adde4904 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -37,6 +37,12 @@ java_library_host {
java_test_host {
name: "SystemUILintCheckerTest",
+ // TODO(b/239881504): Since this test was written, Android
+ // Lint was updated, and now includes classes that were
+ // compiled for java 15. The soong build doesn't support
+ // java 15 yet, so we can't compile against "lint". Disable
+ // the test until java 15 is supported.
+ enabled: false,
srcs: [
"tests/**/*.kt",
"tests/**/*.java",
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt b/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt
index 4d5014cdbba7..b8639e64e002 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt
+++ b/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt
@@ -37,7 +37,7 @@ val LocalAndroidColorScheme =
* Important: Use M3 colors from MaterialTheme.colorScheme whenever possible instead. In the future,
* most of the colors in this class will be removed in favor of their M3 counterpart.
*/
-class AndroidColorScheme internal constructor(private val context: Context) {
+class AndroidColorScheme internal constructor(context: Context) {
val colorPrimary = getColor(context, R.attr.colorPrimary)
val colorPrimaryDark = getColor(context, R.attr.colorPrimaryDark)
val colorAccent = getColor(context, R.attr.colorAccent)
diff --git a/packages/SystemUI/compose/gallery/Android.bp b/packages/SystemUI/compose/gallery/Android.bp
index bddc1e63fee8..40504dc30c33 100644
--- a/packages/SystemUI/compose/gallery/Android.bp
+++ b/packages/SystemUI/compose/gallery/Android.bp
@@ -34,6 +34,7 @@ android_library {
],
static_libs: [
+ "SystemUI-core",
"SystemUIComposeCore",
"SystemUIComposeFeatures",
diff --git a/packages/SystemUI/compose/gallery/AndroidManifest.xml b/packages/SystemUI/compose/gallery/AndroidManifest.xml
index 4fcce0bf6968..2f30651a6acf 100644
--- a/packages/SystemUI/compose/gallery/AndroidManifest.xml
+++ b/packages/SystemUI/compose/gallery/AndroidManifest.xml
@@ -16,7 +16,40 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.systemui.compose.gallery">
<!-- To emulate a display size and density. -->
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
+ <application
+ android:name="android.app.Application"
+ android:appComponentFactory="androidx.core.app.AppComponentFactory"
+ tools:replace="android:name,android:appComponentFactory">
+ <!-- Disable providers from SystemUI -->
+ <provider android:name="com.android.systemui.keyguard.KeyguardSliceProvider"
+ android:authorities="com.android.systemui.test.keyguard.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="com.google.android.systemui.keyguard.KeyguardSliceProviderGoogle"
+ android:authorities="com.android.systemui.test.keyguard.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="com.android.keyguard.clock.ClockOptionsProvider"
+ android:authorities="com.android.systemui.test.keyguard.clock.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="com.android.systemui.people.PeopleProvider"
+ android:authorities="com.android.systemui.test.people.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="androidx.core.content.FileProvider"
+ android:authorities="com.android.systemui.test.fileprovider.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove"/>
+ </application>
</manifest>
diff --git a/packages/SystemUI/compose/gallery/app/AndroidManifest.xml b/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
index e7d496c2cb35..1f3fd8c312d9 100644
--- a/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
+++ b/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
@@ -16,6 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.systemui.compose.gallery.app">
<application
android:allowBackup="true"
@@ -23,7 +24,8 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
- android:theme="@style/Theme.SystemUIGallery">
+ android:theme="@style/Theme.SystemUI.Gallery"
+ tools:replace="android:icon,android:theme,android:label">
<activity
android:name="com.android.systemui.compose.gallery.GalleryActivity"
android:exported="true"
diff --git a/packages/SystemUI/compose/gallery/res/values-night/themes.xml b/packages/SystemUI/compose/gallery/res/values-night/themes.xml
deleted file mode 100644
index 58d20b88c13b..000000000000
--- a/packages/SystemUI/compose/gallery/res/values-night/themes.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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 xmlns:tools="http://schemas.android.com/tools">
- <style name="Theme.SystemUIGallery" parent="Theme.AppCompat.DayNight.NoActionBar">
- <item name="android:statusBarColor" tools:targetApi="l">
- @android:color/transparent
- </item>
- <item name="android:navigationBarColor" tools:targetApi="l">
- @android:color/transparent
- </item>
- </style>
-</resources> \ No newline at end of file
diff --git a/packages/SystemUI/compose/gallery/res/values/themes.xml b/packages/SystemUI/compose/gallery/res/values/themes.xml
index 6e5e99832f09..45fa1f5dfb5c 100644
--- a/packages/SystemUI/compose/gallery/res/values/themes.xml
+++ b/packages/SystemUI/compose/gallery/res/values/themes.xml
@@ -15,7 +15,10 @@
limitations under the License.
-->
<resources xmlns:tools="http://schemas.android.com/tools">
- <style name="Theme.SystemUIGallery" parent="Theme.AppCompat.DayNight.NoActionBar">
+ <style name="Theme.SystemUI.Gallery">
+ <item name="android:windowActionBar">false</item>
+ <item name="android:windowNoTitle">true</item>
+
<item name="android:statusBarColor" tools:targetApi="l">
@android:color/transparent
</item>
@@ -24,4 +27,4 @@
</item>
<item name="android:windowLightStatusBar">true</item>
</style>
-</resources> \ No newline at end of file
+</resources>
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
index 06bdad8a6735..990d060207df 100644
--- a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
@@ -9,11 +9,12 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.BrightnessHigh
-import androidx.compose.material.icons.filled.BrightnessLow
+import androidx.compose.material.icons.filled.DarkMode
import androidx.compose.material.icons.filled.FormatSize
import androidx.compose.material.icons.filled.FormatTextdirectionLToR
import androidx.compose.material.icons.filled.FormatTextdirectionRToL
+import androidx.compose.material.icons.filled.InvertColors
+import androidx.compose.material.icons.filled.LightMode
import androidx.compose.material.icons.filled.Smartphone
import androidx.compose.material.icons.filled.Tablet
import androidx.compose.material3.Button
@@ -44,12 +45,13 @@ enum class FontScale(val scale: Float) {
/** A configuration panel that allows to toggle the theme, font scale and layout direction. */
@Composable
fun ConfigurationControls(
- isDarkTheme: Boolean,
+ theme: Theme,
fontScale: FontScale,
layoutDirection: LayoutDirection,
onChangeTheme: () -> Unit,
onChangeLayoutDirection: () -> Unit,
onChangeFontScale: () -> Unit,
+ modifier: Modifier = Modifier,
) {
// The display we are emulating, if any.
var emulatedDisplayName by rememberSaveable { mutableStateOf<String?>(null) }
@@ -84,18 +86,26 @@ fun ConfigurationControls(
// TODO(b/231131244): Fork FlowRow from Accompanist and use that instead to make sure that users
// don't miss any available configuration.
- LazyRow {
+ LazyRow(modifier) {
// Dark/light theme.
item {
TextButton(onChangeTheme) {
val text: String
val icon: ImageVector
- if (isDarkTheme) {
- icon = Icons.Default.BrightnessHigh
- text = "Dark"
- } else {
- icon = Icons.Default.BrightnessLow
- text = "Light"
+
+ when (theme) {
+ Theme.System -> {
+ icon = Icons.Default.InvertColors
+ text = "System"
+ }
+ Theme.Dark -> {
+ icon = Icons.Default.DarkMode
+ text = "Dark"
+ }
+ Theme.Light -> {
+ icon = Icons.Default.LightMode
+ text = "Light"
+ }
}
Icon(icon, null)
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryActivity.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryActivity.kt
index d18b454bc78f..bb2d2feba39f 100644
--- a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryActivity.kt
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryActivity.kt
@@ -16,6 +16,8 @@
package com.android.systemui.compose.gallery
+import android.app.UiModeManager
+import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@@ -23,7 +25,7 @@ import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import androidx.core.view.WindowCompat
@@ -33,22 +35,46 @@ class GalleryActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
+ val uiModeManager = getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
setContent {
- val isSystemInDarkTheme = isSystemInDarkTheme()
- var isDarkTheme by remember { mutableStateOf(isSystemInDarkTheme) }
- val onChangeTheme = { isDarkTheme = !isDarkTheme }
+ var theme by rememberSaveable { mutableStateOf(Theme.System) }
+ val onChangeTheme = {
+ // Change to the next theme for a toggle behavior.
+ theme =
+ when (theme) {
+ Theme.System -> Theme.Dark
+ Theme.Dark -> Theme.Light
+ Theme.Light -> Theme.System
+ }
+ }
+ val isSystemInDarkTheme = isSystemInDarkTheme()
+ val isDark = theme == Theme.Dark || (theme == Theme.System && isSystemInDarkTheme)
+ val useDarkIcons = !isDark
val systemUiController = rememberSystemUiController()
- val useDarkIcons = !isDarkTheme
SideEffect {
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = useDarkIcons,
)
+
+ uiModeManager.setApplicationNightMode(
+ when (theme) {
+ Theme.System -> UiModeManager.MODE_NIGHT_AUTO
+ Theme.Dark -> UiModeManager.MODE_NIGHT_YES
+ Theme.Light -> UiModeManager.MODE_NIGHT_NO
+ }
+ )
}
- GalleryApp(isDarkTheme, onChangeTheme)
+ GalleryApp(theme, onChangeTheme)
}
}
}
+
+enum class Theme {
+ System,
+ Dark,
+ Light,
+}
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt
index 0ac3a63aa997..c341867bfb59 100644
--- a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt
@@ -23,36 +23,38 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost
-import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.android.systemui.compose.theme.SystemUITheme
-enum class Screen {
- Home,
- Typography,
- MaterialColors,
- AndroidColors,
- ExampleFeature,
+/** The gallery app screens. */
+object GalleryAppScreens {
+ val Typography = ChildScreen("typography") { TypographyScreen() }
+ val MaterialColors = ChildScreen("material_colors") { MaterialColorsScreen() }
+ val AndroidColors = ChildScreen("android_colors") { AndroidColorsScreen() }
+ val ExampleFeature = ChildScreen("example_feature") { ExampleFeatureScreen() }
+
+ val Home =
+ ParentScreen(
+ "home",
+ mapOf(
+ "Typography" to Typography,
+ "Material colors" to MaterialColors,
+ "Android colors" to AndroidColors,
+ "Example feature" to ExampleFeature,
+ )
+ )
}
-/** The main content of the app, that shows the [HomeScreen] by default. */
+/** The main content of the app, that shows [GalleryAppScreens.Home] by default. */
@Composable
private fun MainContent() {
Box(Modifier.fillMaxSize()) {
val navController = rememberNavController()
NavHost(
navController = navController,
- startDestination = Screen.Home.name,
+ startDestination = GalleryAppScreens.Home.identifier,
) {
- composable(Screen.Home.name) {
- HomeScreen(
- onScreenSelected = { navController.navigate(it.name) },
- )
- }
- composable(Screen.Typography.name) { TypographyScreen() }
- composable(Screen.MaterialColors.name) { MaterialColorsScreen() }
- composable(Screen.AndroidColors.name) { AndroidColorsScreen() }
- composable(Screen.ExampleFeature.name) { ExampleFeatureScreen() }
+ screen(GalleryAppScreens.Home, navController)
}
}
}
@@ -63,7 +65,7 @@ private fun MainContent() {
*/
@Composable
fun GalleryApp(
- isDarkTheme: Boolean,
+ theme: Theme,
onChangeTheme: () -> Unit,
) {
val systemFontScale = LocalDensity.current.fontScale
@@ -98,14 +100,14 @@ fun GalleryApp(
LocalDensity provides density,
LocalLayoutDirection provides layoutDirection,
) {
- SystemUITheme(isDarkTheme) {
+ SystemUITheme {
Surface(
Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background,
) {
Column(Modifier.fillMaxSize().systemBarsPadding().padding(16.dp)) {
ConfigurationControls(
- isDarkTheme,
+ theme,
fontScale,
layoutDirection,
onChangeTheme,
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/HomeScreen.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/HomeScreen.kt
deleted file mode 100644
index b1869da98136..000000000000
--- a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/HomeScreen.kt
+++ /dev/null
@@ -1,59 +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.systemui.compose.gallery
-
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
-
-/** The home screen shown when starting the app. */
-@Composable
-fun HomeScreen(onScreenSelected: (Screen) -> Unit) {
- LazyColumn(
- verticalArrangement = Arrangement.spacedBy(8.dp),
- ) {
- Screen.values()
- .filter { it != Screen.Home }
- .forEach { screen ->
- item {
- Surface(
- Modifier.fillMaxWidth(),
- color = MaterialTheme.colorScheme.secondaryContainer,
- shape = CircleShape,
- ) {
- Column(
- Modifier.clickable { onScreenSelected(screen) }.padding(16.dp),
- horizontalAlignment = Alignment.CenterHorizontally,
- ) {
- Text(screen.name)
- }
- }
- }
- }
- }
-}
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/Screen.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/Screen.kt
new file mode 100644
index 000000000000..467dac044b79
--- /dev/null
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/Screen.kt
@@ -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 com.android.systemui.compose.gallery
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.navigation
+
+/**
+ * A screen in an app. It is either an [ParentScreen] which lists its child screens to navigate to
+ * them or a [ChildScreen] which shows some content.
+ */
+sealed class Screen(val identifier: String)
+
+class ParentScreen(
+ identifier: String,
+ val children: Map<String, Screen>,
+) : Screen(identifier)
+
+class ChildScreen(
+ identifier: String,
+ val content: @Composable (NavController) -> Unit,
+) : Screen(identifier)
+
+/** Create the navigation graph for [screen]. */
+fun NavGraphBuilder.screen(screen: Screen, navController: NavController) {
+ when (screen) {
+ is ChildScreen -> composable(screen.identifier) { screen.content(navController) }
+ is ParentScreen -> {
+ val menuRoute = "${screen.identifier}_menu"
+ navigation(startDestination = menuRoute, route = screen.identifier) {
+ // The menu to navigate to one of the children screens.
+ composable(menuRoute) { ScreenMenu(screen, navController) }
+
+ // The content of the child screens.
+ screen.children.forEach { (_, child) -> screen(child, navController) }
+ }
+ }
+ }
+}
+
+@Composable
+private fun ScreenMenu(
+ screen: ParentScreen,
+ navController: NavController,
+) {
+ LazyColumn(verticalArrangement = Arrangement.spacedBy(8.dp)) {
+ screen.children.forEach { (name, child) ->
+ item {
+ Surface(
+ Modifier.fillMaxWidth(),
+ color = MaterialTheme.colorScheme.secondaryContainer,
+ shape = CircleShape,
+ ) {
+ Column(
+ Modifier.clickable { navController.navigate(child.identifier) }
+ .padding(16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ Text(name)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
index e929169cfe3d..a97c90c5e8ac 100644
--- a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
+++ b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
@@ -54,7 +54,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/rounded_bg_full_large_radius"
- android:onClick="dismissActivity"
android:text="@string/got_it"
android:textColor="?androidprv:attr/textColorOnAccent"
android:layout_marginBottom="60dp"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 3d27dfd95760..d41709a8ef06 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tik weer"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk die onsluitikoon om oop te maak"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ontsluit met gesig. Swiep op om oop te maak."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontsluit met gesig. Druk die ontsluitikoon om oop te maak."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontsluit met gesig. Druk om oop te maak."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesig is herken. Druk om oop te maak."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> toestelle gekies"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ontkoppel)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan nie wissel nie. Tik om weer te probeer."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bind nuwe toestel saam"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑fi onbeskikbaar"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitmodus"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gestel"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera en mikrofoon is af"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# kennisgewing}other{# kennisgewings}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitsaai"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hou op om <xliff:g id="APP_NAME">%1$s</xliff:g> uit te saai?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"As jy <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitsaai of die uitvoer verander, sal jou huidige uitsending stop"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 78873e529f13..8fad08f514fb 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"እንደገና መታ ያድርጉ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ለመክፈት የመክፈቻ አዶውን ይጫኑ"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"በመልክ ተከፍቷል። ለመክፈት ወደ ላይ ያንሸራትቱ።"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"በመልክ ተከፍቷል። ለመክፈት የመክፈቻ አዶውን ይጫኑ።"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"በመልክ ተከፍቷል። ለመክፈት ይጫኑ።"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"መልክ ተለይቶ ታውቋል። ለመክፈት ይጫኑ።"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> መሣሪያዎች ተመርጠዋል"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ተቋርጧል)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"መቀየር አይቻልም። እንደገና ለመሞከር መታ ያድርጉ።"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"አዲስ መሣሪያ ያጣምሩ"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi አይገኝም"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"የቅድሚያ ሁነታ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ማንቂያ ተቀናብሯል"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ካሜራ እና ማይክሮፎን ጠፍተዋል"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ማሳወቂያ}one{# ማሳወቂያዎች}other{# ማሳወቂያዎች}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"በማሰራጨት ላይ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 98ab7a4b8836..243983019e9e 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"انقر مرة أخرى"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"اضغط على رمز فتح القفل لفتح قفل الشاشة."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"تم فتح قفل جهازك عند تقريبه من وجهك. مرِّر سريعًا للأعلى لفتح الجهاز."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"تم فتح القفل بالتعرّف على وجهك. لفتح الجهاز، اضغط على رمز فتح القفل."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط لفتح الجهاز."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"تم التعرّف على الوجه. اضغط لفتح الجهاز."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"تم اختيار <xliff:g id="COUNT">%1$d</xliff:g> جهاز."</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غير متّصل)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"لا يمكن التبديل. انقر لإعادة المحاولة."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"إقران جهاز جديد"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏شبكة Wi‑Fi غير متاحة"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"وضع الأولوية"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"تم ضبط المنبه."</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"الكاميرا والميكروفون غير مفعّلين."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{إشعار واحد}zero{# إشعار}two{إشعاران}few{# إشعارات}many{# إشعارًا}other{# إشعار}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"البث"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"هل تريد إيقاف بث تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"إذا أجريت بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g> أو غيَّرت جهاز الإخراج، سيتوقَف البث الحالي."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 564fd1b11ff1..2fda54f3c498 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"পুনৰ টিপক"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা। খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক।"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ টিপক।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। খুলিবলৈ টিপক।"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> টা ডিভাইচ বাছনি কৰা হৈছে"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(সংযোগ বিচ্ছিন্ন কৰা হৈছে)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"সলনি কৰিব নোৱাৰি। আকৌ চেষ্টা কৰিবলৈ টিপক।"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইচ পেয়াৰ কৰক"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ৱাই-ফাই উপলব্ধ নহয়"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"অগ্ৰাধিকাৰ ম’ড"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"এলাৰ্ম ছেট কৰা হ’ল"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"কেমেৰা আৰু মাইক অফ হৈ আছে"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# টা জাননী}one{# টা জাননী}other{# টা জাননী}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"সম্প্ৰচাৰণ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰা বন্ধ কৰিবনে?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"যদি আপুনি <xliff:g id="SWITCHAPP">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰে অথবা আউটপুট সলনি কৰে, তেন্তে, আপোনাৰ বৰ্তমানৰ সম্প্ৰচাৰ বন্ধ হৈ যাব"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 4ce451c86ed1..bbf3c8950e34 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Yenidən toxunun"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"\"Kilidi aç\" ikonasına basıb açın"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Üz ilə kiliddən çıxarılıb. Açmaq üçün yuxarı sürüşdürün."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Üzlə kilidi açılıb. \"Kilidi aç\" ikonasına basıb açın."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Üz ilə kiliddən çıxarılıb. Açmaq üçün basın."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Üz tanınıb. Açmaq üçün basın."</string>
@@ -832,7 +831,7 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> cihaz seçilib"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kəsildi)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Dəyişmək olmur. Yenidən cəhd etmək üçün toxunun."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Cihaz əlavə edin"</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Cihaz qoşun"</string>
<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>
@@ -944,8 +943,11 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi əlçatan deyil"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritet rejimi"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Siqnal ayarlanıb"</string>
+ <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera deaktivdir"</string>
+ <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon deaktivdir"</string>
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera və mikrofon deaktivdir"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildiriş}other{# bildiriş}}"</string>
+ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayım"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinin yayımlanması dayandırılsın?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index e87cc5effbcf..80a812dade66 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Otključano je licem. Prevucite nagore da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano je licem. Pritisnite ikonu otključavanja da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano je licem. Pritisnite da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Izabranih uređaja: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Prebacivanje nije uspelo. Probajte ponovo."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi nije dostupan"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni režim"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je podešen"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obaveštenje}one{# obaveštenje}few{# obaveštenja}other{# obaveštenja}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitovanje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 5779cb3ace7e..35925a85b508 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Націсніце яшчэ раз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Каб адкрыць, націсніце значок разблакіроўкі"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Твар распазнаны. Каб адкрыць, прагарніце ўверх."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Твар распазнаны. Для адкрыцця націсніце значок разблакіроўкі"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблакіравана распазнаваннем твару. Націсніце, каб адкрыць."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Твар распазнаны. Націсніце, каб адкрыць."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Выбрана прылад: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(адключана)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не ўдалося пераключыцца. Дакраніцеся, каб паўтарыць спробу."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спалучыць з новай прыладай"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сетка Wi‑Fi недаступная"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Прыярытэтны рэжым"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будзільнік зададзены"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера і мікрафон выключаны"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# апавяшчэнне}one{# апавяшчэнне}few{# апавяшчэнні}many{# апавяшчэнняў}other{# апавяшчэння}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Перадача даных"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Спыніць трансляцыю праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Пры пераключэнні на праграму \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" ці змяненні вываду бягучая трансляцыя спыняецца"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 1784939b8f2d..2277ba273728 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Докоснете отново"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Натиснете иконата за отключване, за да отворите"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Отключено с лице. Прекарайте пръст нагоре за отваряне."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отключено с лице. Натиснете иконата за отключване, за да отворите."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отключено с лице. Натиснете за отваряне."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето бе разпознато. Натиснете за отваряне."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> избрани устройства"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(връзката е прекратена)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не може да се превключи. Докоснете за нов опит."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Сдвояване на ново устройство"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi не е налице"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будилникът е зададен"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонът са изключени"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известие}other{# известия}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Излъчване"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се спре ли предаването на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако предавате <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените изхода, текущото ви предаване ще бъде прекратено"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index dfc8a2b714ad..0f82d07282f8 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"আবার ট্যাপ করুন"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"খোলার জন্য আনলক আইকন প্রেস করুন"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"মুখের মাধ্যমে আনলক করা হয়েছে। খুলতে উপরের দিকে সোয়াইপ করুন।"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য আনলক আইকন প্রেস করুন।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য প্রেস করুন।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ফেস শনাক্ত করা হয়েছে। খোলার জন্য প্রেস করুন।"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g>টি ডিভাইস বেছে নেওয়া হয়েছে"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ডিসকানেক্ট হয়ে গেছে)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"পাল্টানো যাচ্ছে না। আবার চেষ্টা করতে ট্যাপ করুন।"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইস পেয়ার করুন"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ওয়াই-ফাই উপলভ্য নেই"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"প্রায়োরিটি মোড"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"অ্যালার্ম সেট করা হয়েছে"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ক্যামেরা ও মাইক্রোফোন বন্ধ আছে"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#টি বিজ্ঞপ্তি}one{#টি বিজ্ঞপ্তি}other{#টি বিজ্ঞপ্তি}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ব্রডকাস্ট করা হচ্ছে"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> সম্প্রচার বন্ধ করবেন?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"আপনি <xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করলে বা আউটপুট পরিবর্তন করলে, আপনার বর্তমান সম্প্রচার বন্ধ হয়ে যাবে"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 1ae04fedbf03..cabdb0bcc990 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Ponovo dodirnite"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite da otvorite"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu za otključavanje da otvorite."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Otključano licem. Prevucite nagore da otvorite."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano licem. Pritisnite ikonu za otklj. da otvorite."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano licem. Pritisnite da otvorite."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice prepoznato. Pritisnite da otvorite."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Broj odabranih uređaja: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije moguće prebaciti. Dodirnite da pokušate ponovo."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi je nedostupan"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Način rada Prioriteti"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavještenje}one{# obavještenje}few{# obavještenja}other{# obavještenja}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, trenutno emitiranje će se zaustaviti"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0899d882edec..eaeec2e3322d 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Torna a tocar"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Prem la icona de desbloqueig per obrir"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"S\'ha desbloquejat amb la cara. Llisca cap amunt per obrir."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S\'ha desbloquejat amb la cara. Prem la icona per obrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S\'ha desbloquejat amb la cara. Prem per obrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"S\'ha reconegut la cara. Prem per obrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"S\'han seleccionat <xliff:g id="COUNT">%1$d</xliff:g> dispositius"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconnectat)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No es pot canviar. Torna-ho a provar."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincula un dispositiu nou"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritat"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Càmera i micròfon desactivats"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificació}other{# notificacions}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"S\'està emetent"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vols deixar d\'emetre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emets <xliff:g id="SWITCHAPP">%1$s</xliff:g> o canvies la sortida, l\'emissió actual s\'aturarà"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index db653160c64d..934ba3a68531 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Znovu klepněte"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Otevřete klepnutím na ikonu odemknutí"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Odemknuto obličejem. Otevřete přejetím prstem nahoru."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odemknuto obličejem. Klepněte na ikonu odemknutí."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odemknuto obličejem. Stisknutím otevřete."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obličej rozpoznán. Stisknutím otevřete."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Vybraná zařízení: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojeno)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nelze přepnout. Klepnutím opakujte akci."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovat nové zařízení"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Síť Wi‑Fi není k dispozici"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritní režim"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Je nastaven budík"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparát a mikrofon jsou vypnuté"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# oznámení}few{# oznámení}many{# oznámení}other{# oznámení}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysílání"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zastavit vysílání v aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Pokud budete vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g> nebo změníte výstup, aktuální vysílání se zastaví"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index c1e364b2745b..ff007b9336c7 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tryk igen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryk på oplåsningsikonet for at åbne"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Låst op ved hjælp af ansigt. Stryg opad for at åbne."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst op vha. ansigt. Tryk på oplåsningsikonet for at åbne."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst op ved hjælp af ansigt. Tryk for at åbne."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansigt genkendt. Tryk for at åbne."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Der er valgt <xliff:g id="COUNT">%1$d</xliff:g> enhed"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(afbrudt)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Det var ikke muligt at skifte. Tryk for at prøve igen."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Par ny enhed"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Ingen tilgængelig Wi-Fi-forbindelse"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tilstanden Prioritet"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er indstillet"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er slået fra"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikation}one{# notifikation}other{# notifikationer}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Udsender"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop udsendelsen <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du udsender <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller skifter output, stopper din aktuelle udsendelse"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 618901cae413..40e47a5f7115 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Noch einmal tippen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tippe zum Öffnen auf das Symbol „Entsperren“"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Gerät mit Gesicht entsperrt. Zum Öffnen nach oben wischen."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen auf das Symbol „Entsperren“."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesicht erkannt. Tippe zum Öffnen."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> Geräte ausgewählt"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nicht verbunden)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Wechseln nicht möglich. Tippe, um es noch einmal zu versuchen."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Neues Gerät koppeln"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN nicht verfügbar"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritätsmodus"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wecker gestellt"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera und Mikrofon ausgeschaltet"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# Benachrichtigung}other{# Benachrichtigungen}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Übertragung läuft"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> nicht mehr streamen?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Wenn du <xliff:g id="SWITCHAPP">%1$s</xliff:g> streamst oder die Ausgabe änderst, wird dein aktueller Stream beendet"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 4a15ede13596..4670fc794e75 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Πατήστε ξανά"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Πατήστε το εικονίδιο ξεκλειδώματος για άνοιγμα"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ξεκλ. με αναγν. προσώπου. Σύρετε προς τα επάνω για άνοιγμα."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ξεκλείδωμα με πρόσωπο. Πατήστε το εικονίδιο ξεκλειδώματος."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για άνοιγμα."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για άνοιγμα."</string>
@@ -832,7 +831,7 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Επιλέχτηκαν <xliff:g id="COUNT">%1$d</xliff:g> συσκευές"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(αποσυνδέθηκε)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Δεν είναι δυνατή η εναλλαγή. Πατήστε για επανάληψη."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Σύζευξη νέας συσκευής"</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Σύνδεση συσκευής"</string>
<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>
@@ -944,8 +943,11 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Το Wi‑Fi δεν είναι διαθέσιμο"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Λειτουργία προτεραιότητας"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Το ξυπνητήρι ρυθμίστηκε"</string>
+ <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Η κάμερα είναι απενεργοποιημένη"</string>
+ <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Το μικρόφωνο είναι απενεργοποιημένο"</string>
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Η κάμερα και το μικρόφωνο έχουν απενεργοποιηθεί"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ειδοποίηση}other{# ειδοποιήσεις}}"</string>
+ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Μετάδοση"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Διακοπή μετάδοσης με την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Εάν κάνετε μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g> ή αλλάξετε την έξοδο, η τρέχουσα μετάδοση θα σταματήσει"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 634a9daa2abe..213934414235 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -30,7 +30,7 @@
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
- <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
+ <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
<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>
@@ -784,7 +784,7 @@
<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_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>
@@ -831,7 +831,7 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
<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>
@@ -943,8 +943,11 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
+ <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
+ <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index f0e2208a22d0..84f337bafe5e 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -30,7 +30,7 @@
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
- <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
+ <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
<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>
@@ -784,7 +784,7 @@
<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_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>
@@ -831,7 +831,7 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
<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>
@@ -943,8 +943,11 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
+ <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
+ <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 634a9daa2abe..213934414235 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -30,7 +30,7 @@
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
- <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
+ <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
<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>
@@ -784,7 +784,7 @@
<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_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>
@@ -831,7 +831,7 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
<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>
@@ -943,8 +943,11 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
+ <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
+ <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 634a9daa2abe..213934414235 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -30,7 +30,7 @@
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
- <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
+ <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
<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>
@@ -784,7 +784,7 @@
<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_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>
@@ -831,7 +831,7 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
<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>
@@ -943,8 +943,11 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
+ <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
+ <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 1418095fbfe6..c8d044289032 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -831,7 +831,7 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ devices selected‎‏‎‎‏‎"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎(disconnected)‎‏‎‎‏‎"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎Can\'t switch. Tap to try again.‎‏‎‎‏‎"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎Pair new device‎‏‎‎‏‎"</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‏‎‎Connect a device‎‏‎‎‏‎"</string>
<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>
@@ -943,8 +943,11 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎Wi‑Fi unavailable‎‏‎‎‏‎"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎Priority mode‎‏‎‎‏‎"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎Alarm set‎‏‎‎‏‎"</string>
+ <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎Camera is off‎‏‎‎‏‎"</string>
+ <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎Mic is off‎‏‎‎‏‎"</string>
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎Camera and mic are off‎‏‎‎‏‎"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notification‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notifications‎‏‎‎‏‎}}"</string>
+ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="TEMPERATURE">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‎Broadcasting‎‏‎‎‏‎"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎Stop broadcasting ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎If you broadcast ‎‏‎‎‏‏‎<xliff:g id="SWITCHAPP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ or change the output, your current broadcast will stop‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 26d980169833..869e3b9f4923 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Presiona otra vez"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Presiona el ícono de desbloquear para abrir"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueo con rostro. Desliza hacia arriba para abrir."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueo con rostro. Presiona el ícono para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueo con rostro. Presiona para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rostro reconocido. Presiona para abrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Se seleccionaron <xliff:g id="COUNT">%1$d</xliff:g> dispositivos"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se pudo conectar. Presiona para volver a intentarlo."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo nuevo"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"La red Wi-Fi no está disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioridad"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Se estableció la alarma"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están apagados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificaciones}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitiendo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Quieres dejar de transmitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si transmites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu transmisión actual se detendrá"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 1876d77f2238..1899940f7623 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Toca de nuevo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pulsa el icono desbloquear para abrir"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado con la cara. Desliza hacia arriba para abrir."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado con la cara. Toca el icono de desbloquear para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado con la cara. Pulsa para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Cara reconocida. Pulsa para abrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos seleccionados"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se puede cambiar. Toca para volver a intentarlo."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Emparejar nuevo dispositivo"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioritario"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma añadida"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están desactivados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificaciones}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiendo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Dejar de emitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu emisión actual se detendrá"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index c64fef9cba6b..ffeb8b9ba434 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Puudutage uuesti"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Avamiseks vajutage avamise ikooni"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Avati näoga. Pühkige avamiseks üles."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avati näoga. Avamiseks vajutage avamise ikooni."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avati näoga. Avamiseks vajutage."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nägu tuvastati. Avamiseks vajutage."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> seadet on valitud"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ühendus on katkestatud)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ei saa lülitada. Puudutage uuesti proovimiseks."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uue seadme sidumine"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi pole saadaval"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režiim Prioriteetne"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm on määratud"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kaamera ja mikrofon on välja lülitatud"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# märguanne}other{# märguannet}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Edastamine"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Kas peatada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> ülekandmine?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kui kannate rakendust <xliff:g id="SWITCHAPP">%1$s</xliff:g> üle või muudate väljundit, peatatakse teie praegune ülekanne"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 0c1302ebb982..dac1f25712d0 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Sakatu berriro"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Irekitzeko, sakatu desblokeatzeko ikonoa"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Aurpegiaren bidez desblokeatu da. Irekitzeko, pasatu hatza gora."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Aurpegiaren bidez desblokeatu da. Irekitzeko, sakatu desblokeatzeko ikonoa."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Aurpegiaren bidez desblokeatu da. Sakatu irekitzeko."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ezagutu da aurpegia. Sakatu irekitzeko."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> gailu hautatu dira"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deskonektatuta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ezin da aldatu. Berriro saiatzeko, sakatu hau."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parekatu beste gailu batekin"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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">"Gelditu igorpena"</string>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi-konexioa ez dago erabilgarri"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Lehentasun modua"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma ezarrita dago"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera eta mikrofonoa desaktibatuta daude"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# jakinarazpen}other{# jakinarazpen}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Igortzen"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren audioa igortzeari utzi nahi diozu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa igortzen baduzu, edo audio-irteera aldatzen baduzu, une hartako igorpena eten egingo da"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index bd0b037bf291..8a102b7ea027 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند به‌بالا بکشید"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"برای باز کردن، نماد قفل‌گشایی را فشار دهید"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"قفلْ با چهره باز شد. برای باز کردن، تند به‌بالا بکشید."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"قفلْ با چهره باز شد. برای باز کردن، نماد قفل‌گشایی را فشار دهید."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"قفلْ با چهره باز شد. برای باز کردن، فشار دهید."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چهره شناسایی شد. برای باز کردن، فشار دهید."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> دستگاه انتخاب شد"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(اتصال قطع شد)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"عوض نمی‌شود. برای تلاش مجدد ضربه بزنید."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi‑Fi دردسترس نیست"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"حالت اولویت"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"زنگ ساعت تنظیم شد"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"دوربین و میکروفون خاموش هستند"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اعلان}one{# اعلان}other{# اعلان}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"همه‌فرستی"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"همه‌فرستی <xliff:g id="APP_NAME">%1$s</xliff:g> متوقف شود؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر <xliff:g id="SWITCHAPP">%1$s</xliff:g> را همه‌فرستی کنید یا خروجی را تغییر دهید، همه‌فرستی کنونی متوقف خواهد شد"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 329cc44b4e23..d860318eda2b 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Napauta uudelleen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Jatka painamalla lukituksen avauskuvaketta."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Avattu kasvojen avulla. Avaa pyyhkäisemällä ylös."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avattu kasvojen avulla. Jatka lukituksen avauskuvakkeella."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avattu kasvojen avulla. Avaa painamalla."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Kasvot tunnistettu. Avaa painamalla."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> laitetta valittu"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(yhteys katkaistu)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Vaihtaminen ei onnistunut. Yritä uudelleen."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Muodosta uusi laitepari"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ei ole saatavilla"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tärkeät-tila"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Hälytys asetettu"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ja mikrofoni ovat pois päältä"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ilmoitus}other{# ilmoitusta}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Lähettää"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jos lähetät <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta tai muutat ulostuloa, nykyinen lähetyksesi loppuu"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 1fc6b8c9ecd9..e9b6f4a5b382 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Toucher de nouveau"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône Déverrouiller pour ouvrir"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Déverrouillé par le visage. Balayez vers le haut pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverr. par reconn. faciale. App. sur l\'icône pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverr. par reconnaissance faciale. Appuyez pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> appareil sélectionné"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Changement impossible. Touchez pour réessayer."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un autre appareil"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi non disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode priorité"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"L\'alarme a été réglée"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"L\'appareil photo et le micro sont désactivés"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# notifications}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion en cours…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 79acfdbdb882..ea38bcf66c90 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Appuyer à nouveau"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône de déverrouillage pour ouvrir"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Déverrouillé par visage. Balayez vers le haut pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverrouillé par visage. Appuyez sur icône déverrouillage pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverrouillé par visage. Appuyez pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> appareils sélectionnés"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Impossible de changer. Appuyez pour réessayer."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritaire"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme réglée"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Appareil photo et micro désactivés"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# notifications}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou que vous modifiez le résultat, votre annonce actuelle s\'arrêtera"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index e73aa032171a..d928a0f03dec 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Toca de novo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Preme a icona de desbloquear para abrir a porta"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado coa cara. Pasa o dedo cara arriba para acceder."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Usouse o desbloqueo facial. Preme a icona de desbloquear."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Usouse o desbloqueo facial. Preme para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Recoñeceuse a cara. Preme para abrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Seleccionáronse <xliff:g id="COUNT">%1$d</xliff:g> dispositivos"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non se puido realizar o cambio. Toca para tentalo de novo."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo novo"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A wifi non está dispoñible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A cámara e o micrófono están desactivados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificacións}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Difusión"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Queres deixar de emitir contido a través de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se emites contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou cambias de saída, a emisión en curso deterase"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index e00f5ff22297..b22f41453e72 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"ફરીથી ટૅપ કરો"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા માટે દબાવો."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ચહેરો ઓળખ્યો. ખોલવા માટે દબાવો."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ડિવાઇસ પસંદ કર્યા"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ડિસ્કનેક્ટ કરેલું)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"સ્વિચ કરી શકતા નથી. ફરી પ્રયાસ કરવા માટે ટૅપ કરો."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"નવા ડિવાઇસ સાથે જોડાણ કરો"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"વાઇ-ફાઇ ઉપલબ્ધ નથી"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"પ્રાધાન્યતા મોડ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"અલાર્મ સેટ"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"કૅમેરા અને માઇક બંધ છે"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# નોટિફિકેશન}one{# નોટિફિકેશન}other{# નોટિફિકેશન}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"બ્રૉડકાસ્ટ કરી રહ્યાં છે"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> બ્રોડકાસ્ટ કરવાનું રોકીએ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"જો તમે <xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો અથવા આઉટપુટ બદલો, તો તમારું હાલનું બ્રોડકાસ્ટ બંધ થઈ જશે"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index b74d2874fcad..5fa1540a93d4 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -243,7 +243,7 @@
<string name="quick_settings_color_correction_label" msgid="5636617913560474664">"रंग में सुधार करने की सुविधा"</string>
<string name="quick_settings_more_user_settings" msgid="1064187451100861954">"उपयोगकर्ता सेटिंग"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"हो गया"</string>
- <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"बंद करें"</string>
+ <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"रद्द करें"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"कनेक्ट है"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"कनेक्ट किया गया, बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"कनेक्ट हो रहा है..."</string>
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"फिर से टैप करें"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"चेहरे से अनलॉक किया गया. खोलने के लिए ऊपर की ओर स्वाइप करें."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहरे से अनलॉक किया. डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहरे से अनलॉक किया गया. डिवाइस खोलने के लिए टैप करें."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरे की पहचान हो गई. डिवाइस खोलने के लिए टैप करें."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> डिवाइस चुने गए"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिसकनेक्ट हो गया)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच नहीं किया जा सकता. फिर से कोशिश करने के लिए टैप करें."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नया डिवाइस जोड़ें"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाई-फ़ाई उपलब्ध नहीं है"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट किया गया"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कैमरा और माइक बंद हैं"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}one{# सूचना}other{# सूचनाएं}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट ऐप्लिकेशन"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर ब्रॉडकास्ट करना रोकें?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट शुरू करने पर या आउटपुट बदलने पर, आपका मौजूदा ब्रॉडकास्ट बंद हो जाएगा"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 823d2f495d2a..bbf02ca884bc 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Otključano licem. Prijeđite prstom prema gore za otvaranje."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano pomoću lica. Pritisnite ikonu otključavanja da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano pomoću lica. Pritisnite da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Odabrano uređaja: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nije povezano)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije prebačeno. Dodirnite da biste pokušali ponovo."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nije dostupan"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni način rada"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat i mikrofon su isključeni"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, vaše će se trenutačno emitiranje zaustaviti"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 12e2d70de609..e4cf9222279d 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Koppintson újra"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Az eszköz használatához nyomja meg a feloldás ikonját"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Zárolás arccal feloldva. Csúsztasson felfelé a megnyitáshoz."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Arccal feloldva. A megnyitáshoz nyomja meg a feloldás ikont."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Zárolás arccal feloldva. Koppintson az eszköz használatához."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Arc felismerve. Koppintson az eszköz használatához."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> eszköz kiválasztva"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(leválasztva)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"A váltás nem sikerült. Próbálja újra."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Új eszköz párosítása"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A Wi‑Fi nem áll rendelkezésre"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritás mód"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ébresztő beállítva"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A kamera és a mikrofon ki vannak kapcsolva"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# értesítés}other{# értesítés}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sugárzás"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Leállítja a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> közvetítését?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"A(z) <xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése vagy a kimenet módosítása esetén a jelenlegi közvetítés leáll"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index c702969c9058..5d1563d2e60a 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Նորից հպեք"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Բացեք՝ սեղմելով ապակողպման պատկերակը"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ապակողպվել է դեմքով։ Բացելու համար սահեցրեք մատը վերև։"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ապակողպվել է դեմքով։ Բացեք՝ սեղմելով ապակողպման պատկերակը։"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ապակողպվել է դեմքով։ Սեղմեք բացելու համար։"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Դեմքը ճանաչվեց։ Սեղմեք բացելու համար։"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Ընտրված է <xliff:g id="COUNT">%1$d</xliff:g> սարք"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(անջատված է)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Սխալ առաջացավ։ Հպեք՝ կրկնելու համար։"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi-ը հասանելի չէ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Առաջնահերթության ռեժիմ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Զարթուցիչը դրված է"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Տեսախցիկը և խոսափողն անջատված են"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ծանուցում}one{# ծանուցում}other{# ծանուցում}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Հեռարձակում"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Կանգնեցնել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի հեռարձակումը"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Եթե հեռարձակեք <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը կամ փոխեք աուդիո ելքը, ձեր ընթացիկ հեռարձակումը կկանգնեցվի։"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index e52d08d7f721..99bf503317a4 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Ketuk lagi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk membuka"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Kunci dibuka dengan wajah. Geser ke atas untuk membuka."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kunci dibuka dengan wajah. Tekan ikon buka kunci untuk membuka."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Kunci dibuka dengan wajah. Tekan untuk membuka."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dikenali. Tekan untuk membuka."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> perangkat dipilih"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(terputus)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat beralih. Ketuk untuk mencoba lagi."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sambungkan perangkat baru"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi tidak tersedia"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode prioritas"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm disetel"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon nonaktif"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikasi}other{# notifikasi}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika Anda menyiarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau mengubah output, siaran saat ini akan dihentikan"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index e8d2d866aec3..38982e13c2bb 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Ýttu aftur"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Ýttu á táknið til að taka úr lás til að opna"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Opnað með andliti. Strjúktu upp til að opna."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Opnað með andliti. Ýttu á táknið taka úr lás til að opna."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Opnað með andliti. Ýttu til að opna."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Andlitið var greint. Ýttu til að opna."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> tæki valin"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(aftengt)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ekki er hægt að skipta. Ýttu til að reyna aftur."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Para nýtt tæki"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi ekki tiltækt"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Forgangsstilling"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Vekjari stilltur"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Slökkt á myndavél og hljóðnema"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# tilkynning}one{# tilkynning}other{# tilkynningar}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Útsending í gangi"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hætta að senda út <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 5d318bfb1adf..5caaa607245a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tocca di nuovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Premi l\'icona Sblocca per aprire"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Sbloccato con il volto. Scorri verso l\'alto per aprire."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Sbloccato con il volto. Premi l\'icona Sblocca per aprire."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Sbloccato con il volto. Premi per aprire."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Volto riconosciuto. Premi per aprire."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivi selezionati"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnesso)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non puoi cambiare. Tocca per riprovare."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Accoppia nuovo dispositivo"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,18 +944,21 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponibile"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modalità Priorità"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Sveglia impostata"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotocamera e microfono non attivi"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifica}other{# notifiche}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Trasmissione in corso…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vuoi interrompere la trasmissione dell\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambi l\'uscita, la trasmissione attuale viene interrotta"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia uscita"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
- <!-- no translation found for dream_date_complication_date_format (8191225366513860104) -->
- <skip />
- <!-- no translation found for dream_time_complication_12_hr_time_format (4691197486690291529) -->
- <skip />
- <!-- no translation found for dream_time_complication_24_hr_time_format (6248280719733640813) -->
- <skip />
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM g"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 25e08c634b6b..98834a9bb46e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"צריך להקיש פעם נוספת"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"לפתיחה, לוחצים על סמל ביטול הנעילה"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"הנעילה בוטלה באמצעות זיהוי הפנים. צריך להחליק כדי לפתוח."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"הנעילה בוטלה בזיהוי פנים. פותחים בלחיצה על סמל ביטול הנעילה."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי לפתוח."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"הפנים זוהו. יש ללחוץ כדי לפתוח."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"נבחרו <xliff:g id="COUNT">%1$d</xliff:g> מכשירים"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(מנותק)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"לא ניתן להחליף. צריך להקיש כדי לנסות שוב."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"התאמה של מכשיר חדש"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi‑Fi לא זמין"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"מצב עדיפות"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ההתראה מוגדרת"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"המצלמה והמיקרופון כבויים"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{התראה אחת}two{# התראות}many{# התראות}other{# התראות}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"שידור"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"האם להפסיק לשדר את התוכן מאפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"אם משדרים את התוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g> או משנים את הפלט, השידור הנוכחי יפסיק לפעול"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 69a959268d7f..564e9112dc37 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"もう一度タップしてください"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ロック解除アイコンを押して開きます"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"顔でロック解除しました。開くには上にスワイプします。"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"顔でロック解除しました。アイコンを押すと開きます。"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"顔でロック解除しました。押すと開きます。"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"顔を認識しました。押すと開きます。"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"選択したデバイス: <xliff:g id="COUNT">%1$d</xliff:g> 台"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(接続解除済み)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"切り替えられません。タップしてやり直してください。"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi を利用できません"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先順位モード"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"アラームを設定しました"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"カメラとマイクが OFF です"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 件の通知}other{# 件の通知}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ブロードキャスト"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> のブロードキャストを停止しますか?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャストしたり、出力を変更したりすると、現在のブロードキャストが停止します。"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index fc1ecdac36ee..8d0257c25f4a 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"შეეხეთ ხელახლა"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"გასახსნელად დააჭირეთ განბლოკვის ხატულას"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"განიბლოკა სახით. გასახსნელად აწიეთ ზემოთ"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"განიბლოკა სახით. გასახსნელად დააჭირეთ განბლოკვის ხატულას."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"განიბლოკა სახით. დააჭირეთ გასახსნელად."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ამოცნობილია სახით. დააჭირეთ გასახსნელად."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"არჩეულია <xliff:g id="COUNT">%1$d</xliff:g> მოწყობილობა"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(კავშირი გაწყვეტილია)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ვერ გადაირთო. შეეხეთ ხელახლა საცდელად."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ახალი მოწყობილობის დაწყვილება"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi მიუწვდომელია"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"პრიორიტეტული რეჟიმი"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"მაღვიძარა დაყენებულია"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"კამერა და მიკროფონი გამორთულია"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# შეტყობინება}other{# შეტყობინება}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"იწყებთ მაუწყებლობას"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"გსურთ <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ტრანსლაციის შეჩერება?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაციის შემთხვევაში ან აუდიოს გამოსასვლელის შეცვლისას, მიმდინარე ტრანსლაცია შეჩერდება"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index d47c26df09a8..68a180a1e461 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Қайта түртіңіз."</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Бетпен ашылды. Ашу үшін жоғары қарай сырғытыңыз."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Бет үлгісі арқылы ашылды. Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Бетпен ашылды. Ашу үшін басыңыз."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Бет танылды. Ашу үшін басыңыз."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> құрылғы таңдалды."</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратулы)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ауысу мүмкін емес. Әрекетті қайталау үшін түртіңіз."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғымен жұптау"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi қолжетімсіз"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Басымдық режимі"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Оятқыш орнатылды"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера мен микрофон өшірулі"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# хабарландыру}other{# хабарландыру}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Таратуда"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын таратуды тоқтатасыз ба?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 48fedd222a1f..16396ec6d211 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"ចុច​ម្ដងទៀត"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ចុចរូបដោះសោ ដើម្បីបើក"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"បានដោះសោដោយប្រើមុខ។ អូសឡើងលើ​ដើម្បីបើក។"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបើក។"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបើក។"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបើក។"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"បានជ្រើសរើស​ឧបករណ៍ <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(បាន​ដាច់)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"មិនអាចប្ដូរបានទេ។ សូមចុចដើម្បី​ព្យាយាម​ម្ដងទៀត។"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ផ្គូផ្គង​ឧបករណ៍ថ្មី"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ត្រូវបានបិទ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"មុខងារ​អាទិភាព"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"រូបកំណត់​ម៉ោងរោទ៍"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"កាមេរ៉ា និង​មីក្រូហ្វូន​ត្រូវបានបិទ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{ការ​ជូន​ដំណឹង #}other{ការ​ជូនដំណឹង #}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ការផ្សាយ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"បញ្ឈប់ការផ្សាយ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ប្រសិនបើអ្នក​ផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ឬប្ដូរឧបករណ៍បញ្ចេញសំឡេង ការផ្សាយបច្ចុប្បន្នរបស់អ្នកនឹង​បញ្ឈប់"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 55afb910c775..8effb54dbd3c 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"ಪುನಃ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ಸಾಧನಗಳನ್ನು ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ಡಿಸ್‌ಕನೆಕ್ಟ್ ಆಗಿದೆ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ಬದಲಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ಆದ್ಯತೆ ಮೋಡ್"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ಅಲಾರಾಂ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ಅಧಿಸೂಚನೆ}one{# ಅಧಿಸೂಚನೆಗಳು}other{# ಅಧಿಸೂಚನೆಗಳು}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ಪ್ರಸಾರ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಪ್ರಸಾರವನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ನೀವು <xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿದರೆ ಅಥವಾ ಔಟ್‌ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿದರೆ, ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಪ್ರಸಾರವು ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 32d345f04532..27fdc37c00df 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"다시 탭하세요."</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"얼굴 인식으로 잠금 해제되었습니다. 위로 스와이프하여 여세요."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"얼굴 인식으로 잠금 해제되었습니다. 기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"얼굴 인식으로 잠금 해제되었습니다. 열려면 누르세요."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"얼굴이 인식되었습니다. 열려면 누르세요."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"기기 <xliff:g id="COUNT">%1$d</xliff:g>대 선택됨"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(연결 끊김)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"전환할 수 없습니다. 다시 시도하려면 탭하세요."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi를 이용할 수 없습니다."</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"우선순위 모드입니다."</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"알람이 설정되었습니다."</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"카메라 및 마이크가 사용 중지되었습니다."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{알림 #개}other{알림 #개}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"방송 중"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> 방송을 중지하시겠습니까?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 앱을 방송하거나 출력을 변경하면 기존 방송이 중단됩니다"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index a9670589f0cc..75d8582fd613 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Кайра таптап коюңуз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Кулпуну ачуу сүрөтчөсүн басыңыз"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Түзмөгүңүздү жүзүңүз менен ачтыңыз. Эми өйдө сүрүп коюңуз."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Кулпуну жүзүңүз менен ачтыңыз. Эми кулпуну ачуу сүрөтчөсүн басыңыз."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Кулпуну жүзүңүз менен ачтыңыз. Ачуу үчүн басыңыз."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Жүз таанылды. Ачуу үчүн басыңыз."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> түзмөк тандалды"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратылды)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Которулбай жатат. Кайталоо үчүн басыңыз."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңы түзмөк кошуу"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi жеткиликсиз"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Маанилүү сүйлөшүүлөр режими"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ойготкуч коюлду"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера жана микрофон өчүк"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# билдирме}other{# билдирме}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Кеңири таратуу"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда кабарлоо токтотулсунбу?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index d86198e4d512..35b85dd33ed4 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"ແຕະອີກເທື່ອໜຶ່ງ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ກົດໄອຄອນປົດລັອກເພື່ອເປີດ"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ປົດລັອກດ້ວຍໃບໜ້າແລ້ວ. ປັດຂຶ້ນເພື່ອເປີດ."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອເປີດ."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອເປີດ."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອເປີດ."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"ເລືອກ <xliff:g id="COUNT">%1$d</xliff:g> ອຸປະກອນແລ້ວ"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ຕັດການເຊື່ອມຕໍ່ແລ້ວ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ບໍ່ສາມາດສະຫຼັບໄດ້. ແຕະເພື່ອລອງໃໝ່."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ຈັບຄູ່ອຸປະກອນໃໝ່"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ບໍ່ສາມາດໃຊ້ Wi‑Fi ໄດ້"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ໂໝດຄວາມສຳຄັນ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ຕັ້ງໂມງປຸກແລ້ວ"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ປິດກ້ອງຖ່າຍຮູບ ແລະ ໄມແລ້ວ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ການແຈ້ງເຕືອນ}other{# ການແຈ້ງເຕືອນ}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ກຳລັງອອກອາກາດ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ຢຸດການອອກອາກາດ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ຫາກທ່ານອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ຫຼື ປ່ຽນເອົ້າພຸດ, ການອອກອາກາດປັດຈຸບັນຂອງທ່ານຈະຢຸດ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 56bfb2c3713c..db3887e37cef 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Palieskite dar kartą"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Paspauskite atrakinimo piktogramą, kad atidarytumėte"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Atrakinta pagal veidą. Atidarykite perbraukę aukštyn."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atrakinta pagal veidą. Pasp. atr. pikt., kad atidarytumėte."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Atrakinta pagal veidą. Paspauskite, kad atidarytumėte."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Veidas atpažintas. Paspauskite, kad atidarytumėte."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Pasirinkta įrenginių: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(atjungta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nepavyko perjungti. Bandykite vėl palietę."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Naujo įrenginio susiejimas"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"„Wi‑Fi“ ryšys nepasiekiamas"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteto režimas"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signalas nustatytas"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Vaizdo kamera ir mikrofonas išjungti"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pranešimas}one{# pranešimas}few{# pranešimai}many{# pranešimo}other{# pranešimų}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transliavimas"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Sustabdyti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ transliaciją?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jei transliuosite „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“ arba pakeisite išvestį, dabartinė transliacija bus sustabdyta"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 65e7c5d74b39..6c1ae36bee5e 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Pieskarieties vēlreiz"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Lai atvērtu, nospiediet atbloķēšanas ikonu"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ierīce atbloķēta ar seju. Velciet augšup, lai atvērtu."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atbloķēta ar seju. Atvērt: nospiediet atbloķēšanas ikonu."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ierīce atbloķēta ar seju. Nospiediet, lai atvērtu."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Seja atpazīta. Nospiediet, lai atvērtu."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Atlasītas vairākas ierīces (kopā <xliff:g id="COUNT">%1$d</xliff:g>)"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(savienojums pārtraukts)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nevar pārslēgt. Pieskarieties, lai mēģinātu vēlreiz."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Savienošana pārī ar jaunu ierīci"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nav pieejams"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritātes režīms"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signāls ir iestatīts"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera un mikrofons ir izslēgti"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# paziņojums}zero{# paziņojumu}one{# paziņojums}other{# paziņojumi}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Notiek apraidīšana"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vai apturēt lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> apraidīšanu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ja sāksiet lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraidīšanu vai mainīsiet izvadi, pašreizējā apraide tiks apturēta"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 85f9cd5329d0..a6121671d197 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Допрете повторно"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Притиснете ја иконата за отклучување за да отворите"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Отклучено со лице. Повлечете за да отворите."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отклучено со лик. Притиснете ја иконата за отклучување за да отворите."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отклучено со лик. Притиснете за да отворите."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето е препознаено. Притиснете за да отворите."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Избрани се <xliff:g id="COUNT">%1$d</xliff:g> уреди"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(врската е прекината)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не се префрла. Допрете и обидете се пак."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спарете нов уред"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi е недостапна"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Алармот е наместен"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонот се исклучени"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известување}one{# известување}other{# известувања}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитување"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се прекине емитувањето на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитувате на <xliff:g id="SWITCHAPP">%1$s</xliff:g> или го промените излезот, тековното емитување ќе запре"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 49a807545283..5b48a379321f 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"വീണ്ടും ടാപ്പ് ചെയ്യുക"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"മുഖം വഴി അൺലോക്കുചെയ്തു. മുകളിലേക്ക് സ്വൈപ്പുചെയ്ത് തുറക്കൂ."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുറക്കാൻ അമർത്തുക."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"മുഖം തിരിച്ചറിഞ്ഞു. തുറക്കാൻ അമർത്തുക."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ഉപകരണങ്ങൾ തിരഞ്ഞെടുത്തു"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(വിച്ഛേദിച്ചു)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"മാറാനാകുന്നില്ല. വീണ്ടും ശ്രമിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"പുതിയ ഉപകരണവുമായി ജോടിയാക്കുക"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"വൈഫൈ ലഭ്യമല്ല"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"മുൻഗണനാ മോഡ്"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"അലാറം സജ്ജീകരിച്ചു"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ക്യാമറയും മൈക്കും ഓഫാണ്"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# അറിയിപ്പ്}other{# അറിയിപ്പുകൾ}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"പ്രക്ഷേപണം ചെയ്യുന്നു"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുന്നത് അവസാനിപ്പിക്കണോ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"നിങ്ങൾ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുകയോ ഔട്ട്പുട്ട് മാറ്റുകയോ ചെയ്താൽ നിങ്ങളുടെ നിലവിലുള്ള ബ്രോഡ്‌കാസ്റ്റ് അവസാനിക്കും"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index c9bd0bf20243..68fe4c538ea4 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Дaхин товшино уу"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Царайгаар түгжээг тайлсан. Нээхийн тулд дээш шударна уу."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Царайгаар түгжээг тайлсан. Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Царайгаар түгжээг тайлсан. Нээхийн тулд дарна уу."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Царайг таньсан. Нээхийн тулд дарна уу."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> төхөөрөмж сонгосон"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(салсан)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Сэлгэх боломжгүй. Дахин оролдохын тулд товшино уу."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Шинэ төхөөрөмж хослуулах"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi боломжгүй"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Чухал горим"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Сэрүүлгийг тохируулсан"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камер болон микрофон унтраалттай байна"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# мэдэгдэл}other{# мэдэгдэл}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Нэвтрүүлэлт"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нэвтрүүлэхээ зогсоох уу?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 5922126dcebe..be8933fb09e1 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"पुन्हा टॅप करा"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन दाबा"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी वर स्वाइप करा."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहऱ्याने अनलॉक केले. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी दाबा."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरा ओळखला आहे. उघडण्यासाठी दाबा."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> डिव्हाइस निवडली आहेत"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट केलेले)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच करू शकत नाही. पुन्हा प्रयत्न करण्यासाठी टॅप करा."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नवीन डिव्हाइससोबत पेअर करा"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाय-फाय उपलब्ध नाही"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राधान्य मोड"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट केला"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कॅमेरा आणि माइक बंद आहेत"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}other{# सूचना}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट करत आहे"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> चे प्रसारण थांबवायचे आहे का?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तुम्ही <xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण केल्यास किंवा आउटपुट बदलल्यास, तुमचे सध्याचे प्रसारण बंद होईल"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index ac6f3deb8e53..3989e5d6b51b 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Ketik sekali lagi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk buka"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Dibuka kunci dengan wajah. Leret ke atas untuk buka."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Dibuka kunci dengan wajah. Tekan ikon buka kunci untuk buka."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Dibuka kunci dengan wajah. Tekan untuk membuka."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dicam. Tekan untuk membuka."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> peranti dipilih"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(diputuskan sambungan)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat menukar. Ketik untuk mencuba lagi."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Gandingkan peranti baharu"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi dimatikan"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mod keutamaan"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Penggera ditetapkan"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon dimatikan"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pemberitahuan}other{# pemberitahuan}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika anda siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau tukarkan output, siaran semasa anda akan berhenti"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 09de7451064f..5bbe4293221a 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"ထပ်တို့ပါ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ။"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"မျက်နှာပြ လော့ခ်ဖွင့်ထားသည်။ လော့ခ်ဖွင့်သင်္ကေတ နှိပ်၍ဝင်ပါ။"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"မျက်နှာ မှတ်မိသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"စက်ပစ္စည်း <xliff:g id="COUNT">%1$d</xliff:g> ခုကို ရွေးချယ်ထားသည်"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ချိတ်ဆက်မှု မရှိပါ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ပြောင်း၍ မရပါ။ ပြန်စမ်းကြည့်ရန် တို့ပါ။"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"စက်အသစ် တွဲချိတ်ရန်"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi မရပါ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ဦးစားပေးမုဒ်"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"နိုးစက် သတ်မှတ်ထားသည်"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ကင်မရာနှင့် မိုက် ပိတ်ထားသည်"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{အကြောင်းကြားချက် # ခု}other{အကြောင်းကြားချက် # ခု}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ထုတ်လွှင့်ခြင်း"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ထုတ်လွှင့်ခြင်းကို ရပ်မလား။"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ကို ထုတ်လွှင့်သောအခါ (သို့) အထွက်ကို ပြောင်းသောအခါ သင့်လက်ရှိထုတ်လွှင့်ခြင်း ရပ်သွားမည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 8b435c2fd43d..c18d69051669 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Trykk igjen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Trykk på lås opp-ikonet for å åpne"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Låst opp med ansiktet. Sveip opp for å åpne."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst opp med ansiktet. Trykk for å åpne."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet er gjenkjent. Trykk for å åpne."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> enheter er valgt"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frakoblet)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan ikke bytte. Trykk for å prøve igjen."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Koble til en ny enhet"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi er utilgjengelig"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteringsmodus"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er stilt inn"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er av"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# varsel}other{# varsler}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Kringkaster"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vil du stoppe kringkastingen av <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du kringkaster <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller endrer utgangen, stopper den nåværende kringkastingen din"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 05bb2868125c..e9c843f142f5 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"फेरि ट्याप गर्नुहोस्"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"खोल्न अनलक आइकनमा थिच्नुहोस्"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"अनुहार प्रयोग गरी अनलक गरियो। खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"अनुहार प्रयोग गरी अनलक गरियो। खोल्न अनलक आइकनमा थिच्नुहोस्।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"अनुहार प्रयोग गरी अनलक गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"अनुहार पहिचान गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> वटा यन्त्र चयन गरिए"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट गरिएको छ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"बदल्न सकिएन। फेरि प्रयास गर्न ट्याप गर्नुहोस्।"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नयाँ डिभाइस कनेक्ट गर्नुहोस्"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi उपलब्ध छैन"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट गरिएको छ"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"क्यामेरा र माइक अफ छन्"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# वटा सूचना}other{# वटा सूचनाहरू}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"प्रसारण गरिँदै छ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ब्रोडकास्ट गर्न छाड्ने हो?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तपाईंले <xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुभयो वा आउटपुट परिवर्तन गर्नुभयो भने तपाईंको हालको ब्रोडकास्ट रोकिने छ"</string>
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index cf4972805e25..6f871695c491 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -44,7 +44,6 @@
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowLightNavigationBar">false</item>
<item name="android:navigationBarColor">?android:attr/colorBackgroundFloating</item>
- <item name="android:textColorSecondary">?android:attr/textColorPrimaryInverse</item>
</style>
<style name="FloatingOverlay" parent="@android:style/Theme.DeviceDefault.DayNight">
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 2c91600cc5e5..2cdafa5a84b0 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tik nog een keer"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk op het ontgrendelicoon om te openen"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ontgrendeld via gezicht. Swipe omhoog om te openen."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontgrendeld via gezicht. Druk op het ontgrendelicoon."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontgrendeld via gezicht. Druk om te openen."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gezicht herkend. Druk om te openen."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> apparaten geselecteerd"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(verbinding verbroken)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan niet schakelen. Tik om het opnieuw te proberen."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Nieuw apparaat koppelen"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi niet beschikbaar"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitsmodus"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gezet"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera en microfoon staan uit"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# melding}other{# meldingen}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitzending"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Uitzending van <xliff:g id="APP_NAME">%1$s</xliff:g> stopzetten?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Als je <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzendt of de uitvoer wijzigt, wordt je huidige uitzending gestopt"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index f30f7d13d0f7..aae14393f566 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ।"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g>ଟି ଡିଭାଇସ୍ ଚୟନ କରାଯାଇଛି"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ବିଚ୍ଛିନ୍ନ କରାଯାଇଛି)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ସ୍ୱିଚ କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ନୂଆ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ପ୍ରାଥମିକତା ମୋଡ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ଆଲାରାମ ସେଟ"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"କ୍ୟାମେରା ଏବଂ ମାଇକ ବନ୍ଦ ଅଛି"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#ଟି ବିଜ୍ଞପ୍ତି}other{#ଟି ବିଜ୍ଞପ୍ତି}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ବ୍ରଡକାଷ୍ଟ କରୁଛି"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ଯଦି ଆପଣ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତି କିମ୍ବା ଆଉଟପୁଟ ବଦଳାନ୍ତି, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ବ୍ରଡକାଷ୍ଟ ବନ୍ଦ ହୋଇଯିବ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index d41e43c3c935..4492796ecd22 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ਡੀਵਾਈਸਾਂ ਨੂੰ ਚੁਣਿਆ ਗਿਆ"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ਡਿਸਕਨੈਕਟ ਹੈ)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ਤਰਜੀਹੀ ਮੋਡ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ਅਲਾਰਮ ਸੈੱਟ ਹੈ"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ ਬੰਦ ਹਨ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ਸੂਚਨਾ}one{# ਸੂਚਨਾ}other{# ਸੂਚਨਾਵਾਂ}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ਪ੍ਰਸਾਰਨ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੇ ਪ੍ਰਸਾਰਨ ਨੂੰ ਰੋਕਣਾ ਹੈ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ਜੇ ਤੁਸੀਂ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰਦੇ ਹੋ ਜਾਂ ਆਊਟਪੁੱਟ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਪ੍ਰਸਾਰਨ ਰੁਕ ਜਾਵੇਗਾ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 36bbbc4ccbc0..280000d4b22a 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Kliknij jeszcze raz"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Aby otworzyć, kliknij ikonę odblokowywania"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Odblokowano skanem twarzy. Przesuń w górę, aby otworzyć."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odblokowano skanem twarzy. Aby otworzyć, kliknij ikonę odblokowywania."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odblokowano rozpoznawaniem twarzy. Naciśnij, by otworzyć."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Twarz rozpoznana. Naciśnij, by otworzyć."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Wybrane urządzenia: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odłączono)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nie można przełączyć. Spróbuj ponownie."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sparuj nowe urządzenie"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Sieć Wi‑Fi niedostępna"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tryb priorytetowy"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm ustawiony"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Aparat i mikrofon są wyłączone"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# powiadomienie}few{# powiadomienia}many{# powiadomień}other{# powiadomienia}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmisja"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zatrzymaj transmisję aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jeśli transmitujesz aplikację <xliff:g id="SWITCHAPP">%1$s</xliff:g> lub zmieniasz dane wyjściowe, Twoja obecna transmisja zostanie zakończona"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 0cb7420785ba..d93e141e4fd7 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado pelo rosto. Deslize para cima para abrir."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Toque no ícone do cadeado para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos selecionados"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 9702b9759793..d9e9c232cfb9 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Prima o ícone de desbloqueio para abrir"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado com o rosto. Deslize para cima para abrir."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueio com a face. Prima ícone de desbloqueio p/ abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado com o rosto. Prima para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Prima para abrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos selecionados"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desligado)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não é possível mudar. Toque para tentar novamente."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sincronize o novo dispositivo"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponível"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo Prioridade"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmara e o microfone estão desativados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}other{# notificações}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"A transmitir"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se transmitir a app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou alterar a saída, a sua transmissão atual é interrompida"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 0cb7420785ba..d93e141e4fd7 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado pelo rosto. Deslize para cima para abrir."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Toque no ícone do cadeado para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos selecionados"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 99d2f06b2970..3d7f17b4ffaf 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Atingeți din nou"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Apăsați pictograma de deblocare pentru a deschide"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"S-a deblocat folosind fața. Glisați în sus și deschideți."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S-a deblocat cu ajutorul feței. Apăsați pictograma de deblocare pentru a deschide"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S-a deblocat cu ajutorul feței. Apăsați pentru a deschide."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Chipul a fost recunoscut. Apăsați pentru a deschide."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"S-au selectat <xliff:g id="COUNT">%1$d</xliff:g> dispozitive"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deconectat)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nu se poate comuta. Atingeți pentru a încerca din nou."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Asociați un nou dispozitiv"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponibil"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modul Prioritate"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmă setată"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera și microfonul sunt dezactivate"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificare}few{# notificări}other{# de notificări}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Se difuzează"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Opriți difuzarea <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Dacă difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g> sau schimbați rezultatul, difuzarea actuală se va opri"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 817fdc0e275d..75dd8190b9ca 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Нажмите ещё раз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Нажмите на значок разблокировки."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Сканирование выполнено. Чтобы открыть, проведите вверх."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Сканирование выполнено. Нажмите на значок разблокировки."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблокировано сканированием лица. Нажмите, чтобы открыть."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицо распознано. Нажмите, чтобы открыть."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Выбрано устройств: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(нет подключения)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не удается переключиться. Нажмите, чтобы повторить попытку."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сеть Wi‑Fi недоступна"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим приоритета"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлен"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон отключены"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# уведомление}one{# уведомление}few{# уведомления}many{# уведомлений}other{# уведомления}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляция"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Остановить трансляцию \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Если вы начнете транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" или смените целевое устройство, текущая трансляция прервется."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 8c7b85cbe287..763fc59e1f2c 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"නැවත තට්ටු කරන්න"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට ස්වයිප් කරන්න."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට ඔබන්න."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"මුහුණ හඳුනා ගන්නා ලදි. විවෘත කිරීමට ඔබන්න."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"උපාංග <xliff:g id="COUNT">%1$d</xliff:g>ක් තෝරන ලදී"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(විසන්ධි විය)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"මාරු කිරීමට නොහැකිය. නැවත උත්සාහ කිරීමට තට්ටු කරන්න."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"නව උපාංගය යුගල කරන්න"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ලබා ගත නොහැකිය"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ප්‍රමුඛතා ප්‍රකාරය"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"සීනුව සකසන ලදි"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"කැමරාව සහ මයික් ක්‍රියාවිරහිතයි"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{දැනුම්දීම් #ක්}one{දැනුම්දීම් #ක්}other{දැනුම්දීම් #ක්}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"විකාශනය කරමින්"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> විකාශනය කිරීම නවත්වන්නද?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ඔබ <xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය කළහොත් හෝ ප්‍රතිදානය වෙනස් කළහොත්, ඔබගේ වත්මන් විකාශනය නවතිනු ඇත."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 4bdd20601559..86252ef9feda 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Klepnite znova"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Otvorte klepnutím na ikonu odomknutia"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Odomknuté tvárou. Otvoríte potiahnutím nahor."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odomknuté tvárou. Otvorte klepnutím na ikonu odomknutia."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odomknuté tvárou. Otvorte stlačením."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Tvár bola rozpoznaná. Otvorte stlačením."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Počet vybraných zariadení: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojené)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nedá sa prepnúť. Zopakujte klepnutím."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovať nové zariadenie"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nie je k dispozícii"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režim priority"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Budík je nastavený"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera a mikrofón sú vypnuté"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# upozornenie}few{# upozornenia}many{# notifications}other{# upozornení}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysiela"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Chcete zastaviť vysielanie aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ak vysielate aplikáciu <xliff:g id="SWITCHAPP">%1$s</xliff:g> alebo zmeníte výstup, aktuálne vysielanie bude zastavené"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index c1afc12ccc54..e6798c7429c6 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Znova se dotaknite možnosti"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Za odpiranje pritisnite ikono za odklepanje."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Odklenjeno z obrazom. Povlecite navzgor, da odprete."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odklenjeno z obrazom. Za odpiranje pritisnite ikono za odklepanje."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odklenjeno z obrazom. Pritisnite za odpiranje."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obraz je prepoznan. Pritisnite za odpiranje."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Izbranih je toliko naprav: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(povezava je prekinjena)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Preklop ni mogoč. Če želite poskusiti znova, se dotaknite."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Seznanitev nove naprave"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ni na voljo."</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prednostni način"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je nastavljen."</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat in mikrofon sta izklopljena."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obvestilo}one{# obvestilo}two{# obvestili}few{# obvestila}other{# obvestil}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Oddajanje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite ustaviti oddajanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Če oddajate aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g> ali spremenite izhod, bo trenutno oddajanje ustavljeno."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index c3cdf21857c3..11277c36f583 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Trokit sërish"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Shtyp ikonën e shkyçjes për ta hapur"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"U shkyç me fytyrë. Rrëshqit shpejt lart për ta hapur."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"U shkyç me fytyrë. Shtyp ikonën e shkyçjes për ta hapur."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"U shkyç me fytyrë. Shtyp për ta hapur."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Fytyra u njoh. Shtyp për ta hapur."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> pajisje të zgjedhura"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(shkëputur)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nuk mund të ndërrohet. Trokit për të provuar përsëri."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Çifto pajisjen e re"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nuk ofrohet"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modaliteti \"Me përparësi\""</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmi është caktuar"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dhe mikrofoni janë joaktivë"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# njoftim}other{# njoftime}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Po transmeton"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Të ndalohet transmetimi i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nëse transmeton <xliff:g id="SWITCHAPP">%1$s</xliff:g> ose ndryshon daljen, transmetimi yt aktual do të ndalojë"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index ef5993bd9fdd..7e28dbebdb42 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Притисните икону откључавања да бисте отворили."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Откључано је лицем. Превуците нагоре да бисте отворили."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Откључано је лицем. Притисните икону откључавања да бисте отворили."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Откључано је лицем. Притисните да бисте отворили."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лице је препознато. Притисните да бисте отворили."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Изабраних уређаја: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(веза је прекинута)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Пребацивање није успело. Пробајте поново."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Упари нови уређај"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi није доступан"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетни режим"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Аларм је подешен"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон су искључени"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# обавештење}one{# обавештење}few{# обавештења}other{# обавештења}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитовање"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 20bc29fc77ce..01d00b1a8a9e 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tryck igen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryck på ikonen lås upp för att öppna"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Upplåst med ansiktslås. Öppna genom att svepa uppåt."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Upplåst med ansiktslås. Tryck på ikonen lås upp för att öppna."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Upplåst med ansiktslås. Tryck för att öppna."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet har identifierats. Tryck för att öppna."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> enheter har valts"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frånkopplad)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Misslyckat byte. Tryck och försök igen."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parkoppla en ny enhet"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi är inte tillgängligt"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetsläge"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmet är aktiverat"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kameran och mikrofonen är avstängda"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# avisering}other{# aviseringar}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sänder"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vill du sluta sända från <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Om en utsändning från <xliff:g id="SWITCHAPP">%1$s</xliff:g> pågår eller om du byter ljudutgång avbryts den nuvarande utsändningen"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 418b88eede96..2a654eb0ee91 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Gusa tena"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Bonyeza aikoni ya kufungua ili ufungue"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Imefunguliwa kwa kutumia uso wako. Telezesha kidole juu ili ufungue."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Imefunguliwa kwa kutumia uso wako. Bonyeza aikoni ya kufungua ili ufungue."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili ufungue."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Uso umetambuliwa. Bonyeza ili ufungue."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Umechagua vifaa <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(imetenganishwa)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Imeshindwa kubadilisha. Gusa ili ujaribu tena."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Oanisha kifaa kipya"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi haipatikani"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Hali ya kipaumbele"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Kengele imewekwa"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera na maikrofoni zimezimwa"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Arifa #}other{Arifa #}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Inaarifu"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ungependa kusimamisha utangazaji kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ikiwa unatangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g> au unabadilisha maudhui, tangazo lako la sasa litasimamishwa"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 34cb0cf9de5b..c9b057fe42f6 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"மீண்டும் தட்டவும்"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"திறக்க, அன்லாக் ஐகானை அழுத்தவும்"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"முகத்தால் அன்லாக் செய்யப்பட்டது திறக்க மேல்நோக்கி ஸ்வைப்செய்க"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க, அன்லாக் ஐகானை அழுத்துக."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க அழுத்தவும்."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"முகம் அங்கீகரிக்கப்பட்டது. திறக்க அழுத்தவும்."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> சாதனங்கள் தேர்ந்தெடுக்கப்பட்டுள்ளன"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(துண்டிக்கப்பட்டது)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"இணைக்க முடியவில்லை. மீண்டும் முயல தட்டவும்."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"புதிய சாதனத்தை இணைத்தல்"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"வைஃபை கிடைக்கவில்லை"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"முன்னுரிமைப் பயன்முறை"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"அலாரம் அமைக்கப்பட்டுள்ளது"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"கேமராவும் மைக்கும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# அறிவிப்பு}other{# அறிவிப்புகள்}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ஒலிபரப்புதல்"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒலிபரப்பப்படுவதை நிறுத்தவா?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"நீங்கள் <xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பினாலோ அவுட்புட்டை மாற்றினாலோ உங்களின் தற்போதைய ஒலிபரப்பு நிறுத்தப்படும்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 720c909b5223..bc7b79dc249f 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -49,7 +49,7 @@
<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">"ఈ కంప్యూటర్ నుండి ఎల్లప్పుడూ అనుమతించు"</string>
+ <string name="usb_debugging_always" msgid="4003121804294739548">"ఈ కంప్యూటర్ నుండి ఎల్లప్పుడూ అనుమతించండి"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించండి"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
<string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన వినియోగదారు USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక వినియోగదారుకి మారాలి."</string>
@@ -59,7 +59,7 @@
<string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"ప్రస్తుత భాషను అలా ఉంచండి"</string>
<string name="wifi_debugging_title" msgid="7300007687492186076">"ఈ నెట్‌వర్క్ ద్వారా వైర్‌లెస్ డీబగ్గింగ్‌ను అనుమతించాలా?"</string>
<string name="wifi_debugging_message" msgid="5461204211731802995">"నెట్‌వర్క్ పేరు (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi అడ్రస్ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
- <string name="wifi_debugging_always" msgid="2968383799517975155">"ఈ నెట్‌వర్క్ నుండి ఎల్లప్పుడూ అనుమతించు"</string>
+ <string name="wifi_debugging_always" msgid="2968383799517975155">"ఈ నెట్‌వర్క్ నుండి ఎల్లప్పుడూ అనుమతించండి"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించండి"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"వైర్‌లెస్ డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
<string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన యూజర్, వైర్‌లెస్ డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక యూజర్ కి స్విచ్ అవ్వండి."</string>
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"మళ్లీ ట్యాప్ చేయండి"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ముఖం ద్వారా అన్‌లాక్ అయింది. తెరవడానికి, పైకి స్వైప్ చేయండి."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి నొక్కండి."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ముఖం గుర్తించబడింది. తెరవడానికి నొక్కండి."</string>
@@ -352,7 +351,7 @@
<string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ఒక యూజర్‌ను మాత్రమే క్రియేట్ చేయవచ్చు.}other{మీరు గరిష్టంగా # మంది యూజర్‌లను జోడించవచ్చు.}}"</string>
<string name="user_remove_user_title" msgid="9124124694835811874">"వినియోగదారుని తీసివేయాలా?"</string>
<string name="user_remove_user_message" msgid="6702834122128031833">"ఈ వినియోగదారుకు సంబంధించిన అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
- <string name="user_remove_user_remove" msgid="8387386066949061256">"తీసివేయి"</string>
+ <string name="user_remove_user_remove" msgid="8387386066949061256">"తీసివేయండి"</string>
<string name="media_projection_dialog_text" msgid="1755705274910034772">"రికార్డ్ చేస్తున్నప్పుడు లేదా ప్రసారం చేస్తున్నప్పుడు, మీ స్క్రీన్‌పై ప్రదర్శించబడిన లేదా మీ పరికరం నుండి ప్లే చేయబడిన సమాచారం మొత్తాన్ని, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> యాక్సెస్ చేయగలుగుతుంది. ఈ సమాచారంలో, పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, ఫోటోలు, మెసేజ్‌లు, మీరు ప్లే చేసే ఆడియో వంటివి ఉంటాయి."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"రికార్డ్ చేస్తున్నప్పుడు లేదా ప్రసారం చేస్తున్నప్పుడు మీ స్క్రీన్‌పై ప్రదర్శించబడిన లేదా మీ పరికరం నుండి ప్లే చేయబడిన సమాచారం మొత్తాన్ని, ఈ ఫంక్షన్‌ను అందిస్తున్న సర్వీస్ యాక్సెస్ చేయగలదు. ఈ సమాచారంలో, పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, ఫోటోలు, మెసేజ్‌లు, మీరు ప్లే చేసే ఆడియో వంటివి ఉంటాయి."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"రికార్డ్ చేయడం లేదా ప్రసారం చేయడం ప్రారంభించాలా?"</string>
@@ -483,7 +482,7 @@
<string name="tuner_persistent_warning" msgid="230466285569307806">"ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
<string name="got_it" msgid="477119182261892069">"అర్థమైంది"</string>
<string name="tuner_toast" msgid="3812684836514766951">"అభినందనలు! సెట్టింగ్‌లకు సిస్టమ్ UI ట్యూనర్ జోడించబడింది"</string>
- <string name="remove_from_settings" msgid="633775561782209994">"సెట్టింగ్‌ల నుండి తీసివేయి"</string>
+ <string name="remove_from_settings" msgid="633775561782209994">"సెట్టింగ్‌ల నుండి తీసివేయండి"</string>
<string name="remove_from_settings_prompt" msgid="551565437265615426">"సిస్టమ్ UI ట్యూనర్‌ను సెట్టింగ్‌ల నుండి తీసివేసి, దాని అన్ని లక్షణాలను ఉపయోగించడం ఆపివేయాలా?"</string>
<string name="enable_bluetooth_title" msgid="866883307336662596">"బ్లూటూత్ ఆన్ చేయాలా?"</string>
<string name="enable_bluetooth_message" msgid="6740938333772779717">"మీ కీబోర్డ్‌ను మీ టాబ్లెట్‌తో కనెక్ట్ చేయడానికి, మీరు ముందుగా బ్లూటూత్ ఆన్ చేయాలి."</string>
@@ -528,7 +527,7 @@
<string name="notification_more_settings" msgid="4936228656989201793">"మరిన్ని సెట్టింగ్‌లు"</string>
<string name="notification_app_settings" msgid="8963648463858039377">"అనుకూలపరచండి"</string>
<string name="notification_conversation_bubble" msgid="2242180995373949022">"బబుల్‌ను చూపించు"</string>
- <string name="notification_conversation_unbubble" msgid="6908427185031099868">"బబుల్స్ తీసివేయి"</string>
+ <string name="notification_conversation_unbubble" msgid="6908427185031099868">"బబుల్స్ తీసివేయండి"</string>
<string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
<string name="notification_menu_gear_description" msgid="6429668976593634862">"నోటిఫికేషన్ నియంత్రణలు"</string>
<string name="notification_menu_snooze_description" msgid="4740133348901973244">"నోటిఫికేషన్ తాత్కాలిక ఆపివేత ఎంపికలు"</string>
@@ -564,7 +563,7 @@
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
<string name="keyboard_key_num_lock" msgid="7209960042043090548">"Num Lock"</string>
<string name="keyboard_key_numpad_template" msgid="7316338238459991821">"నంబర్ ప్యాడ్ <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"అటాచ్‌మెంట్‌ను తీసివేయి"</string>
+ <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"అటాచ్‌మెంట్‌ను తీసివేయండి"</string>
<string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"సిస్టమ్"</string>
<string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"హోమ్"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"ఇటీవలివి"</string>
@@ -766,7 +765,7 @@
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>వ స్థానంలో ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
<string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ఇష్టమైనదిగా పెట్టిన గుర్తు తీసివేయబడింది"</string>
<string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ఇష్టమైనదిగా గుర్తు పెట్టు"</string>
- <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ఇష్టమైనదిగా పెట్టిన గుర్తును తీసివేయి"</string>
+ <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ఇష్టమైనదిగా పెట్టిన గుర్తును తీసివేయండి"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> పొజిషన్‌కు తరలించండి"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"నియంత్రణలు"</string>
<string name="controls_favorite_subtitle" msgid="6481675111056961083">"త్వరిత సెట్టింగ్‌ల నుండి యాక్సెస్ చేయడానికి కంట్రోల్స్‌ను ఎంచుకోండి"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> పరికరాలు ఎంచుకోబడ్డాయి"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(డిస్కనెక్ట్ అయ్యింది)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"స్విచ్ చేయడం సాధ్యం కాదు. మళ్ళీ ట్రై చేయడానికి ట్యాప్ చేయండి."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"కొత్త పరికరాన్ని పెయిర్ చేయండి"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi అందుబాటులో లేదు"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ముఖ్యమైన ఫైల్స్ మోడ్"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"అలారం సెట్ చేశాను"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"కెమెరా, మైక్ ఆఫ్‌లో ఉన్నాయి"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# నోటిఫికేషన్}other{# నోటిఫికేషన్‌లు}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ప్రసారం చేస్తోంది"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రసారం చేయడాన్ని ఆపివేయాలా?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"మీరు <xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేస్తే లేదా అవుట్‌పుట్‌ను మార్చినట్లయితే, మీ ప్రస్తుత ప్రసారం ఆగిపోతుంది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 8958be0ea95a..bacb5aa79efb 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"แตะอีกครั้ง"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"กดไอคอนปลดล็อกเพื่อเปิด"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ปลดล็อกด้วยใบหน้าแล้ว ปัดขึ้นเพื่อเปิด"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ปลดล็อกด้วยใบหน้าแล้ว กดไอคอนปลดล็อกเพื่อเปิด"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อเปิด"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"จดจำใบหน้าได้ กดเพื่อเปิด"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"เลือกอุปกรณ์ไว้ <xliff:g id="COUNT">%1$d</xliff:g> รายการ"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ยกเลิกการเชื่อมต่อแล้ว)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"เปลี่ยนไม่ได้ แตะเพื่อลองอีกครั้ง"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"จับคู่อุปกรณ์ใหม่"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ใช้ Wi‑Fi ไม่ได้"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"โหมดลำดับความสำคัญ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ตั้งปลุกแล้ว"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"กล้องและไมค์ปิดอยู่"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{การแจ้งเตือน # รายการ}other{การแจ้งเตือน # รายการ}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"กำลังออกอากาศ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"หยุดการออกอากาศ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"หากคุณออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g> หรือเปลี่ยนแปลงเอาต์พุต การออกอากาศในปัจจุบันจะหยุดลง"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 134005c85545..38fbdf80cec7 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"I-tap ulit"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pindutin ang icon ng unlock para buksan"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Na-unlock gamit ang mukha. Mag-swipe pataas para buksan."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Na-unlock gamit ang mukha. Pindutin ang icon ng unlock para buksan."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Na-unlock gamit ang mukha. Pindutin para buksan."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nakilala ang mukha. Pindutin para buksan."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> (na) device ang napili"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nadiskonekta)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Hindi makalipat. I-tap para subukan ulit."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Magpares ng bagong device"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Hindi available ang Wi‑Fi"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Nakatakda ang alarm"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Naka-off ang camera at mikropono"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# na notification}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Nagbo-broadcast"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ihinto ang pag-broadcast ng <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kung magbo-broadcast ka ng <xliff:g id="SWITCHAPP">%1$s</xliff:g> o babaguhin mo ang output, hihinto ang iyong kasalukuyang broadcast"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index fb928b2f5c4a..8556fc81868b 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tekrar dokunun"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Açmak için Kilit açma simgesine basın"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Cihazın kilidini yüzünüzle açtınız. Açmak için yukarı kaydırın."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Cihazın kilidini yüzünüzle açtınız. Açmak için basın."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yüzünüz tanındı. Açmak için basın."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> cihaz seçildi"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kesildi)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Geçiş yapılamıyor. Tekrar denemek için dokunun."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihaz eşle"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Kablosuz kullanılamıyor"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Öncelik modu"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm kuruldu"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ve mikrofon kapalı"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildirim}other{# bildirim}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayınlama"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında anons durdurulsun mu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapar veya çıkışı değiştirirseniz mevcut anonsunuz duraklatılır"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 3df26f662787..357a78bcb572 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Натисніть знову"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Щоб відкрити, натисніть значок розблокування."</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Розблоковано (фейсконтроль). Відкрити: проведіть угору."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Розблоковано (фейсконтроль). Натисніть, щоб відкрити."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Обличчя розпізнано. Натисніть, щоб відкрити."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Вибрано пристроїв: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(від’єднано)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не вдалося змінити підключення. Натисніть, щоб повторити спробу."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Підключити новий пристрій"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Мережа Wi-Fi недоступна"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим пріоритету"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлено"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камеру й мікрофон вимкнено"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# сповіщення}one{# сповіщення}few{# сповіщення}many{# сповіщень}other{# сповіщення}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляція"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Зупинити трансляцію з додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Якщо ви зміните додаток (<xliff:g id="SWITCHAPP">%1$s</xliff:g>) або аудіовихід, поточну трансляцію буде припинено"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 40e0bb3e3148..09b23a337c8c 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"دوبارہ تھپتھپائیں"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"کھولنے کیلئے انلاک آئیکن دبائیں"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"چہرے سے غیر مقفل کیا گیا۔ کھولنے کے لیے اوپر سوائپ کريں۔"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"چہرے سے انلاک کیا گیا۔ کھولنے کیلئے انلاک آئیکن دبائیں۔"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"چہرے سے انلاک کیا گیا۔ کھولنے کے لیے دبائیں۔"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چہرے کی شناخت ہو گئی۔ کھولنے کے لیے دبائیں۔"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> آلات منتخب کیے گئے"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غیر منسلک ہے)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"سوئچ نہیں کر سکتے۔ دوبارہ کوشش کرنے کے لیے تھپتھپائیں۔"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"نئے آلہ کا جوڑا بنائیں"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi-Fi دستیاب نہیں ہے"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ترجیحی وضع"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"الارم سیٹ ہوگیا"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"کیمرا اور مائیک آف ہیں"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اطلاع}other{# اطلاعات}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"نشریات"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> براڈکاسٹنگ روکیں؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر آپ <xliff:g id="SWITCHAPP">%1$s</xliff:g> براڈکاسٹ کرتے ہیں یا آؤٹ پٹ کو تبدیل کرتے ہیں تو آپ کا موجودہ براڈکاسٹ رک جائے گا"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index a6490f429742..63e5c7f3b077 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Yana bosing"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Ochish uchun ochish belgisini bosing"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Yuz bilan ochildi. Ochish uchun tepaga suring."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Yuz orqali ochilgan. Ochish uchun ochish belgisini bosing."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Yuz orqali ochildi. Ochish uchun bosing."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yuz aniqlandi. Ochish uchun bosing."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ta qurilma tanlandi"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(uzildi)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Xatolik. Qayta urinish uchun bosing."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani juftlash"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ishlamayapti"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imtiyozli rejim"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signal oʻrnatildi"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera va mikrofon yoqilmagan"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ta bildirishnoma}other{# ta bildirishnoma}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Signal uzatish"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga translatsiya toʻxtatilsinmi?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Agar <xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya qilsangiz yoki ovoz chiqishini oʻzgartirsangiz, joriy translatsiya toʻxtab qoladi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 3a579f15ead4..48d1bba7a5e8 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Nhấn lại"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Nhấn biểu tượng mở khoá để mở"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Đã mở khoá bằng khuôn mặt. Vuốt lên để mở"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Đã mở khoá bằng khuôn mặt. Nhấn vào biểu tượng mở khoá để mở."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Đã mở khoá bằng khuôn mặt. Nhấn để mở."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Đã nhận diện khuôn mặt. Nhấn để mở."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Đã chọn <xliff:g id="COUNT">%1$d</xliff:g> thiết bị"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(đã ngắt kết nối)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Không thể chuyển đổi. Hãy nhấn để thử lại."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Ghép nối thiết bị mới"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Không có Wi‑Fi"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Chế độ ưu tiên"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Đã đặt chuông báo"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Máy ảnh và micrô đang tắt"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# thông báo}other{# thông báo}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Phát sóng"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Dừng phát <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nếu bạn phát <xliff:g id="SWITCHAPP">%1$s</xliff:g> hoặc thay đổi đầu ra, phiên truyền phát hiện tại sẽ dừng"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b46406e9d31e..fe8aa3057c5b 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"请再点按一次"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"按下解锁图标即可打开"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"已通过面孔识别解锁。向上滑动即可打开。"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已通过面孔识别解锁。按下解锁图标即可打开。"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已通过面孔识别解锁。点按即可打开。"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"识别出面孔。点按即可打开。"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"已选择 <xliff:g id="COUNT">%1$d</xliff:g> 个设备"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已断开连接)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"无法切换。点按即可重试。"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN 已关闭"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"优先模式"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"闹钟已设置"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"摄像头和麦克风已关闭"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 条通知}other{# 条通知}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"正在广播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止广播“<xliff:g id="APP_NAME">%1$s</xliff:g>”的内容吗?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容或更改输出来源,当前的广播就会停止"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 1958d0df7401..0cd35b1361b8 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"再次輕按"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"按解鎖圖示即可開啟"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"已使用面孔解鎖,向上滑動即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已使用面孔解鎖。按解鎖圖示即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已使用面孔解鎖。按下即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"已識別面孔。按下即可開啟。"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 部裝置"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已中斷連線)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕按即可重試。"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"已設定鬧鐘"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"相機和麥克風已關閉"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止廣播「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如要廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止廣播目前的內容"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 22d0544f3314..dc2faf051b0e 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"再輕觸一次"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"按下「解鎖」圖示即可開啟"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"你已用自己的臉解鎖裝置,向上滑動即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"裝置已透過人臉解鎖,按下「解鎖」圖示即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"裝置已透過你的臉解鎖,按下即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"臉孔辨識完成,按下即可開啟。"</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 部裝置"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(連線中斷)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕觸即可重試。"</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"鬧鐘設定成功"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"已關閉相機和麥克風"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止播送「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止播送目前的內容"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 4000ce00de59..ac61ce661666 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -307,8 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Thepha futhi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Cindezela isithonjana sokuvula ukuze uvule"</string>
- <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
- <skip />
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Vula ngobuso. Swayiphela phezulu ukuze uvule."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uvule."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Vula ngobuso. Cindezela ukuze uvule."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ubuso buyaziwa. Cindezela ukuze uvule."</string>
@@ -832,7 +831,8 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"amadivayisi akhethiwe angu-<xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(inqamukile)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Akukwazi ukushintsha. Thepha ukuze uzame futhi."</string>
- <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhangqa idivayisi entsha"</string>
+ <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+ <skip />
<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>
@@ -944,8 +944,14 @@
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"I-Wi-Fi ayitholakali"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imodi ebalulekile"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"I-alamu isethiwe"</string>
+ <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+ <skip />
+ <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+ <skip />
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Ikhamera nemakrofoni kuvaliwe"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Isaziso esingu-#}one{Izaziso ezingu-#}other{Izaziso ezingu-#}}"</string>
+ <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Ukusakaza"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Misa ukusakaza i-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Uma usakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g> noma ushintsha okuphumayo, ukusakaza kwakho kwamanje kuzoma"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f369bb2e3fa6..ddbe6d6a0f17 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -59,8 +59,8 @@
<dimen name="navigation_edge_entry_margin">4dp</dimen>
<dimen name="navigation_edge_entry_background_width">8dp</dimen>
<dimen name="navigation_edge_entry_background_height">60dp</dimen>
- <dimen name="navigation_edge_entry_edge_corners">6dp</dimen>
- <dimen name="navigation_edge_entry_far_corners">6dp</dimen>
+ <dimen name="navigation_edge_entry_edge_corners">30dp</dimen>
+ <dimen name="navigation_edge_entry_far_corners">30dp</dimen>
<dimen name="navigation_edge_entry_arrow_length">10dp</dimen>
<dimen name="navigation_edge_entry_arrow_height">7dp</dimen>
@@ -90,6 +90,7 @@
<dimen name="navigation_edge_cancelled_arrow_length">12dp</dimen>
<dimen name="navigation_edge_cancelled_arrow_height">0dp</dimen>
+ <dimen name="navigation_edge_cancelled_edge_corners">6dp</dimen>
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
@@ -889,7 +890,7 @@
<!-- The maximum offset for the under-display fingerprint sensor (UDFPS) icon in either
direction that elements are moved to prevent burn-in on AOD-->
<dimen name="udfps_burn_in_offset_x">7px</dimen>
- <dimen name="udfps_burn_in_offset_y">28px</dimen>
+ <dimen name="udfps_burn_in_offset_y">20px</dimen>
<!-- The absolute side margins of quick settings -->
<dimen name="quick_settings_bottom_margin_media">8dp</dimen>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index e3f568732b9d..422274469dcc 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -16,6 +16,7 @@
package com.android.systemui.shared.recents.model;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
@@ -245,12 +246,16 @@ public class Task {
*/
public static Task from(TaskKey taskKey, TaskInfo taskInfo, boolean isLocked) {
ActivityManager.TaskDescription td = taskInfo.taskDescription;
+ // Also consider undefined activity type to include tasks in overview right after rebooting
+ // the device.
+ final boolean isDockable = taskInfo.supportsMultiWindow
+ && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode())
+ && (taskInfo.getActivityType() == ACTIVITY_TYPE_UNDEFINED
+ || ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType()));
return new Task(taskKey,
td != null ? td.getPrimaryColor() : 0,
- td != null ? td.getBackgroundColor() : 0, taskInfo.supportsMultiWindow
- && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
- && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()),
- isLocked, td, taskInfo.topActivity);
+ td != null ? td.getBackgroundColor() : 0, isDockable , isLocked, td,
+ taskInfo.topActivity);
}
public Task(TaskKey key) {
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
index cccd3a482ef0..81da80233d42 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
@@ -36,7 +36,7 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.shared.system.ActivityManagerKt.isInForeground
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.phone.CentralSurfaces
-import com.android.systemui.statusbar.phone.PanelViewController
+import com.android.systemui.shade.PanelViewController
import com.android.systemui.statusbar.policy.KeyguardStateController
import java.util.concurrent.Executor
import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index aa67ecd30627..e16ac08c88f8 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -169,6 +169,7 @@ public class ClipboardOverlayController {
private Animator mExitAnimator;
private Animator mEnterAnimator;
private final int mOrientation;
+ private boolean mKeyboardVisible;
public ClipboardOverlayController(Context context,
@@ -261,8 +262,22 @@ public class ClipboardOverlayController {
attachWindow();
withWindowAttached(() -> {
mWindow.setContentView(mView);
- updateInsets(mWindowManager.getCurrentWindowMetrics().getWindowInsets());
- mView.requestLayout();
+ WindowInsets insets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();
+ mKeyboardVisible = insets.isVisible(WindowInsets.Type.ime());
+ updateInsets(insets);
+ mWindow.peekDecorView().getViewTreeObserver().addOnGlobalLayoutListener(
+ new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ WindowInsets insets =
+ mWindowManager.getCurrentWindowMetrics().getWindowInsets();
+ boolean keyboardVisible = insets.isVisible(WindowInsets.Type.ime());
+ if (keyboardVisible != mKeyboardVisible) {
+ mKeyboardVisible = keyboardVisible;
+ updateInsets(insets);
+ }
+ }
+ });
mWindow.peekDecorView().getViewRootImpl().setActivityConfigCallback(
new ViewRootImpl.ActivityConfigCallback() {
@Override
@@ -384,8 +399,6 @@ public class ClipboardOverlayController {
mRemoteCopyChip.setVisibility(View.GONE);
}
withWindowAttached(() -> {
- updateInsets(
- mWindowManager.getCurrentWindowMetrics().getWindowInsets());
if (mEnterAnimator == null || !mEnterAnimator.isRunning()) {
mView.post(this::animateIn);
}
@@ -509,7 +522,7 @@ public class ClipboardOverlayController {
private void shareContent(ClipData clip) {
mUiEventLogger.log(CLIPBOARD_OVERLAY_SHARE_TAPPED);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.putExtra(Intent.EXTRA_TEXT, clip.getItemAt(0).getText());
+ shareIntent.putExtra(Intent.EXTRA_TEXT, clip.getItemAt(0).getText().toString());
shareIntent.setDataAndType(
clip.getItemAt(0).getUri(), clip.getDescription().getMimeType(0));
shareIntent.putExtra(Intent.EXTRA_STREAM, clip.getItemAt(0).getUri());
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
index a174ed0312c8..2389ad134c55 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
@@ -62,7 +62,7 @@ class AppAdapter(
backgroundExecutor.execute {
val collator = Collator.getInstance(resources.configuration.locales[0])
val localeComparator = compareBy<ControlsServiceInfo, CharSequence>(collator) {
- it.loadLabel()
+ it.loadLabel() ?: ""
}
listOfServices = serviceInfos.sortedWith(localeComparator)
uiExecutor.execute(::notifyDataSetChanged)
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 029cabb0bc0b..718befadd2b5 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -31,6 +31,7 @@ import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver;
import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender;
import com.android.systemui.people.PeopleProvider;
+import com.android.systemui.statusbar.pipeline.ConnectivityInfoProcessor;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.unfold.FoldStateLogger;
import com.android.systemui.unfold.FoldStateLoggingProvider;
@@ -130,6 +131,7 @@ public interface SysUIComponent {
getMediaTttCommandLineHelper();
getMediaMuteAwaitConnectionCli();
getNearbyMediaDevicesManager();
+ getConnectivityInfoProcessor();
getUnfoldLatencyTracker().init();
getFoldStateLoggingProvider().ifPresent(FoldStateLoggingProvider::init);
getFoldStateLogger().ifPresent(FoldStateLogger::init);
@@ -212,6 +214,9 @@ public interface SysUIComponent {
/** */
Optional<NearbyMediaDevicesManager> getNearbyMediaDevicesManager();
+ /** */
+ Optional<ConnectivityInfoProcessor> getConnectivityInfoProcessor();
+
/**
* Returns {@link CoreStartable}s that should be started with the application.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index fe9622250e67..ceb702eafe1e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -70,7 +70,7 @@ import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfC
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
-import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.pipeline.dagger.StatusBarPipelineModule;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -91,7 +91,6 @@ import com.android.systemui.wallet.dagger.WalletModule;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.dagger.DynamicOverride;
-import com.android.wm.shell.sysui.ShellController;
import java.util.Optional;
import java.util.concurrent.Executor;
@@ -135,6 +134,7 @@ import dagger.Provides;
SettingsUtilModule.class,
SmartRepliesInflationModule.class,
SmartspaceModule.class,
+ StatusBarPipelineModule.class,
StatusBarPolicyModule.class,
StatusBarWindowModule.class,
SysUIConcurrencyModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
index b9436f96c74f..9c22dc61e67b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
@@ -25,7 +25,7 @@ import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.touch.BouncerSwipeTouchHandler;
import com.android.systemui.dreams.touch.DreamTouchHandler;
-import com.android.systemui.statusbar.phone.PanelViewController;
+import com.android.systemui.shade.PanelViewController;
import com.android.wm.shell.animation.FlingAnimationUtils;
import javax.inject.Named;
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 481025e5bde3..b0f025d4a195 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -61,7 +61,7 @@ public class Flags {
new ResourceBooleanFlag(108, R.bool.config_notificationToContents);
public static final BooleanFlag REMOVE_UNRANKED_NOTIFICATIONS =
- new BooleanFlag(109, false);
+ new BooleanFlag(109, false, true);
public static final BooleanFlag FSI_REQUIRES_KEYGUARD =
new BooleanFlag(110, false, true);
@@ -122,7 +122,7 @@ public class Flags {
new BooleanFlag(500, true);
public static final BooleanFlag COMBINED_QS_HEADERS =
- new BooleanFlag(501, false);
+ new BooleanFlag(501, false, true);
public static final ResourceBooleanFlag PEOPLE_TILE =
new ResourceBooleanFlag(502, R.bool.flag_conversations);
@@ -136,7 +136,7 @@ public class Flags {
@Deprecated
public static final BooleanFlag NEW_FOOTER = new BooleanFlag(504, true);
- public static final BooleanFlag NEW_HEADER = new BooleanFlag(505, false);
+ public static final BooleanFlag NEW_HEADER = new BooleanFlag(505, false, true);
public static final ResourceBooleanFlag FULL_SCREEN_USER_SWITCHER =
new ResourceBooleanFlag(506, R.bool.config_enableFullscreenUserSwitcher);
@@ -151,6 +151,8 @@ public class Flags {
public static final BooleanFlag STATUS_BAR_LETTERBOX_APPEARANCE =
new BooleanFlag(603, false);
+ public static final BooleanFlag NEW_STATUS_BAR_PIPELINE = new BooleanFlag(604, false);
+
/***************************************/
// 700 - dialer/calls
public static final BooleanFlag ONGOING_CALL_STATUS_BAR_CHIP =
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 7e3275da8c31..7e58a83c5697 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -209,15 +209,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
Log.d(TAG, "No media controller for " + mPackageName);
}
}
- if (mLocalMediaManager == null) {
- if (DEBUG) {
- Log.d(TAG, "No local media manager " + mPackageName);
- }
- return;
- }
mCallback = cb;
- mLocalMediaManager.unregisterCallback(this);
- mLocalMediaManager.stopScan();
mLocalMediaManager.registerCallback(this);
mLocalMediaManager.startScan();
}
@@ -239,10 +231,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
if (mMediaController != null) {
mMediaController.unregisterCallback(mCb);
}
- if (mLocalMediaManager != null) {
- mLocalMediaManager.unregisterCallback(this);
- mLocalMediaManager.stopScan();
- }
+ mLocalMediaManager.unregisterCallback(this);
+ mLocalMediaManager.stopScan();
synchronized (mMediaDevicesLock) {
mCachedMediaDevices.clear();
mMediaDevices.clear();
@@ -622,10 +612,6 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
return mLocalMediaManager.getCurrentConnectedDevice();
}
- private MediaDevice getMediaDeviceById(String id) {
- return mLocalMediaManager.getMediaDeviceById(new ArrayList<>(mMediaDevices), id);
- }
-
boolean addDeviceToPlayMedia(MediaDevice device) {
mMetricLogger.logInteractionExpansion(device);
return mLocalMediaManager.addDeviceToPlayMedia(device);
@@ -647,10 +633,6 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
return mLocalMediaManager.getDeselectableMediaDevice();
}
- void adjustSessionVolume(String sessionId, int volume) {
- mLocalMediaManager.adjustSessionVolume(sessionId, volume);
- }
-
void adjustSessionVolume(int volume) {
mLocalMediaManager.adjustSessionVolume(volume);
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index 28ab83c83a42..b05e75ea1c97 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -34,7 +34,6 @@ import android.view.ViewConfiguration
import android.view.WindowManager
import android.view.animation.DecelerateInterpolator
import android.view.animation.PathInterpolator
-import android.window.BackEvent
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.internal.util.LatencyTracker
@@ -97,7 +96,6 @@ private val DECELERATE_INTERPOLATOR_SLOW = DecelerateInterpolator(0.7f)
class BackPanelController private constructor(
context: Context,
- private var backAnimation: BackAnimation?,
private val windowManager: WindowManager,
private val viewConfiguration: ViewConfiguration,
@Main private val mainHandler: Handler,
@@ -124,7 +122,6 @@ class BackPanelController private constructor(
fun create(context: Context, backAnimation: BackAnimation?): BackPanelController {
val backPanelController = BackPanelController(
context,
- backAnimation,
windowManager,
viewConfiguration,
mainHandler,
@@ -266,7 +263,6 @@ class BackPanelController private constructor(
*/
private fun updateConfiguration() {
params.update(resources)
- updateBackAnimationSwipeThresholds()
mView.updateArrowPaint(params.arrowThickness)
}
@@ -298,13 +294,6 @@ class BackPanelController private constructor(
}
override fun onMotionEvent(event: MotionEvent) {
- backAnimation?.onBackMotion(
- event.x,
- event.y,
- event.actionMasked,
- if (mView.isLeftPanel) BackEvent.EDGE_LEFT else BackEvent.EDGE_RIGHT
- )
-
velocityTracker!!.addMovement(event)
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
@@ -483,18 +472,6 @@ class BackPanelController private constructor(
)
}
- fun setBackAnimation(backAnimation: BackAnimation?) {
- this.backAnimation = backAnimation
- updateBackAnimationSwipeThresholds()
- }
-
- private fun updateBackAnimationSwipeThresholds() {
- backAnimation?.setSwipeThresholds(
- params.swipeTriggerThreshold,
- fullyStretchedThreshold
- )
- }
-
override fun onDestroy() {
cancelFailsafe()
windowManager.removeView(mView)
@@ -567,7 +544,6 @@ class BackPanelController private constructor(
totalTouchDelta = 0f
vibrationTime = 0
cancelFailsafe()
- backAnimation?.setTriggerBack(false)
}
private fun updateYPosition(touchY: Float) {
@@ -580,7 +556,6 @@ class BackPanelController private constructor(
override fun setDisplaySize(displaySize: Point) {
this.displaySize.set(displaySize.x, displaySize.y)
fullyStretchedThreshold = min(displaySize.x.toFloat(), params.swipeProgressThreshold)
- updateBackAnimationSwipeThresholds()
}
/**
@@ -626,7 +601,7 @@ class BackPanelController private constructor(
if (currentState == GestureState.INACTIVE ||
currentState == GestureState.CANCELLED
)
- params.entryIndicator.backgroundDimens.edgeCornerRadius
+ params.cancelledEdgeCornerRadius
else
params.activeIndicator.backgroundDimens.edgeCornerRadius
)
@@ -664,7 +639,6 @@ class BackPanelController private constructor(
updateRestingArrowDimens(animated = true, currentState)
}
GestureState.ACTIVE -> {
- backAnimation?.setTriggerBack(true)
updateRestingArrowDimens(animated = true, currentState)
// Vibrate the first time we transition to ACTIVE
if (!hasHapticPlayed) {
@@ -674,7 +648,6 @@ class BackPanelController private constructor(
}
}
GestureState.INACTIVE -> {
- backAnimation?.setTriggerBack(false)
updateRestingArrowDimens(animated = true, currentState)
}
GestureState.FLUNG -> playFlingBackAnimation()
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 067f4cbb975e..057ed2439df3 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -53,6 +53,7 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.ViewConfiguration;
import android.view.WindowManager;
+import android.window.BackEvent;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.policy.GestureNavigationSettingsObserver;
@@ -208,6 +209,10 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
private float mBottomGestureHeight;
// The slop to distinguish between horizontal and vertical motion
private float mTouchSlop;
+ // The threshold for triggering back
+ private float mBackSwipeTriggerThreshold;
+ // The threshold for back swipe full progress.
+ private float mBackSwipeProgressThreshold;
// Duration after which we consider the event as longpress.
private final int mLongPressTimeout;
private int mStartingQuickstepRotation = -1;
@@ -274,6 +279,8 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
Log.d(DEBUG_MISSING_GESTURE_TAG, "Triggered back: down="
+ sendDown + ", up=" + sendUp);
}
+ } else {
+ mBackAnimation.setTriggerBack(true);
}
mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x,
@@ -285,6 +292,9 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
@Override
public void cancelBack() {
+ if (mBackAnimation != null) {
+ mBackAnimation.setTriggerBack(false);
+ }
logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE);
mOverviewProxyService.notifyBackAction(false, (int) mDownPoint.x,
(int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge);
@@ -406,6 +416,11 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
final float backGestureSlop = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.BACK_GESTURE_SLOP_MULTIPLIER, 0.75f);
mTouchSlop = mViewConfiguration.getScaledTouchSlop() * backGestureSlop;
+ mBackSwipeTriggerThreshold = res.getDimension(
+ R.dimen.navigation_edge_action_drag_threshold);
+ mBackSwipeProgressThreshold = res.getDimension(
+ R.dimen.navigation_edge_action_progress_threshold);
+ updateBackAnimationThresholds();
}
public void updateNavigationBarOverlayExcludeRegion(Rect exclude) {
@@ -748,6 +763,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
MotionEvent cancelEv = MotionEvent.obtain(ev);
cancelEv.setAction(MotionEvent.ACTION_CANCEL);
mEdgeBackPlugin.onMotionEvent(cancelEv);
+ dispatchToBackAnimation(cancelEv);
cancelEv.recycle();
}
@@ -794,6 +810,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
if (mAllowGesture) {
mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
mEdgeBackPlugin.onMotionEvent(ev);
+ dispatchToBackAnimation(ev);
}
if (mLogGesture) {
mDownPoint.set(ev.getX(), ev.getY());
@@ -867,12 +884,23 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
if (mAllowGesture) {
// forward touch
mEdgeBackPlugin.onMotionEvent(ev);
+ dispatchToBackAnimation(ev);
}
}
mProtoTracer.scheduleFrameUpdate();
}
+ private void dispatchToBackAnimation(MotionEvent event) {
+ if (mBackAnimation != null) {
+ mBackAnimation.onBackMotion(
+ event.getX(),
+ event.getY(),
+ event.getActionMasked(),
+ mIsOnLeftEdge ? BackEvent.EDGE_LEFT : BackEvent.EDGE_RIGHT);
+ }
+ }
+
private void updateDisabledForQuickstep(Configuration newConfig) {
int rotation = newConfig.windowConfiguration.getRotation();
mDisabledForQuickstep = mStartingQuickstepRotation > -1 &&
@@ -900,6 +928,16 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
if (mEdgeBackPlugin != null) {
mEdgeBackPlugin.setDisplaySize(mDisplaySize);
}
+ updateBackAnimationThresholds();
+ }
+
+ private void updateBackAnimationThresholds() {
+ if (mBackAnimation == null) {
+ return;
+ }
+ mBackAnimation.setSwipeThresholds(
+ mBackSwipeTriggerThreshold,
+ Math.min(mDisplaySize.x, mBackSwipeProgressThreshold));
}
private boolean sendEvent(int action, int code) {
@@ -979,13 +1017,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
public void setBackAnimation(BackAnimation backAnimation) {
mBackAnimation = backAnimation;
- if (mEdgeBackPlugin != null) {
- if (mEdgeBackPlugin instanceof NavigationBarEdgePanel) {
- ((NavigationBarEdgePanel) mEdgeBackPlugin).setBackAnimation(backAnimation);
- } else if (mEdgeBackPlugin instanceof BackPanelController) {
- ((BackPanelController) mEdgeBackPlugin).setBackAnimation(backAnimation);
- }
- }
+ updateBackAnimationThresholds();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
index a3fb58d5b015..d56537b694da 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -33,6 +33,8 @@ data class EdgePanelParams(private var resources: Resources) {
private set
var fullyStretchedIndicator = BackIndicatorDimens()
private set
+ var cancelledEdgeCornerRadius: Float = 0f
+ private set
var cancelledArrowDimens = ArrowDimens()
// navigation bar edge constants
@@ -132,6 +134,8 @@ data class EdgePanelParams(private var resources: Resources) {
)
)
+ cancelledEdgeCornerRadius = getDimen(R.dimen.navigation_edge_cancelled_edge_corners)
+
cancelledArrowDimens = ArrowDimens(
length = getDimen(R.dimen.navigation_edge_cancelled_arrow_length),
height = getDimen(R.dimen.navigation_edge_cancelled_arrow_height)
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index e845aa85a121..7cc95a158a14 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -22,7 +22,6 @@ import static android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
-import android.view.View;
import android.view.ViewGroup;
import androidx.activity.ComponentActivity;
@@ -40,7 +39,6 @@ public class PeopleSpaceActivity extends ComponentActivity {
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
private final PeopleViewModel.Factory mViewModelFactory;
- private PeopleViewModel mViewModel;
@Inject
public PeopleSpaceActivity(PeopleViewModel.Factory viewModelFactory) {
@@ -52,38 +50,32 @@ public class PeopleSpaceActivity extends ComponentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setResult(RESULT_CANCELED);
- mViewModel = new ViewModelProvider(this, mViewModelFactory).get(PeopleViewModel.class);
+
+ PeopleViewModel viewModel = new ViewModelProvider(this, mViewModelFactory).get(
+ PeopleViewModel.class);
// Update the widget ID coming from the intent.
int widgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID);
- mViewModel.onWidgetIdChanged(widgetId);
+ viewModel.onWidgetIdChanged(widgetId);
ViewGroup view = PeopleViewBinder.create(this);
- PeopleViewBinder.bind(view, mViewModel, /* lifecycleOwner= */ this,
- () -> {
- finishActivity();
+ PeopleViewBinder.bind(view, viewModel, /* lifecycleOwner= */ this,
+ (result) -> {
+ finishActivity(result);
return null;
});
setContentView(view);
}
- /** Finish activity with a successful widget configuration result. */
- private void finishActivity() {
- if (DEBUG) Log.d(TAG, "Widget added!");
- setActivityResult(RESULT_OK);
+ private void finishActivity(PeopleViewModel.Result result) {
+ if (result instanceof PeopleViewModel.Result.Success) {
+ if (DEBUG) Log.d(TAG, "Widget added!");
+ Intent data = ((PeopleViewModel.Result.Success) result).getData();
+ setResult(RESULT_OK, data);
+ } else {
+ if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
+ setResult(RESULT_CANCELED);
+ }
finish();
}
-
- /** Finish activity without choosing a widget. */
- public void dismissActivity(View v) {
- if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
- setResult(RESULT_CANCELED);
- finish();
- }
-
- private void setActivityResult(int result) {
- Intent resultValue = new Intent();
- resultValue.putExtra(EXTRA_APPWIDGET_ID, mViewModel.getAppWidgetId().getValue());
- setResult(result, resultValue);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
index bc982cccaacd..d8a429e5bb1a 100644
--- a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
@@ -41,7 +41,7 @@ import kotlinx.coroutines.launch
/** A ViewBinder for [PeopleViewModel]. */
object PeopleViewBinder {
- private const val TAG = "PeopleSpaceViewBinder"
+ private const val TAG = "PeopleViewBinder"
/**
* The [ViewOutlineProvider] used to clip the corner radius of the recent and priority lists.
@@ -72,15 +72,15 @@ object PeopleViewBinder {
view: ViewGroup,
viewModel: PeopleViewModel,
lifecycleOwner: LifecycleOwner,
- onFinish: () -> Unit,
+ onResult: (PeopleViewModel.Result) -> Unit,
) {
- // Call [onFinish] this activity when the ViewModel tells us so.
+ // Call [onResult] as soon as a result is available.
lifecycleOwner.lifecycleScope.launch {
lifecycleOwner.repeatOnLifecycle(CREATED) {
- viewModel.isFinished.collect { isFinished ->
- if (isFinished) {
- viewModel.clearIsFinished()
- onFinish()
+ viewModel.result.collect { result ->
+ if (result != null) {
+ viewModel.clearResult()
+ onResult(result)
}
}
}
@@ -104,7 +104,7 @@ object PeopleViewBinder {
viewModel::onTileClicked,
)
} else {
- setNoConversationsContent(view)
+ setNoConversationsContent(view, viewModel::onUserJourneyCancelled)
}
}
}
@@ -119,7 +119,7 @@ object PeopleViewBinder {
}
}
- private fun setNoConversationsContent(view: ViewGroup) {
+ private fun setNoConversationsContent(view: ViewGroup, onGotItClicked: () -> Unit) {
// This should never happen.
if (view.childCount > 1) {
error("view has ${view.childCount} children, it should have maximum 1")
@@ -140,6 +140,10 @@ object PeopleViewBinder {
LayoutInflater.from(context)
.inflate(R.layout.people_space_activity_no_conversations, /* root= */ view)
+ noConversationsView.findViewById<View>(R.id.got_it_button).setOnClickListener {
+ onGotItClicked()
+ }
+
// The Tile preview has colorBackground as its background. Change it so it's different than
// the activity's background.
val item = noConversationsView.findViewById<LinearLayout>(android.R.id.background)
diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
index 17de991588b8..0834a5ae75f6 100644
--- a/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
@@ -16,8 +16,10 @@
package com.android.systemui.people.ui.viewmodel
+import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
import android.content.Context
+import android.content.Intent
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
@@ -32,6 +34,7 @@ import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
/**
* Models UI state for the people space, allowing the user to select which conversation should be
@@ -49,7 +52,7 @@ class PeopleViewModel(
* reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
*/
private val _priorityTiles = MutableStateFlow(priorityTiles())
- val priorityTiles: Flow<List<PeopleTileViewModel>> = _priorityTiles
+ val priorityTiles: Flow<List<PeopleTileViewModel>> = _priorityTiles.asStateFlow()
/**
* The list of the priority tiles/conversations.
@@ -58,15 +61,15 @@ class PeopleViewModel(
* reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
*/
private val _recentTiles = MutableStateFlow(recentTiles())
- val recentTiles: Flow<List<PeopleTileViewModel>> = _recentTiles
+ val recentTiles: Flow<List<PeopleTileViewModel>> = _recentTiles.asStateFlow()
/** The ID of the widget currently being edited/added. */
private val _appWidgetId = MutableStateFlow(INVALID_APPWIDGET_ID)
- val appWidgetId: StateFlow<Int> = _appWidgetId
+ val appWidgetId: StateFlow<Int> = _appWidgetId.asStateFlow()
- /** Whether the user journey is complete. */
- private val _isFinished = MutableStateFlow(false)
- val isFinished: StateFlow<Boolean> = _isFinished
+ /** The result of this user journey. */
+ private val _result = MutableStateFlow<Result?>(null)
+ val result: StateFlow<Result?> = _result.asStateFlow()
/** Refresh the [priorityTiles] and [recentTiles]. */
fun onTileRefreshRequested() {
@@ -79,22 +82,28 @@ class PeopleViewModel(
_appWidgetId.value = widgetId
}
- /** Clear [isFinished], setting it to false. */
- fun clearIsFinished() {
- _isFinished.value = false
+ /** Clear [result], setting it to null. */
+ fun clearResult() {
+ _result.value = null
}
/** Called when a tile is clicked. */
fun onTileClicked(tile: PeopleTileViewModel) {
+ val widgetId = _appWidgetId.value
if (PeopleSpaceUtils.DEBUG) {
Log.d(
TAG,
- "Put ${tile.username}'s shortcut ID: ${tile.key.shortcutId} for widget ID: " +
- _appWidgetId.value
+ "Put ${tile.username}'s shortcut ID: ${tile.key.shortcutId} for widget ID $widgetId"
)
}
- widgetRepository.setWidgetTile(_appWidgetId.value, tile.key)
- _isFinished.value = true
+ widgetRepository.setWidgetTile(widgetId, tile.key)
+ _result.value =
+ Result.Success(Intent().apply { putExtra(EXTRA_APPWIDGET_ID, appWidgetId.value) })
+ }
+
+ /** Called when this user journey is cancelled. */
+ fun onUserJourneyCancelled() {
+ _result.value = Result.Cancelled
}
private fun priorityTiles(): List<PeopleTileViewModel> {
@@ -143,7 +152,12 @@ class PeopleViewModel(
}
}
+ sealed class Result {
+ class Success(val data: Intent) : Result()
+ object Cancelled : Result()
+ }
+
companion object {
- private const val TAG = "PeopleSpaceViewModel"
+ private const val TAG = "PeopleViewModel"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index a1c66b35bacc..4552abd402b0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -19,8 +19,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings.Secure;
@@ -28,6 +26,7 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
import com.android.internal.logging.InstanceId;
@@ -35,9 +34,7 @@ import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
-import com.android.systemui.broadcast.BroadcastDispatcher;
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.plugins.PluginListener;
@@ -68,12 +65,20 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.function.Predicate;
import javax.inject.Inject;
import javax.inject.Provider;
-/** Platform implementation of the quick settings tile host **/
+/** Platform implementation of the quick settings tile host
+ *
+ * This class keeps track of the set of current tiles and is the in memory source of truth
+ * (ground truth is kept in {@link Secure#QS_TILES}). When the ground truth changes,
+ * {@link #onTuningChanged} will be called and the tiles will be re-created as needed.
+ *
+ * This class also provides the interface for adding/removing/changing tiles.
+ */
@SysUISingleton
public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, Dumpable {
private static final String TAG = "QSTileHost";
@@ -89,11 +94,11 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
private final TunerService mTunerService;
private final PluginManager mPluginManager;
private final DumpManager mDumpManager;
- private final BroadcastDispatcher mBroadcastDispatcher;
private final QSLogger mQSLogger;
private final UiEventLogger mUiEventLogger;
private final InstanceIdSequence mInstanceIdSequence;
private final CustomTileStatePersister mCustomTileStatePersister;
+ private final Executor mMainExecutor;
private final List<Callback> mCallbacks = new ArrayList<>();
@Nullable
@@ -113,13 +118,11 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
public QSTileHost(Context context,
StatusBarIconController iconController,
QSFactory defaultFactory,
- @Main Handler mainHandler,
- @Background Looper bgLooper,
+ @Main Executor mainExecutor,
PluginManager pluginManager,
TunerService tunerService,
Provider<AutoTileManager> autoTiles,
DumpManager dumpManager,
- BroadcastDispatcher broadcastDispatcher,
Optional<CentralSurfaces> centralSurfacesOptional,
QSLogger qsLogger,
UiEventLogger uiEventLogger,
@@ -137,7 +140,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
mDumpManager = dumpManager;
mQSLogger = qsLogger;
mUiEventLogger = uiEventLogger;
- mBroadcastDispatcher = broadcastDispatcher;
+ mMainExecutor = mainExecutor;
mTileServiceRequestController = tileServiceRequestControllerBuilder.create(this);
mTileLifeCycleManagerFactory = tileLifecycleManagerFactory;
@@ -151,7 +154,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
mSecureSettings = secureSettings;
mCustomTileStatePersister = customTileStatePersister;
- mainHandler.post(() -> {
+ mainExecutor.execute(() -> {
// This is technically a hack to avoid circular dependency of
// QSTileHost -> XXXTile -> QSTileHost. Posting ensures creation
// finishes before creating any tiles.
@@ -258,6 +261,33 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
return mTileSpecs.indexOf(spec);
}
+ /**
+ * Whenever the Secure Setting keeping track of the current tiles changes (or upon start) this
+ * will be called with the new value of the setting.
+ *
+ * This method will do the following:
+ * <ol>
+ * <li>Destroy any existing tile that's not one of the current tiles (in the setting)</li>
+ * <li>Create new tiles for those that don't already exist. If this tiles end up being
+ * not available, they'll also be destroyed.</li>
+ * <li>Save the resolved list of tiles (current tiles that are available) into the setting.
+ * This means that after this call ends, the tiles in the Setting, {@link #mTileSpecs},
+ * and visible tiles ({@link #mTiles}) must match.
+ * </li>
+ * </ol>
+ *
+ * Additionally, if the user has changed, it'll do the following:
+ * <ul>
+ * <li>Change the user for SystemUI tiles: {@link QSTile#userSwitch}.</li>
+ * <li>Destroy any {@link CustomTile} and recreate it for the new user.</li>
+ * </ul>
+ *
+ * This happens in main thread as {@link com.android.systemui.tuner.TunerServiceImpl} dispatches
+ * in main thread.
+ *
+ * @see QSTile#isAvailable
+ */
+ @MainThread
@Override
public void onTuningChanged(String key, String newValue) {
if (!TILES_SETTING.equals(key)) {
@@ -330,34 +360,44 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
mCurrentUser = currentUser;
List<String> currentSpecs = new ArrayList<>(mTileSpecs);
mTileSpecs.clear();
- mTileSpecs.addAll(tileSpecs);
+ mTileSpecs.addAll(newTiles.keySet()); // Only add the valid (available) tiles.
mTiles.clear();
mTiles.putAll(newTiles);
if (newTiles.isEmpty() && !tileSpecs.isEmpty()) {
// If we didn't manage to create any tiles, set it to empty (default)
Log.d(TAG, "No valid tiles on tuning changed. Setting to default.");
- changeTiles(currentSpecs, loadTileSpecs(mContext, ""));
+ changeTilesByUser(currentSpecs, loadTileSpecs(mContext, ""));
} else {
+ String resolvedTiles = TextUtils.join(",", mTileSpecs);
+ if (!resolvedTiles.equals(newValue)) {
+ // If the resolved tiles (those we actually ended up with) are different than
+ // the ones that are in the setting, update the Setting.
+ saveTilesToSettings(mTileSpecs);
+ }
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onTilesChanged();
}
}
}
+ /**
+ * Only use with [CustomTile] if the tile doesn't exist anymore (and therefore doesn't need
+ * its lifecycle terminated).
+ */
@Override
public void removeTile(String spec) {
- changeTileSpecs(tileSpecs-> tileSpecs.remove(spec));
+ mMainExecutor.execute(() -> changeTileSpecs(tileSpecs-> tileSpecs.remove(spec)));
}
/**
* Remove many tiles at once.
*
- * It will only save to settings once (as opposed to {@link QSTileHost#removeTile} called
+ * It will only save to settings once (as opposed to {@link QSTileHost#removeTileByUser} called
* multiple times).
*/
@Override
public void removeTiles(Collection<String> specs) {
- changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs));
+ mMainExecutor.execute(() -> changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs)));
}
@Override
@@ -381,26 +421,29 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
* @param requestPosition -1 for end, 0 for beginning, or X for insertion at position X
*/
public void addTile(String spec, int requestPosition) {
- if (spec.equals("work")) Log.wtfStack(TAG, "Adding work tile");
- changeTileSpecs(tileSpecs -> {
- if (tileSpecs.contains(spec)) return false;
-
- int size = tileSpecs.size();
- if (requestPosition == POSITION_AT_END || requestPosition >= size) {
- tileSpecs.add(spec);
- } else {
- tileSpecs.add(requestPosition, spec);
- }
- return true;
- });
+ mMainExecutor.execute(() ->
+ changeTileSpecs(tileSpecs -> {
+ if (tileSpecs.contains(spec)) return false;
+
+ int size = tileSpecs.size();
+ if (requestPosition == POSITION_AT_END || requestPosition >= size) {
+ tileSpecs.add(spec);
+ } else {
+ tileSpecs.add(requestPosition, spec);
+ }
+ return true;
+ })
+ );
}
- void saveTilesToSettings(List<String> tileSpecs) {
+ @MainThread
+ private void saveTilesToSettings(List<String> tileSpecs) {
mSecureSettings.putStringForUser(TILES_SETTING, TextUtils.join(",", tileSpecs),
null /* tag */, false /* default */, mCurrentUser,
true /* overrideable by restore */);
}
+ @MainThread
private void changeTileSpecs(Predicate<List<String>> changeFunction) {
final String setting = mSecureSettings.getStringForUser(TILES_SETTING, mCurrentUser);
final List<String> tileSpecs = loadTileSpecs(mContext, setting);
@@ -420,29 +463,32 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
*/
public void addTile(ComponentName tile, boolean end) {
String spec = CustomTile.toSpec(tile);
- if (!mTileSpecs.contains(spec)) {
- List<String> newSpecs = new ArrayList<>(mTileSpecs);
- if (end) {
- newSpecs.add(spec);
- } else {
- newSpecs.add(0, spec);
- }
- changeTiles(mTileSpecs, newSpecs);
- }
+ addTile(spec, end ? POSITION_AT_END : 0);
}
- public void removeTile(ComponentName tile) {
- List<String> newSpecs = new ArrayList<>(mTileSpecs);
- newSpecs.remove(CustomTile.toSpec(tile));
- changeTiles(mTileSpecs, newSpecs);
+ /**
+ * This will call through {@link #changeTilesByUser}. It should only be used when a tile is
+ * removed by a <b>user action</b> like {@code adb}.
+ */
+ public void removeTileByUser(ComponentName tile) {
+ mMainExecutor.execute(() -> {
+ List<String> newSpecs = new ArrayList<>(mTileSpecs);
+ if (newSpecs.remove(CustomTile.toSpec(tile))) {
+ changeTilesByUser(mTileSpecs, newSpecs);
+ }
+ });
}
/**
* Change the tiles triggered by the user editing.
* <p>
* This is not called on device start, or on user change.
+ *
+ * {@link android.service.quicksettings.TileService#onTileRemoved} will be called for tiles
+ * that are removed.
*/
- public void changeTiles(List<String> previousTiles, List<String> newTiles) {
+ @MainThread
+ public void changeTilesByUser(List<String> previousTiles, List<String> newTiles) {
final List<String> copy = new ArrayList<>(previousTiles);
final int NP = copy.size();
for (int i = 0; i < NP; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index e52bfbd67275..d84b12c714bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -182,7 +182,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
for (int i = 1; i < mTiles.size() && mTiles.get(i) != null; i++) {
newSpecs.add(mTiles.get(i).spec);
}
- host.changeTiles(mCurrentSpecs, newSpecs);
+ host.changeTilesByUser(mCurrentSpecs, newSpecs);
mCurrentSpecs = newSpecs;
}
@@ -200,7 +200,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
/** */
public void resetTileSpecs(List<String> specs) {
// Notify the host so the tiles get removed callbacks.
- mHost.changeTiles(mCurrentSpecs, specs);
+ mHost.changeTilesByUser(mCurrentSpecs, specs);
setTileSpecs(specs);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
index bd2f64bb9874..6265b3c056e7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
@@ -73,6 +73,7 @@ class TileRequestDialog(
icon = tileData.icon?.loadDrawable(context)?.let {
QSTileImpl.DrawableIcon(it)
} ?: ResourceIcon.get(R.drawable.android)
+ contentDescription = label
}
tile.onStateChanged(state)
tile.post {
@@ -95,4 +96,4 @@ class TileRequestDialog(
val label: CharSequence,
val icon: Icon?
)
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index bf565a8c52e0..cfc57db2eeb8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -289,7 +289,7 @@ public class TileServiceManager {
}
}
- mServices.getHost().removeTile(component);
+ mServices.getHost().removeTile(CustomTile.toSpec(component));
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 89a15f65e98f..82de389060ae 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -843,14 +843,20 @@ public class ScreenshotController {
// The media player creation is slow and needs on the background thread.
return CallbackToFutureAdapter.getFuture((completer) -> {
mBgExecutor.execute(() -> {
- MediaPlayer player = MediaPlayer.create(mContext,
- Uri.fromFile(new File(mContext.getResources().getString(
- com.android.internal.R.string.config_cameraShutterSound))), null,
- new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .build(), AudioSystem.newAudioSessionId());
- completer.set(player);
+ try {
+ MediaPlayer player = MediaPlayer.create(mContext,
+ Uri.fromFile(new File(mContext.getResources().getString(
+ com.android.internal.R.string.config_cameraShutterSound))),
+ null,
+ new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+ .build(), AudioSystem.newAudioSessionId());
+ completer.set(player);
+ } catch (IllegalStateException e) {
+ Log.w(TAG, "Screenshot sound initialization failed", e);
+ completer.set(null);
+ }
});
return "ScreenshotController#loadCameraSound";
});
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
index 8c8f54fe9c3d..ad073c073ed8 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
@@ -49,8 +49,8 @@ class UserFileManagerImpl @Inject constructor(
) : UserFileManager, CoreStartable(context) {
companion object {
private const val FILES = "files"
- private const val SHARED_PREFS = "shared_prefs"
- internal const val ID = "UserFileManager"
+ @VisibleForTesting internal const val SHARED_PREFS = "shared_prefs"
+ @VisibleForTesting internal const val ID = "UserFileManager"
}
private val broadcastReceiver = object : BroadcastReceiver() {
@@ -85,13 +85,15 @@ class UserFileManagerImpl @Inject constructor(
fileName
)
} else {
- Environment.buildPath(
+ val secondaryFile = Environment.buildPath(
context.filesDir,
ID,
userId.toString(),
FILES,
fileName
)
+ ensureParentDirExists(secondaryFile)
+ secondaryFile
}
}
@@ -114,6 +116,7 @@ class UserFileManagerImpl @Inject constructor(
fileName
)
+ ensureParentDirExists(secondaryUserDir)
return context.getSharedPreferences(secondaryUserDir, mode)
}
@@ -141,4 +144,18 @@ class UserFileManagerImpl @Inject constructor(
}
}
}
+
+ /**
+ * Checks to see if parent dir of the file exists. If it does not, we create the parent dirs
+ * recursively.
+ */
+ @VisibleForTesting
+ internal fun ensureParentDirExists(file: File) {
+ val parent = file.parentFile
+ if (!parent.exists()) {
+ if (!parent.mkdirs()) {
+ Log.e(ID, "Could not create parent directory for file: ${file.absolutePath}")
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
index e0997ff0f905..9818af3751a7 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
@@ -25,7 +25,6 @@ import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.PanelView;
import com.android.systemui.statusbar.phone.TapAgainView;
public class NotificationPanelView extends PanelView {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index ba9a908cf183..24448bb0ed2e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -192,8 +192,6 @@ import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.PanelView;
-import com.android.systemui.statusbar.phone.PanelViewController;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.ScrimController;
@@ -1704,10 +1702,17 @@ public final class NotificationPanelViewController extends PanelViewController {
/**
* Animate QS closing by flinging it.
* If QS is expanded, it will collapse into QQS and stop.
+ * If in split shade, it will collapse the whole shade.
*
* @param animateAway Do not stop when QS becomes QQS. Fling until QS isn't visible anymore.
*/
public void animateCloseQs(boolean animateAway) {
+ if (mSplitShadeEnabled) {
+ collapsePanel(
+ /* animate= */true, /* delayed= */false, /* speedUpFactor= */1.0f);
+ return;
+ }
+
if (mQsExpansionAnimator != null) {
if (!mQsAnimatorExpand) {
return;
@@ -3380,19 +3385,11 @@ public final class NotificationPanelViewController extends PanelViewController {
return mQsExpanded;
}
- public boolean isQsDetailShowing() {
- return mQs.isShowingDetail();
- }
-
/** Returns whether the QS customizer is currently active. */
public boolean isQsCustomizing() {
return mQs.isCustomizing();
}
- public void closeQsDetail() {
- mQs.closeDetail();
- }
-
/** Close the QS customizer if it is open. */
public void closeQsCustomizer() {
mQs.closeCustomizer();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/OWNERS b/packages/SystemUI/src/com/android/systemui/shade/OWNERS
index 133711ee5ab2..7dc9dc7efeb7 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/shade/OWNERS
@@ -3,6 +3,7 @@ per-file *Notification* = file:../statusbar/notification/OWNERS
per-file NotificationsQuickSettingsContainer.java = kozynski@google.com, asc@google.com
per-file NotificationsQSContainerController.kt = kozynski@google.com, asc@google.com
+per-file *ShadeHeader* = kozynski@google.com, asc@google.com
per-file NotificationShadeWindowViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com
per-file NotificationShadeWindowView.java = pixel@google.com, cinek@google.com, juliacr@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/shade/PanelView.java
index 45dc943de2f8..1082967d3b5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/PanelView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
import android.content.Context;
import android.content.res.Configuration;
@@ -22,6 +22,10 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+
public abstract class PanelView extends FrameLayout {
public static final boolean DEBUG = false;
public static final String TAG = PanelView.class.getSimpleName();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/PanelViewController.java
index 3a85a3ea6391..229acf4ed061 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/PanelViewController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
@@ -60,7 +60,14 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.stack.AmbientState;
+import com.android.systemui.statusbar.phone.BounceInterpolator;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.time.SystemClock;
@@ -388,7 +395,7 @@ public abstract class PanelViewController {
return Math.abs(yDiff) >= Math.abs(xDiff);
}
- protected void startExpandMotion(float newX, float newY, boolean startTracking,
+ public void startExpandMotion(float newX, float newY, boolean startTracking,
float expandedHeight) {
if (!mHandlingPointerUp && !mStatusBarStateController.isDozing()) {
beginJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 38a208b72edc..f4ca7edb146d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -642,6 +642,8 @@ public class NotificationLockscreenUserManagerImpl implements
// - device keyguard is shown in secure mode;
// - profile is locked with a work challenge.
SparseArray<UserInfo> currentProfiles = getCurrentProfiles();
+ SparseBooleanArray oldPublicModes = mLockscreenPublicMode.clone();
+ SparseBooleanArray oldWorkChallenges = mUsersWithSeparateWorkChallenge.clone();
mUsersWithSeparateWorkChallenge.clear();
for (int i = currentProfiles.size() - 1; i >= 0; i--) {
final int userId = currentProfiles.valueAt(i).id;
@@ -660,7 +662,10 @@ public class NotificationLockscreenUserManagerImpl implements
}
getEntryManager().updateNotifications("NotificationLockscreenUserManager.updatePublicMode");
// TODO(b/234738798): Migrate KeyguardNotificationVisibilityProvider to use this listener
- // notifyNotificationStateChanged();
+ if (!mLockscreenPublicMode.equals(oldPublicModes)
+ || !mUsersWithSeparateWorkChallenge.equals(oldWorkChallenges)) {
+ notifyNotificationStateChanged();
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
index a62a152ab7f4..5351024c2f9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
@@ -24,6 +24,7 @@ import com.android.systemui.statusbar.phone.PhoneStatusBarViewController
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
import com.android.systemui.statusbar.window.StatusBarWindowController
import java.lang.IllegalStateException
import javax.inject.Inject
@@ -34,7 +35,8 @@ import javax.inject.Inject
*/
@CentralSurfacesScope
class StatusBarInitializer @Inject constructor(
- private val windowController: StatusBarWindowController
+ private val windowController: StatusBarWindowController,
+ private val creationListeners: Set<@JvmSuppressWildcards OnStatusBarViewInitializedListener>,
) {
var statusBarViewUpdatedListener: OnStatusBarViewUpdatedListener? = null
@@ -56,6 +58,9 @@ class StatusBarInitializer @Inject constructor(
statusBarFragmentComponent.phoneStatusBarViewController,
statusBarFragmentComponent.phoneStatusBarTransitions
)
+ creationListeners.forEach { listener ->
+ listener.onStatusBarViewInitialized(statusBarFragmentComponent)
+ }
}
override fun onFragmentViewDestroyed(tag: String?, fragment: Fragment?) {
@@ -69,6 +74,17 @@ class StatusBarInitializer @Inject constructor(
.commit()
}
+ interface OnStatusBarViewInitializedListener {
+
+ /**
+ * The status bar view has been initialized.
+ *
+ * @param component Dagger component that is created when the status bar view is created.
+ * Can be used to retrieve dependencies from that scope, including the status bar root view.
+ */
+ fun onStatusBarViewInitialized(component: StatusBarFragmentComponent)
+ }
+
interface OnStatusBarViewUpdatedListener {
fun onStatusBarViewUpdated(
statusBarView: PhoneStatusBarView,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 94341ba4bb19..3c018022085d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1909,6 +1909,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
* @param isEnabled whether the content views should be enabled for accessibility
*/
private void updateContentAccessibilityImportanceForGuts(boolean isEnabled) {
+ updateAccessibilityImportance(isEnabled);
+
if (mChildrenContainer != null) {
updateChildAccessibilityImportance(mChildrenContainer, isEnabled);
}
@@ -1924,6 +1926,15 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
/**
+ * Updates whether this view is important for accessibility based on {@code isEnabled}.
+ */
+ private void updateAccessibilityImportance(boolean isEnabled) {
+ setImportantForAccessibility(isEnabled
+ ? View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
+ : View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ }
+
+ /**
* Updates whether the given childView is important for accessibility based on
* {@code isEnabled}.
*/
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 b8b7ebe0a79c..defbfd8dc8c8 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
@@ -327,6 +327,13 @@ public class NotificationStackScrollLayoutController {
};
/**
+ * Recalculate sensitiveness without animation; called when waking up while keyguard occluded.
+ */
+ public void updateSensitivenessForOccludedWakeup() {
+ mView.updateSensitiveness(false, mLockscreenUserManager.isAnyProfilePublicMode());
+ }
+
+ /**
* Set the overexpansion of the panel to be applied to the view.
*/
public void setOverExpansion(float overExpansion) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 8782be50794f..9070eadd9944 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -428,7 +428,7 @@ public class AutoTileManager implements UserAwareController {
if (isSafetyCenterEnabled && !mAutoTracker.isAdded(mSafetySpec)) {
initSafetyTile();
} else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(mSafetySpec)) {
- mHost.removeTile(CustomTile.getComponentFromSpec(mSafetySpec));
+ mHost.removeTile(mSafetySpec);
mHost.unmarkTileAsAutoAdded(mSafetySpec);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 53b5b0caf257..f4b7772a1453 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -57,10 +57,8 @@ import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.qs.QSPanelController;
import com.android.systemui.shade.NotificationPanelView;
import com.android.systemui.shade.NotificationPanelViewController;
-import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
@@ -91,19 +89,16 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final AssistManager mAssistManager;
private final DozeServiceHost mDozeServiceHost;
- private final SysuiStatusBarStateController mStatusBarStateController;
- private final NotificationShadeWindowView mNotificationShadeWindowView;
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
private final PowerManager mPowerManager;
private final VibratorHelper mVibratorHelper;
private final Optional<Vibrator> mVibratorOptional;
- private final LightBarController mLightBarController;
private final DisableFlagsLogger mDisableFlagsLogger;
private final int mDisplayId;
private final boolean mVibrateOnOpening;
private final VibrationEffect mCameraLaunchGestureVibrationEffect;
-
+ private final SystemBarAttributesListener mSystemBarAttributesListener;
private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
@@ -126,16 +121,14 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
AssistManager assistManager,
DozeServiceHost dozeServiceHost,
- SysuiStatusBarStateController statusBarStateController,
- NotificationShadeWindowView notificationShadeWindowView,
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
PowerManager powerManager,
VibratorHelper vibratorHelper,
Optional<Vibrator> vibratorOptional,
- LightBarController lightBarController,
DisableFlagsLogger disableFlagsLogger,
- @DisplayId int displayId) {
+ @DisplayId int displayId,
+ SystemBarAttributesListener systemBarAttributesListener) {
mCentralSurfaces = centralSurfaces;
mContext = context;
@@ -152,20 +145,18 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mAssistManager = assistManager;
mDozeServiceHost = dozeServiceHost;
- mStatusBarStateController = statusBarStateController;
- mNotificationShadeWindowView = notificationShadeWindowView;
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
mPowerManager = powerManager;
mVibratorHelper = vibratorHelper;
mVibratorOptional = vibratorOptional;
- mLightBarController = lightBarController;
mDisableFlagsLogger = disableFlagsLogger;
mDisplayId = displayId;
mVibrateOnOpening = resources.getBoolean(R.bool.config_vibrateOnIconAnimation);
mCameraLaunchGestureVibrationEffect = getCameraGestureVibrationEffect(
mVibratorOptional, resources);
+ mSystemBarAttributesListener = systemBarAttributesListener;
}
@Override
@@ -191,7 +182,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
public void remQsTile(ComponentName tile) {
QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
if (qsPanelController != null && qsPanelController.getHost() != null) {
- qsPanelController.getHost().removeTile(tile);
+ qsPanelController.getHost().removeTileByUser(tile);
}
}
@@ -472,14 +463,18 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
if (displayId != mDisplayId) {
return;
}
- boolean barModeChanged = mCentralSurfaces.setAppearance(appearance);
-
- mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged,
- mCentralSurfaces.getBarMode(), navbarColorManagedByIme);
-
- mCentralSurfaces.updateBubblesVisibility();
- mStatusBarStateController.setSystemBarAttributes(
- appearance, behavior, requestedVisibilities, packageName);
+ // SystemBarAttributesListener should __always__ be the top-level listener for system bar
+ // attributes changed.
+ mSystemBarAttributesListener.onSystemBarAttributesChanged(
+ displayId,
+ appearance,
+ appearanceRegions,
+ navbarColorManagedByIme,
+ behavior,
+ requestedVisibilities,
+ packageName,
+ letterboxDetails
+ );
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index dbeb4c467fcb..c5aa512f5717 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -3308,11 +3308,7 @@ public class CentralSurfacesImpl extends CoreStartable implements
return true;
}
if (mNotificationPanelViewController.isQsExpanded()) {
- if (mNotificationPanelViewController.isQsDetailShowing()) {
- mNotificationPanelViewController.closeQsDetail();
- } else {
mNotificationPanelViewController.animateCloseQs(false /* animateAway */);
- }
return true;
}
if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
@@ -3648,6 +3644,18 @@ public class CentralSurfacesImpl extends CoreStartable implements
public void onFinishedWakingUp() {
mWakeUpCoordinator.setFullyAwake(true);
mWakeUpCoordinator.setWakingUp(false);
+ if (mKeyguardStateController.isOccluded()
+ && !mDozeParameters.canControlUnlockedScreenOff()) {
+ // When the keyguard is occluded we don't use the KEYGUARD state which would
+ // normally cause these redaction updates. If AOD is on, the KEYGUARD state is used
+ // to show the doze, AND UnlockedScreenOffAnimationController.onFinishedWakingUp()
+ // would force a KEYGUARD state that would take care of recalculating redaction.
+ // So if AOD is off or unsupported we need to trigger these updates at screen on
+ // when the keyguard is occluded.
+ mLockscreenUserManager.updatePublicMode();
+ mNotificationPanelViewController.getNotificationStackScrollLayoutController()
+ .updateSensitivenessForOccludedWakeup();
+ }
if (mLaunchCameraWhenFinishedWaking) {
mNotificationPanelViewController.launchCamera(mLastCameraLaunchSource);
mLaunchCameraWhenFinishedWaking = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
new file mode 100644
index 000000000000..70ec13b14abd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
@@ -0,0 +1,227 @@
+/*
+ * 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.statusbar.phone
+
+import android.annotation.ColorInt
+import android.graphics.Color
+import android.graphics.Rect
+import android.view.InsetsFlags
+import android.view.ViewDebug
+import android.view.WindowInsetsController
+import android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS
+import android.view.WindowInsetsController.Appearance
+import com.android.internal.statusbar.LetterboxDetails
+import com.android.internal.util.ContrastColorUtil
+import com.android.internal.view.AppearanceRegion
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewInitializedListener
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
+import java.io.PrintWriter
+import java.util.Arrays
+import javax.inject.Inject
+
+class LetterboxAppearance(
+ @Appearance val appearance: Int,
+ val appearanceRegions: Array<AppearanceRegion>
+)
+
+/**
+ * Responsible for calculating the [Appearance] and [AppearanceRegion] for the status bar when apps
+ * are letterboxed.
+ */
+@CentralSurfacesScope
+class LetterboxAppearanceCalculator
+@Inject
+constructor(
+ private val lightBarController: LightBarController,
+ private val dumpManager: DumpManager,
+) : OnStatusBarViewInitializedListener, CentralSurfacesComponent.Startable {
+
+ private var statusBarBoundsProvider: StatusBarBoundsProvider? = null
+
+ override fun start() {
+ dumpManager.registerDumpable(javaClass.simpleName) { printWriter, _ -> dump(printWriter) }
+ }
+
+ override fun stop() {
+ dumpManager.unregisterDumpable(javaClass.simpleName)
+ }
+
+ private var lastAppearance: Int? = null
+ private var lastAppearanceRegions: Array<AppearanceRegion>? = null
+ private var lastLetterboxes: Array<LetterboxDetails>? = null
+ private var lastLetterboxAppearance: LetterboxAppearance? = null
+
+ fun getLetterboxAppearance(
+ @Appearance originalAppearance: Int,
+ originalAppearanceRegions: Array<AppearanceRegion>,
+ letterboxes: Array<LetterboxDetails>
+ ): LetterboxAppearance {
+ lastAppearance = originalAppearance
+ lastAppearanceRegions = originalAppearanceRegions
+ lastLetterboxes = letterboxes
+ return getLetterboxAppearanceInternal(
+ letterboxes, originalAppearance, originalAppearanceRegions)
+ .also { lastLetterboxAppearance = it }
+ }
+
+ private fun getLetterboxAppearanceInternal(
+ letterboxes: Array<LetterboxDetails>,
+ originalAppearance: Int,
+ originalAppearanceRegions: Array<AppearanceRegion>
+ ): LetterboxAppearance {
+ if (isScrimNeeded(letterboxes)) {
+ return originalAppearanceWithScrim(originalAppearance, originalAppearanceRegions)
+ }
+ val appearance = appearanceWithoutScrim(originalAppearance)
+ val appearanceRegions = getAppearanceRegions(originalAppearanceRegions, letterboxes)
+ return LetterboxAppearance(appearance, appearanceRegions.toTypedArray())
+ }
+
+ private fun isScrimNeeded(letterboxes: Array<LetterboxDetails>): Boolean {
+ if (isOuterLetterboxMultiColored()) {
+ return true
+ }
+ return letterboxes.any { letterbox ->
+ letterbox.letterboxInnerBounds.overlapsWith(getStartSideIconBounds()) ||
+ letterbox.letterboxInnerBounds.overlapsWith(getEndSideIconsBounds())
+ }
+ }
+
+ private fun getAppearanceRegions(
+ originalAppearanceRegions: Array<AppearanceRegion>,
+ letterboxes: Array<LetterboxDetails>
+ ): List<AppearanceRegion> {
+ return sanitizeAppearanceRegions(originalAppearanceRegions, letterboxes) +
+ getAllOuterAppearanceRegions(letterboxes)
+ }
+
+ private fun sanitizeAppearanceRegions(
+ originalAppearanceRegions: Array<AppearanceRegion>,
+ letterboxes: Array<LetterboxDetails>
+ ): List<AppearanceRegion> =
+ originalAppearanceRegions.map { appearanceRegion ->
+ val matchingLetterbox =
+ letterboxes.find { it.letterboxFullBounds == appearanceRegion.bounds }
+ if (matchingLetterbox == null) {
+ appearanceRegion
+ } else {
+ // When WindowManager sends appearance regions for an app, it sends them for the
+ // full bounds of its window.
+ // Here we want the bounds to be only for the inner bounds of the letterboxed app.
+ AppearanceRegion(
+ appearanceRegion.appearance, matchingLetterbox.letterboxInnerBounds)
+ }
+ }
+
+ private fun originalAppearanceWithScrim(
+ @Appearance originalAppearance: Int,
+ originalAppearanceRegions: Array<AppearanceRegion>
+ ): LetterboxAppearance {
+ return LetterboxAppearance(
+ originalAppearance or APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS,
+ originalAppearanceRegions)
+ }
+
+ @Appearance
+ private fun appearanceWithoutScrim(@Appearance originalAppearance: Int): Int =
+ originalAppearance and APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS.inv()
+
+ private fun getAllOuterAppearanceRegions(
+ letterboxes: Array<LetterboxDetails>
+ ): List<AppearanceRegion> = letterboxes.map(this::getOuterAppearanceRegions).flatten()
+
+ private fun getOuterAppearanceRegions(
+ letterboxDetails: LetterboxDetails
+ ): List<AppearanceRegion> {
+ @Appearance val outerAppearance = getOuterAppearance()
+ return getVisibleOuterBounds(letterboxDetails).map { bounds ->
+ AppearanceRegion(outerAppearance, bounds)
+ }
+ }
+
+ private fun getVisibleOuterBounds(letterboxDetails: LetterboxDetails): List<Rect> {
+ val inner = letterboxDetails.letterboxInnerBounds
+ val outer = letterboxDetails.letterboxFullBounds
+ val top = Rect(outer.left, outer.top, outer.right, inner.top)
+ val left = Rect(outer.left, outer.top, inner.left, outer.bottom)
+ val right = Rect(inner.right, outer.top, outer.right, outer.bottom)
+ val bottom = Rect(outer.left, inner.bottom, outer.right, outer.bottom)
+ return listOf(left, top, right, bottom).filter { !it.isEmpty }
+ }
+
+ @Appearance
+ private fun getOuterAppearance(): Int {
+ val backgroundColor = outerLetterboxBackgroundColor()
+ val darkAppearanceContrast =
+ ContrastColorUtil.calculateContrast(
+ lightBarController.darkAppearanceIconColor, backgroundColor)
+ val lightAppearanceContrast =
+ ContrastColorUtil.calculateContrast(
+ lightBarController.lightAppearanceIconColor, backgroundColor)
+ return if (lightAppearanceContrast > darkAppearanceContrast) {
+ WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
+ } else {
+ 0 // APPEARANCE_DEFAULT
+ }
+ }
+
+ @ColorInt
+ private fun outerLetterboxBackgroundColor(): Int {
+ // TODO(b/238607453): retrieve this information from WindowManager.
+ return Color.BLACK
+ }
+
+ private fun isOuterLetterboxMultiColored(): Boolean {
+ // TODO(b/238607453): retrieve this information from WindowManager.
+ return false
+ }
+
+ private fun getEndSideIconsBounds(): Rect {
+ return statusBarBoundsProvider?.visibleEndSideBounds ?: Rect()
+ }
+
+ private fun getStartSideIconBounds(): Rect {
+ return statusBarBoundsProvider?.visibleStartSideBounds ?: Rect()
+ }
+
+ override fun onStatusBarViewInitialized(component: StatusBarFragmentComponent) {
+ statusBarBoundsProvider = component.boundsProvider
+ }
+
+ private fun Rect.overlapsWith(other: Rect): Boolean {
+ if (this.contains(other) || other.contains(this)) {
+ return false
+ }
+ return this.intersect(other)
+ }
+
+ private fun dump(printWriter: PrintWriter) {
+ printWriter.println(
+ """
+ lastAppearance: ${lastAppearance?.toAppearanceString()}
+ lastAppearanceRegion: ${Arrays.toString(lastAppearanceRegions)},
+ lastLetterboxes: ${Arrays.toString(lastLetterboxes)},
+ lastLetterboxAppearance: $lastLetterboxAppearance
+ """.trimIndent())
+ }
+}
+
+private fun Int.toAppearanceString(): String =
+ ViewDebug.flagsToString(InsetsFlags::class.java, "appearance", this)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 2c57328174e8..4d1454232853 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -23,8 +23,8 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import android.annotation.ColorInt;
import android.content.Context;
-import android.graphics.Color;
import android.graphics.Rect;
import android.view.InsetsFlags;
import android.view.ViewDebug;
@@ -63,7 +63,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
private int mStatusBarMode;
private int mNavigationBarMode;
private int mNavigationMode;
- private final Color mDarkModeColor;
+ private final int mDarkIconColor;
+ private final int mLightIconColor;
/**
* Whether the navigation bar should be light factoring in already how much alpha the scrim has
@@ -94,7 +95,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
BatteryController batteryController,
NavigationModeController navModeController,
DumpManager dumpManager) {
- mDarkModeColor = Color.valueOf(ctx.getColor(R.color.dark_mode_icon_color_single_tone));
+ mDarkIconColor = ctx.getColor(R.color.dark_mode_icon_color_single_tone);
+ mLightIconColor = ctx.getColor(R.color.light_mode_icon_color_single_tone);
mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher;
mBatteryController = batteryController;
mBatteryController.addCallback(this);
@@ -107,6 +109,16 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
}
}
+ @ColorInt
+ int getLightAppearanceIconColor() {
+ return mDarkIconColor;
+ }
+
+ @ColorInt
+ int getDarkAppearanceIconColor() {
+ return mLightIconColor;
+ }
+
public void setNavigationBar(LightBarTransitionsController navigationBar) {
mNavigationBarController = navigationBar;
updateNavigation();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
new file mode 100644
index 000000000000..a0415f2f3d7c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
@@ -0,0 +1,158 @@
+/*
+ * 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.statusbar.phone
+
+import android.view.InsetsVisibilities
+import android.view.WindowInsetsController.Appearance
+import android.view.WindowInsetsController.Behavior
+import com.android.internal.statusbar.LetterboxDetails
+import com.android.internal.view.AppearanceRegion
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
+import java.io.PrintWriter
+import javax.inject.Inject
+
+/**
+ * Top-level listener of system attributes changed. This class is __always the first__ one to be
+ * notified about changes.
+ *
+ * It is responsible for modifying any attributes if necessary, and then notifying the other
+ * downstream listeners.
+ */
+@CentralSurfacesScope
+class SystemBarAttributesListener
+@Inject
+internal constructor(
+ private val centralSurfaces: CentralSurfaces,
+ private val featureFlags: FeatureFlags,
+ private val letterboxAppearanceCalculator: LetterboxAppearanceCalculator,
+ private val statusBarStateController: SysuiStatusBarStateController,
+ private val lightBarController: LightBarController,
+ private val dumpManager: DumpManager,
+) : CentralSurfacesComponent.Startable, StatusBarBoundsProvider.BoundsChangeListener {
+
+ private var lastLetterboxAppearance: LetterboxAppearance? = null
+ private var lastSystemBarAttributesParams: SystemBarAttributesParams? = null
+
+ override fun start() {
+ dumpManager.registerDumpable(javaClass.simpleName, this::dump)
+ }
+
+ override fun stop() {
+ dumpManager.unregisterDumpable(javaClass.simpleName)
+ }
+
+ override fun onStatusBarBoundsChanged() {
+ val params = lastSystemBarAttributesParams
+ if (params != null && shouldUseLetterboxAppearance(params.letterboxesArray)) {
+ onSystemBarAttributesChanged(
+ params.displayId,
+ params.appearance,
+ params.appearanceRegionsArray,
+ params.navbarColorManagedByIme,
+ params.behavior,
+ params.requestedVisibilities,
+ params.packageName,
+ params.letterboxesArray)
+ }
+ }
+
+ fun onSystemBarAttributesChanged(
+ displayId: Int,
+ @Appearance originalAppearance: Int,
+ originalAppearanceRegions: Array<AppearanceRegion>,
+ navbarColorManagedByIme: Boolean,
+ @Behavior behavior: Int,
+ requestedVisibilities: InsetsVisibilities,
+ packageName: String,
+ letterboxDetails: Array<LetterboxDetails>
+ ) {
+ lastSystemBarAttributesParams =
+ SystemBarAttributesParams(
+ displayId,
+ originalAppearance,
+ originalAppearanceRegions.toList(),
+ navbarColorManagedByIme,
+ behavior,
+ requestedVisibilities,
+ packageName,
+ letterboxDetails.toList())
+
+ val (appearance, appearanceRegions) =
+ modifyAppearanceIfNeeded(
+ originalAppearance, originalAppearanceRegions, letterboxDetails)
+
+ val barModeChanged = centralSurfaces.setAppearance(appearance)
+
+ lightBarController.onStatusBarAppearanceChanged(
+ appearanceRegions, barModeChanged, centralSurfaces.barMode, navbarColorManagedByIme)
+
+ centralSurfaces.updateBubblesVisibility()
+ statusBarStateController.setSystemBarAttributes(
+ appearance, behavior, requestedVisibilities, packageName)
+ }
+
+ private fun modifyAppearanceIfNeeded(
+ appearance: Int,
+ appearanceRegions: Array<AppearanceRegion>,
+ letterboxDetails: Array<LetterboxDetails>
+ ): Pair<Int, Array<AppearanceRegion>> =
+ if (shouldUseLetterboxAppearance(letterboxDetails)) {
+ val letterboxAppearance =
+ letterboxAppearanceCalculator.getLetterboxAppearance(
+ appearance, appearanceRegions, letterboxDetails)
+ lastLetterboxAppearance = letterboxAppearance
+ Pair(letterboxAppearance.appearance, letterboxAppearance.appearanceRegions)
+ } else {
+ lastLetterboxAppearance = null
+ Pair(appearance, appearanceRegions)
+ }
+
+ private fun shouldUseLetterboxAppearance(letterboxDetails: Array<LetterboxDetails>) =
+ isLetterboxAppearanceFlagEnabled() && letterboxDetails.isNotEmpty()
+
+ private fun isLetterboxAppearanceFlagEnabled() =
+ featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)
+
+ private fun dump(printWriter: PrintWriter, strings: Array<String>) {
+ printWriter.println("lastSystemBarAttributesParams: $lastSystemBarAttributesParams")
+ printWriter.println("lastLetterboxAppearance: $lastLetterboxAppearance")
+ printWriter.println("letterbox appearance flag: ${isLetterboxAppearanceFlagEnabled()}")
+ }
+}
+
+/**
+ * Keeps track of the parameters passed in
+ * [SystemBarAttributesListener.onSystemBarAttributesChanged].
+ */
+private data class SystemBarAttributesParams(
+ val displayId: Int,
+ @Appearance val appearance: Int,
+ val appearanceRegions: List<AppearanceRegion>,
+ val navbarColorManagedByIme: Boolean,
+ @Behavior val behavior: Int,
+ val requestedVisibilities: InsetsVisibilities,
+ val packageName: String,
+ val letterboxes: List<LetterboxDetails>,
+) {
+ val letterboxesArray = letterboxes.toTypedArray()
+ val appearanceRegionsArray = appearanceRegions.toTypedArray()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
index 21e5ad5778b1..d57e6a791489 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
@@ -16,13 +16,28 @@
package com.android.systemui.statusbar.phone.dagger;
+import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator;
+import com.android.systemui.statusbar.phone.SystemBarAttributesListener;
+
import java.util.Set;
+import dagger.Binds;
import dagger.Module;
+import dagger.multibindings.IntoSet;
import dagger.multibindings.Multibinds;
@Module
interface CentralSurfacesStartableModule {
@Multibinds
Set<CentralSurfacesComponent.Startable> multibindStartables();
+
+ @Binds
+ @IntoSet
+ CentralSurfacesComponent.Startable letterboxAppearanceCalculator(
+ LetterboxAppearanceCalculator letterboxAppearanceCalculator);
+
+ @Binds
+ @IntoSet
+ CentralSurfacesComponent.Startable sysBarAttrsListener(
+ SystemBarAttributesListener systemBarAttributesListener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index f02196cd44e3..200f45f7f8a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -45,15 +45,19 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.OperatorNameViewController;
+import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewInitializedListener;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
import com.android.systemui.statusbar.phone.StatusIconContainer;
+import com.android.systemui.statusbar.phone.SystemBarAttributesListener;
import com.android.systemui.statusbar.phone.TapAgainView;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
@@ -71,8 +75,10 @@ import java.util.concurrent.Executor;
import javax.inject.Named;
+import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.IntoSet;
@Module(subcomponents = StatusBarFragmentComponent.class)
public abstract class StatusBarViewModule {
@@ -247,6 +253,17 @@ public abstract class StatusBarViewModule {
return notificationShadeWindowView.findViewById(R.id.notification_container_parent);
}
+ @Binds
+ @IntoSet
+ abstract OnStatusBarViewInitializedListener statusBarInitializedListener(
+ LetterboxAppearanceCalculator letterboxAppearanceCalculator
+ );
+
+ @Binds
+ @IntoSet
+ abstract StatusBarBoundsProvider.BoundsChangeListener sysBarAttrsListenerAsBoundsListener(
+ SystemBarAttributesListener systemBarAttributesListener);
+
/**
* Creates a new {@link CollapsedStatusBarFragment}.
*
diff --git a/apct-tests/perftests/core/src/android/view/HandwritingImeService.java b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
index 27cb16e9a19f..bd6cf9a1d101 100644
--- a/apct-tests/perftests/core/src/android/view/HandwritingImeService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
@@ -14,19 +14,17 @@
* limitations under the License.
*/
-package android.view;
+package com.android.systemui.statusbar.pipeline
-import android.content.ComponentName;
-import android.inputmethodservice.InputMethodService;
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
-public class HandwritingImeService extends InputMethodService {
- private static final String PACKAGE_NAME = "com.android.perftests.core";
-
- private static ComponentName getComponentName() {
- return new ComponentName(PACKAGE_NAME, HandwritingImeService.class.getName());
- }
-
- static String getImeId() {
- return getComponentName().flattenToShortString();
- }
-}
+/**
+ * A processor that transforms raw connectivity information that we get from callbacks and turns it
+ * into a list of displayable connectivity information.
+ *
+ * This will be used for the new status bar pipeline to calculate the list of icons that should be
+ * displayed in the RHS of the status bar.
+ */
+@SysUISingleton
+class ConnectivityInfoProcessor @Inject constructor()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
new file mode 100644
index 000000000000..734bd2d8e5b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.statusbar.pipeline.dagger
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.pipeline.ConnectivityInfoProcessor
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import java.util.Optional
+
+@Module
+class StatusBarPipelineModule {
+ @Provides
+ @SysUISingleton
+ fun provideConnectivityInfoProcessor(
+ featureFlags: FeatureFlags,
+ processorLazy: Lazy<ConnectivityInfoProcessor>
+ ): Optional<ConnectivityInfoProcessor> {
+ return if (featureFlags.isEnabled(Flags.NEW_STATUS_BAR_PIPELINE)) {
+ Optional.of(processorLazy.get())
+ } else {
+ Optional.empty()
+ }
+ }
+}
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 2e6664820fa7..dfcdaefd8e03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -62,7 +62,6 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.LatencyTracker;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.users.UserCreatingDialog;
-import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.GuestResetOrExitSessionReceiver;
import com.android.systemui.GuestResumeSessionReceiver;
@@ -167,6 +166,7 @@ public class UserSwitcherController implements Dumpable {
private final AtomicBoolean mGuestIsResetting;
private final AtomicBoolean mGuestCreationScheduled;
private FalsingManager mFalsingManager;
+ @Nullable
private View mView;
private String mCreateSupervisedUserPackage;
private GlobalSettings mGlobalSettings;
@@ -572,9 +572,11 @@ public class UserSwitcherController implements Dumpable {
protected void switchToUserId(int id) {
try {
- mInteractionJankMonitor.begin(InteractionJankMonitor.Configuration.Builder
- .withView(InteractionJankMonitor.CUJ_USER_SWITCH, mView)
- .setTimeout(MULTI_USER_JOURNEY_TIMEOUT));
+ if (mView != null) {
+ mInteractionJankMonitor.begin(InteractionJankMonitor.Configuration.Builder
+ .withView(InteractionJankMonitor.CUJ_USER_SWITCH, mView)
+ .setTimeout(MULTI_USER_JOURNEY_TIMEOUT));
+ }
mLatencyTracker.onActionStart(LatencyTracker.ACTION_USER_SWITCH);
pauseRefreshUsers();
mActivityManager.switchUser(id);
@@ -936,15 +938,17 @@ public class UserSwitcherController implements Dumpable {
guestCreationProgressDialog.show();
// userManager.createGuest will block the thread so post is needed for the dialog to show
- ThreadUtils.postOnMainThread(() -> {
+ mBgExecutor.execute(() -> {
final int guestId = createGuest();
- guestCreationProgressDialog.dismiss();
- if (guestId == UserHandle.USER_NULL) {
- Toast.makeText(mContext,
- com.android.settingslib.R.string.add_guest_failed,
- Toast.LENGTH_SHORT).show();
- }
- callback.accept(guestId);
+ mUiExecutor.execute(() -> {
+ guestCreationProgressDialog.dismiss();
+ if (guestId == UserHandle.USER_NULL) {
+ Toast.makeText(mContext,
+ com.android.settingslib.R.string.add_guest_failed,
+ Toast.LENGTH_SHORT).show();
+ }
+ callback.accept(guestId);
+ });
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserCreator.java b/packages/SystemUI/src/com/android/systemui/user/UserCreator.java
deleted file mode 100644
index 0686071c1718..000000000000
--- a/packages/SystemUI/src/com/android/systemui/user/UserCreator.java
+++ /dev/null
@@ -1,85 +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.systemui.user;
-
-import android.app.Dialog;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.os.UserManager;
-
-import com.android.internal.util.UserIcons;
-import com.android.settingslib.users.UserCreatingDialog;
-import com.android.settingslib.utils.ThreadUtils;
-
-import java.util.function.Consumer;
-
-import javax.inject.Inject;
-
-/**
- * A class to do the user creation process. It shows a progress dialog, and manages the user
- * creation
- */
-public class UserCreator {
-
- private final Context mContext;
- private final UserManager mUserManager;
-
- @Inject
- public UserCreator(Context context, UserManager userManager) {
- mContext = context;
- mUserManager = userManager;
- }
-
- /**
- * Shows a progress dialog then starts the user creation process on the main thread.
- *
- * @param successCallback is called when the user creation is successful.
- * @param errorCallback is called when userManager.createUser returns null.
- * (Exceptions are not handled by this class)
- */
- public void createUser(String userName, Drawable userIcon, Consumer<UserInfo> successCallback,
- Runnable errorCallback) {
-
- Dialog userCreationProgressDialog = new UserCreatingDialog(mContext);
- userCreationProgressDialog.show();
-
- // userManager.createUser will block the thread so post is needed for the dialog to show
- ThreadUtils.postOnMainThread(() -> {
- UserInfo user =
- mUserManager.createUser(userName, UserManager.USER_TYPE_FULL_SECONDARY, 0);
- if (user == null) {
- // Couldn't create user for some reason
- userCreationProgressDialog.dismiss();
- errorCallback.run();
- return;
- }
-
- Drawable newUserIcon = userIcon;
- Resources res = mContext.getResources();
- if (newUserIcon == null) {
- newUserIcon = UserIcons.getDefaultUserIcon(res, user.id, false);
- }
- mUserManager.setUserIcon(
- user.id, UserIcons.convertToBitmapAtUserIconSize(res, newUserIcon));
-
- userCreationProgressDialog.dismiss();
- successCallback.accept(user);
- });
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserCreator.kt b/packages/SystemUI/src/com/android/systemui/user/UserCreator.kt
new file mode 100644
index 000000000000..dcbbe7441922
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/user/UserCreator.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.systemui.user
+
+import android.app.Dialog
+import android.content.Context
+import android.content.pm.UserInfo
+import android.graphics.drawable.Drawable
+import android.os.UserManager
+import com.android.internal.util.UserIcons
+import com.android.settingslib.users.UserCreatingDialog
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import java.util.concurrent.Executor
+import java.util.function.Consumer
+import javax.inject.Inject
+
+/**
+ * A class to do the user creation process. It shows a progress dialog, and manages the user
+ * creation
+ */
+class UserCreator @Inject constructor(
+ private val context: Context,
+ private val userManager: UserManager,
+ @Main private val mainExecutor: Executor,
+ @Background private val bgExecutor: Executor
+) {
+ /**
+ * Shows a progress dialog then starts the user creation process on the main thread.
+ *
+ * @param successCallback is called when the user creation is successful.
+ * @param errorCallback is called when userManager.createUser returns null.
+ * (Exceptions are not handled by this class)
+ */
+ fun createUser(
+ userName: String?,
+ userIcon: Drawable?,
+ successCallback: Consumer<UserInfo?>,
+ errorCallback: Runnable
+ ) {
+ val userCreationProgressDialog: Dialog = UserCreatingDialog(context)
+ userCreationProgressDialog.show()
+
+ // userManager.createUser will block the thread so post is needed for the dialog to show
+ bgExecutor.execute {
+ val user = userManager.createUser(userName, UserManager.USER_TYPE_FULL_SECONDARY, 0)
+ mainExecutor.execute main@{
+ if (user == null) {
+ // Couldn't create user for some reason
+ userCreationProgressDialog.dismiss()
+ errorCallback.run()
+ return@main
+ }
+ bgExecutor.execute {
+ var newUserIcon = userIcon
+ val res = context.resources
+ if (newUserIcon == null) {
+ newUserIcon = UserIcons.getDefaultUserIcon(res, user.id, false)
+ }
+ userManager.setUserIcon(
+ user.id, UserIcons.convertToBitmapAtUserIconSize(res, newUserIcon))
+ }
+ userCreationProgressDialog.dismiss()
+ successCallback.accept(user)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
new file mode 100644
index 000000000000..1e4a9e42cce1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
@@ -0,0 +1,84 @@
+/*
+ * 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.controls.management
+
+import android.content.ComponentName
+import android.content.res.Resources
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import androidx.test.filters.SmallTest
+import com.android.settingslib.core.lifecycle.Lifecycle
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.controls.ControlsServiceInfo
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class AppAdapterTest : SysuiTestCase() {
+ private val fakeSystemClock = FakeSystemClock()
+ private val backgroundExecutor = FakeExecutor(fakeSystemClock)
+ private val uiExecutor = FakeExecutor(fakeSystemClock)
+ @Mock lateinit var lifecycle: Lifecycle
+ @Mock lateinit var controlsListingController: ControlsListingController
+ @Mock lateinit var layoutInflater: LayoutInflater
+ @Mock lateinit var onAppSelected: (ComponentName?) -> Unit
+ @Mock lateinit var favoritesRenderer: FavoritesRenderer
+ val resources: Resources = context.resources
+ lateinit var adapter: AppAdapter
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ adapter = AppAdapter(backgroundExecutor,
+ uiExecutor,
+ lifecycle,
+ controlsListingController,
+ layoutInflater,
+ onAppSelected,
+ favoritesRenderer,
+ resources)
+ }
+
+ @Test
+ fun testOnServicesUpdated_nullLoadLabel() {
+ val captor = ArgumentCaptor
+ .forClass(ControlsListingController.ControlsListingCallback::class.java)
+ val controlsServiceInfo = mock(ControlsServiceInfo::class.java)
+ val serviceInfo = listOf(controlsServiceInfo)
+ `when`(controlsServiceInfo.loadLabel()).thenReturn(null)
+ verify(controlsListingController).observe(any(Lifecycle::class.java), captor.capture())
+
+ captor.value.onServicesUpdated(serviceInfo)
+ backgroundExecutor.runAllReady()
+ uiExecutor.runAllReady()
+
+ assertThat(adapter.itemCount).isEqualTo(serviceInfo.size)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index d414660018a8..533c231f68a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -233,46 +233,29 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
}
@Test
- public void onStart_isBroadcasting_verifyRegisterLeBroadcastServiceCallBack() {
+ public void whenBroadcasting_verifyLeBroadcastServiceCallBackIsRegisteredAndUnregistered() {
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
mLocalBluetoothLeBroadcast);
mIsBroadcasting = true;
mMediaOutputBaseDialogImpl.onStart();
-
verify(mLocalBluetoothLeBroadcast).registerServiceCallBack(any(), any());
- }
-
- @Test
- public void onStart_notBroadcasting_noRegisterLeBroadcastServiceCallBack() {
- when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
- mLocalBluetoothLeBroadcast);
- mIsBroadcasting = false;
-
- mMediaOutputBaseDialogImpl.onStart();
-
- verify(mLocalBluetoothLeBroadcast, never()).registerServiceCallBack(any(), any());
- }
-
- @Test
- public void onStart_isBroadcasting_verifyUnregisterLeBroadcastServiceCallBack() {
- when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
- mLocalBluetoothLeBroadcast);
- mIsBroadcasting = true;
mMediaOutputBaseDialogImpl.onStop();
-
verify(mLocalBluetoothLeBroadcast).unregisterServiceCallBack(any());
}
@Test
- public void onStop_notBroadcasting_noUnregisterLeBroadcastServiceCallBack() {
+ public void
+ whenNotBroadcasting_verifyLeBroadcastServiceCallBackIsNotRegisteredOrUnregistered() {
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
mLocalBluetoothLeBroadcast);
mIsBroadcasting = false;
+ mMediaOutputBaseDialogImpl.onStart();
mMediaOutputBaseDialogImpl.onStop();
+ verify(mLocalBluetoothLeBroadcast, never()).registerServiceCallBack(any(), any());
verify(mLocalBluetoothLeBroadcast, never()).unregisterServiceCallBack(any());
}
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 664af75a6529..32c66d25d4aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -32,8 +32,6 @@ import android.app.Fragment;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
@@ -42,36 +40,23 @@ import android.view.ViewGroup;
import androidx.test.filters.SmallTest;
-import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.R;
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.animation.ShadeInterpolation;
-import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.dagger.QSFragmentComponent;
-import com.android.systemui.qs.external.CustomTileStatePersister;
-import com.android.systemui.qs.external.TileLifecycleManager;
import com.android.systemui.qs.external.TileServiceRequestController;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSFactoryImpl;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
-import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.animation.UniqueObjectHostView;
-import com.android.systemui.util.settings.SecureSettings;
import org.junit.Before;
import org.junit.Test;
@@ -79,8 +64,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.Optional;
-
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
@@ -125,34 +108,11 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
mFragments.dispatchResume();
processAllMessages();
- QSTileHost host =
- new QSTileHost(
- mContext,
- mock(StatusBarIconController.class),
- mock(QSFactoryImpl.class),
- new Handler(),
- Looper.myLooper(),
- mock(PluginManager.class),
- mock(TunerService.class),
- () -> mock(AutoTileManager.class),
- mock(DumpManager.class),
- mock(BroadcastDispatcher.class),
- Optional.of(mock(CentralSurfaces.class)),
- mock(QSLogger.class),
- mock(UiEventLogger.class),
- mock(UserTracker.class),
- mock(SecureSettings.class),
- mock(CustomTileStatePersister.class),
- mTileServiceRequestControllerBuilder,
- mock(TileLifecycleManager.Factory.class));
-
qs.setListening(true);
processAllMessages();
qs.setListening(false);
processAllMessages();
- host.destroy();
- processAllMessages();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 8cf3fe274848..7dbc561fbfc1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -32,12 +32,11 @@ import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.database.ContentObserver;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import androidx.annotation.Nullable;
@@ -48,7 +47,6 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.CollectionUtils;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.ActivityStarter;
@@ -68,8 +66,10 @@ import com.android.systemui.statusbar.phone.AutoTileManager;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -81,18 +81,19 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.Optional;
+import java.util.concurrent.Executor;
import javax.inject.Provider;
@RunWith(AndroidTestingRunner.class)
@SmallTest
-@RunWithLooper(setAsMainLooper = true)
public class QSTileHostTest extends SysuiTestCase {
private static String MOCK_STATE_STRING = "MockState";
private static ComponentName CUSTOM_TILE =
ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS");
private static final String CUSTOM_TILE_SPEC = CustomTile.toSpec(CUSTOM_TILE);
+ private static final String SETTING = QSTileHost.TILES_SETTING;
@Mock
private StatusBarIconController mIconController;
@@ -107,8 +108,6 @@ public class QSTileHostTest extends SysuiTestCase {
@Mock
private DumpManager mDumpManager;
@Mock
- private BroadcastDispatcher mBroadcastDispatcher;
- @Mock
private QSTile.State mMockState;
@Mock
private CentralSurfaces mCentralSurfaces;
@@ -132,31 +131,47 @@ public class QSTileHostTest extends SysuiTestCase {
@Mock
private TileLifecycleManager mTileLifecycleManager;
- private Handler mHandler;
- private TestableLooper mLooper;
+ private FakeExecutor mMainExecutor;
+
private QSTileHost mQSTileHost;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLooper = TestableLooper.get(this);
- mHandler = new Handler(mLooper.getLooper());
+ mMainExecutor = new FakeExecutor(new FakeSystemClock());
+
when(mTileServiceRequestControllerBuilder.create(any()))
.thenReturn(mTileServiceRequestController);
when(mTileLifecycleManagerFactory.create(any(Intent.class), any(UserHandle.class)))
.thenReturn(mTileLifecycleManager);
mSecureSettings = new FakeSettings();
- mSecureSettings.putStringForUser(
- QSTileHost.TILES_SETTING, "", "", false, mUserTracker.getUserId(), false);
- mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler,
- mLooper.getLooper(), mPluginManager, mTunerService, mAutoTiles, mDumpManager,
- mBroadcastDispatcher, mCentralSurfaces, mQSLogger, mUiEventLogger, mUserTracker,
- mSecureSettings, mCustomTileStatePersister, mTileServiceRequestControllerBuilder,
- mTileLifecycleManagerFactory);
+ saveSetting("");
+ mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mMainExecutor,
+ mPluginManager, mTunerService, mAutoTiles, mDumpManager, mCentralSurfaces,
+ mQSLogger, mUiEventLogger, mUserTracker, mSecureSettings, mCustomTileStatePersister,
+ mTileServiceRequestControllerBuilder, mTileLifecycleManagerFactory);
+
+ mSecureSettings.registerContentObserverForUser(SETTING, new ContentObserver(null) {
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ mMainExecutor.execute(() -> mQSTileHost.onTuningChanged(SETTING, getSetting()));
+ mMainExecutor.runAllReady();
+ }
+ }, mUserTracker.getUserId());
setUpTileFactory();
}
+ private void saveSetting(String value) {
+ mSecureSettings.putStringForUser(
+ SETTING, value, "", false, mUserTracker.getUserId(), false);
+ }
+
+ private String getSetting() {
+ return mSecureSettings.getStringForUser(SETTING, mUserTracker.getUserId());
+ }
+
private void setUpTileFactory() {
when(mMockState.toString()).thenReturn(MOCK_STATE_STRING);
// Only create this kind of tiles
@@ -173,6 +188,10 @@ public class QSTileHostTest extends SysuiTestCase {
return new NotAvailableTile(mQSTileHost);
} else if (CUSTOM_TILE_SPEC.equals(spec)) {
return mCustomTile;
+ } else if ("internet".equals(spec)
+ || "wifi".equals(spec)
+ || "cell".equals(spec)) {
+ return new TestTile1(mQSTileHost);
} else {
return null;
}
@@ -196,14 +215,14 @@ public class QSTileHostTest extends SysuiTestCase {
public void testInvalidSpecUsesDefault() {
mContext.getOrCreateTestableResources()
.addOverride(R.string.quick_settings_tiles, "spec1,spec2");
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "not-valid");
+ saveSetting("not-valid");
assertEquals(2, mQSTileHost.getTiles().size());
}
@Test
public void testRemoveWifiAndCellularWithoutInternet() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "wifi, spec1, cell, spec2");
+ saveSetting("wifi, spec1, cell, spec2");
assertEquals("internet", mQSTileHost.mTileSpecs.get(0));
assertEquals("spec1", mQSTileHost.mTileSpecs.get(1));
@@ -212,7 +231,7 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testRemoveWifiAndCellularWithInternet() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "wifi, spec1, cell, spec2, internet");
+ saveSetting("wifi, spec1, cell, spec2, internet");
assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
@@ -221,7 +240,7 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testRemoveWifiWithoutInternet() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1, wifi, spec2");
+ saveSetting("spec1, wifi, spec2");
assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
assertEquals("internet", mQSTileHost.mTileSpecs.get(1));
@@ -230,7 +249,7 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testRemoveCellWithInternet() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1, spec2, cell, internet");
+ saveSetting("spec1, spec2, cell, internet");
assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
@@ -239,7 +258,7 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testNoWifiNoCellularNoInternet() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec2");
+ saveSetting("spec1,spec2");
assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
@@ -249,7 +268,7 @@ public class QSTileHostTest extends SysuiTestCase {
public void testSpecWithInvalidDoesNotUseDefault() {
mContext.getOrCreateTestableResources()
.addOverride(R.string.quick_settings_tiles, "spec1,spec2");
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec2,not-valid");
+ saveSetting("spec2,not-valid");
assertEquals(1, mQSTileHost.getTiles().size());
QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles());
@@ -258,7 +277,7 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testDump() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec2");
+ saveSetting("spec1,spec2");
StringWriter w = new StringWriter();
PrintWriter pw = new PrintWriter(w);
mQSTileHost.dump(pw, new String[]{});
@@ -274,7 +293,7 @@ public class QSTileHostTest extends SysuiTestCase {
public void testDefault() {
mContext.getOrCreateTestableResources()
.addOverride(R.string.quick_settings_tiles_default, "spec1");
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "default");
+ saveSetting("default");
assertEquals(1, mQSTileHost.getTiles().size());
QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles());
assertTrue(element instanceof TestTile1);
@@ -285,7 +304,7 @@ public class QSTileHostTest extends SysuiTestCase {
public void testNoRepeatedSpecs_addTile() {
mContext.getOrCreateTestableResources()
.addOverride(R.string.quick_settings_tiles, "spec1,spec2");
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec2");
+ saveSetting("spec1,spec2");
mQSTileHost.addTile("spec1");
@@ -298,9 +317,10 @@ public class QSTileHostTest extends SysuiTestCase {
public void testAddTileAtValidPosition() {
mContext.getOrCreateTestableResources()
.addOverride(R.string.quick_settings_tiles, "spec1,spec3");
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+ saveSetting("spec1,spec3");
mQSTileHost.addTile("spec2", 1);
+ mMainExecutor.runAllReady();
assertEquals(3, mQSTileHost.mTileSpecs.size());
assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
@@ -312,9 +332,10 @@ public class QSTileHostTest extends SysuiTestCase {
public void testAddTileAtInvalidPositionAddsToEnd() {
mContext.getOrCreateTestableResources()
.addOverride(R.string.quick_settings_tiles, "spec1,spec3");
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+ saveSetting("spec1,spec3");
mQSTileHost.addTile("spec2", 100);
+ mMainExecutor.runAllReady();
assertEquals(3, mQSTileHost.mTileSpecs.size());
assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
@@ -326,9 +347,10 @@ public class QSTileHostTest extends SysuiTestCase {
public void testAddTileAtEnd() {
mContext.getOrCreateTestableResources()
.addOverride(R.string.quick_settings_tiles, "spec1,spec3");
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+ saveSetting("spec1,spec3");
mQSTileHost.addTile("spec2", QSTileHost.POSITION_AT_END);
+ mMainExecutor.runAllReady();
assertEquals(3, mQSTileHost.mTileSpecs.size());
assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
@@ -338,9 +360,10 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testNoRepeatedSpecs_customTile() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, CUSTOM_TILE_SPEC);
+ saveSetting(CUSTOM_TILE_SPEC);
mQSTileHost.addTile(CUSTOM_TILE, /* end */ false);
+ mMainExecutor.runAllReady();
assertEquals(1, mQSTileHost.mTileSpecs.size());
assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
@@ -348,9 +371,10 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testAddedAtBeginningOnDefault_customTile() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1"); // seed
+ saveSetting("spec1"); // seed
mQSTileHost.addTile(CUSTOM_TILE);
+ mMainExecutor.runAllReady();
assertEquals(2, mQSTileHost.mTileSpecs.size());
assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
@@ -358,9 +382,10 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testAddedAtBeginning_customTile() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1"); // seed
+ saveSetting("spec1"); // seed
mQSTileHost.addTile(CUSTOM_TILE, /* end */ false);
+ mMainExecutor.runAllReady();
assertEquals(2, mQSTileHost.mTileSpecs.size());
assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
@@ -368,9 +393,10 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testAddedAtEnd_customTile() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1"); // seed
+ saveSetting("spec1"); // seed
mQSTileHost.addTile(CUSTOM_TILE, /* end */ true);
+ mMainExecutor.runAllReady();
assertEquals(2, mQSTileHost.mTileSpecs.size());
assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(1));
@@ -409,13 +435,13 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testNotAvailableTile_specNotNull() {
- mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "na");
+ saveSetting("na");
verify(mQSLogger, never()).logTileDestroyed(isNull(), anyString());
}
@Test
public void testCustomTileRemoved_stateDeleted() {
- mQSTileHost.changeTiles(List.of(CUSTOM_TILE_SPEC), List.of());
+ mQSTileHost.changeTilesByUser(List.of(CUSTOM_TILE_SPEC), List.of());
verify(mCustomTileStatePersister)
.removeState(new TileServiceKey(CUSTOM_TILE, mQSTileHost.getUserId()));
@@ -423,29 +449,99 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testRemoveTiles() {
- List<String> tiles = List.of("spec1", "spec2", "spec3");
- mQSTileHost.saveTilesToSettings(tiles);
+ saveSetting("spec1,spec2,spec3");
mQSTileHost.removeTiles(List.of("spec1", "spec2"));
+ mMainExecutor.runAllReady();
assertEquals(List.of("spec3"), mQSTileHost.mTileSpecs);
}
+ @Test
+ public void testTilesRemovedInQuickSuccession() {
+ saveSetting("spec1,spec2,spec3");
+ mQSTileHost.removeTile("spec1");
+ mQSTileHost.removeTile("spec3");
+
+ mMainExecutor.runAllReady();
+ assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+ assertEquals("spec2", getSetting());
+ }
+
+ @Test
+ public void testAddTileInMainThread() {
+ saveSetting("spec1,spec2");
+
+ mQSTileHost.addTile("spec3");
+ assertEquals(List.of("spec1", "spec2"), mQSTileHost.mTileSpecs);
+
+ mMainExecutor.runAllReady();
+ assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.mTileSpecs);
+ }
+
+ @Test
+ public void testRemoveTileInMainThread() {
+ saveSetting("spec1,spec2");
+
+ mQSTileHost.removeTile("spec1");
+ assertEquals(List.of("spec1", "spec2"), mQSTileHost.mTileSpecs);
+
+ mMainExecutor.runAllReady();
+ assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+ }
+
+ @Test
+ public void testRemoveTilesInMainThread() {
+ saveSetting("spec1,spec2,spec3");
+
+ mQSTileHost.removeTiles(List.of("spec3", "spec1"));
+ assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.mTileSpecs);
+
+ mMainExecutor.runAllReady();
+ assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+ }
+
+ @Test
+ public void testRemoveTileByUserInMainThread() {
+ saveSetting("spec1," + CUSTOM_TILE_SPEC);
+
+ mQSTileHost.removeTileByUser(CUSTOM_TILE);
+ assertEquals(List.of("spec1", CUSTOM_TILE_SPEC), mQSTileHost.mTileSpecs);
+
+ mMainExecutor.runAllReady();
+ assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+ }
+
+ @Test
+ public void testNonValidTileNotStoredInSettings() {
+ saveSetting("spec1,not-valid");
+
+ assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+ assertEquals("spec1", getSetting());
+ }
+
+ @Test
+ public void testNotAvailableTileNotStoredInSettings() {
+ saveSetting("spec1,na");
+
+ assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+ assertEquals("spec1", getSetting());
+ }
+
private class TestQSTileHost extends QSTileHost {
TestQSTileHost(Context context, StatusBarIconController iconController,
- QSFactory defaultFactory, Handler mainHandler, Looper bgLooper,
+ QSFactory defaultFactory, Executor mainExecutor,
PluginManager pluginManager, TunerService tunerService,
Provider<AutoTileManager> autoTiles, DumpManager dumpManager,
- BroadcastDispatcher broadcastDispatcher, CentralSurfaces centralSurfaces,
- QSLogger qsLogger, UiEventLogger uiEventLogger, UserTracker userTracker,
- SecureSettings secureSettings, CustomTileStatePersister customTileStatePersister,
+ CentralSurfaces centralSurfaces, QSLogger qsLogger, UiEventLogger uiEventLogger,
+ UserTracker userTracker, SecureSettings secureSettings,
+ CustomTileStatePersister customTileStatePersister,
TileServiceRequestController.Builder tileServiceRequestControllerBuilder,
TileLifecycleManager.Factory tileLifecycleManagerFactory) {
- super(context, iconController, defaultFactory, mainHandler, bgLooper, pluginManager,
- tunerService, autoTiles, dumpManager, broadcastDispatcher,
- Optional.of(centralSurfaces), qsLogger, uiEventLogger, userTracker,
- secureSettings, customTileStatePersister, tileServiceRequestControllerBuilder,
- tileLifecycleManagerFactory);
+ super(context, iconController, defaultFactory, mainExecutor, pluginManager,
+ tunerService, autoTiles, dumpManager, Optional.of(centralSurfaces), qsLogger,
+ uiEventLogger, userTracker, secureSettings, customTileStatePersister,
+ tileServiceRequestControllerBuilder, tileLifecycleManagerFactory);
}
@Override
@@ -455,25 +551,16 @@ public class QSTileHostTest extends SysuiTestCase {
@Override
public void onPluginDisconnected(QSFactory plugin) {
}
-
- @Override
- void saveTilesToSettings(List<String> tileSpecs) {
- super.saveTilesToSettings(tileSpecs);
- // After tiles are changed, make sure to call onTuningChanged with the new setting if it
- // changed
- String specs = mSecureSettings.getStringForUser(
- QSTileHost.TILES_SETTING, mUserTracker.getUserId());
- onTuningChanged(TILES_SETTING, specs);
- }
}
+
private class TestTile extends QSTileImpl<QSTile.State> {
protected TestTile(QSHost host) {
super(
host,
- mLooper.getLooper(),
- new Handler(mLooper.getLooper()),
+ mock(Looper.class),
+ mock(Handler.class),
new FalsingManagerFake(),
mock(MetricsLogger.class),
mock(StatusBarStateController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
index 3d53062d7d02..d42cbe3b698a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
@@ -55,6 +55,6 @@ public class TileAdapterTest extends SysuiTestCase {
@Test
public void testResetNotifiesHost() {
mTileAdapter.resetTileSpecs(Collections.emptyList());
- verify(mQSTileHost).changeTiles(any(), any());
+ verify(mQSTileHost).changeTilesByUser(any(), any());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
index 2ad9c9400f65..fb17fc0a0595 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
@@ -163,4 +163,20 @@ class TileRequestDialogTest : SysuiTestCase() {
assertThat(tile.isClickable).isFalse()
assertThat(tile.isLongClickable).isFalse()
}
-} \ No newline at end of file
+
+ @Test
+ fun setTileData_tileHasCorrectContentDescription() {
+ val icon = Icon.createWithResource(mContext, R.drawable.cloud)
+ val tileData = TileRequestDialog.TileData(APP_NAME, LABEL, icon)
+
+ dialog.setTileData(tileData)
+ dialog.show()
+
+ TestableLooper.get(this).processAllMessages()
+
+ val content = dialog.requireViewById<ViewGroup>(TileRequestDialog.CONTENT_ID)
+ val tile = content.getChildAt(1) as QSTileView
+
+ assertThat(tile.contentDescription).isEqualTo(LABEL)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 6b7e5b9335f2..471ddfd3f224 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -29,6 +29,7 @@ import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.quicksettings.IQSTileService;
@@ -65,6 +66,7 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.Optional;
+import java.util.concurrent.Executor;
import javax.inject.Provider;
@@ -130,17 +132,16 @@ public class TileServicesTest extends SysuiTestCase {
.thenReturn(mTileLifecycleManager);
Provider<Handler> provider = () -> new Handler(mTestableLooper.getLooper());
+ Executor executor = new HandlerExecutor(provider.get());
QSTileHost host = new QSTileHost(mContext,
mStatusBarIconController,
mQSFactory,
- provider.get(),
- mTestableLooper.getLooper(),
+ executor,
mPluginManager,
mTunerService,
() -> mAutoTileManager,
mDumpManager,
- mock(BroadcastDispatcher.class),
Optional.of(mCentralSurfaces),
mQSLogger,
mUiEventLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
index 73226fa0b12c..6d9b01e28aa4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
@@ -31,6 +31,7 @@ import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Executor
+import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -62,6 +63,14 @@ class UserFileManagerImplTest : SysuiTestCase() {
broadcastDispatcher, backgroundExecutor)
}
+ @After
+ fun end() {
+ val dir = Environment.buildPath(
+ context.filesDir,
+ UserFileManagerImpl.ID)
+ dir.deleteRecursively()
+ }
+
@Test
fun testGetFile() {
assertThat(userFileManager.getFile(TEST_FILE_NAME, 0).path)
@@ -72,8 +81,19 @@ class UserFileManagerImplTest : SysuiTestCase() {
@Test
fun testGetSharedPreferences() {
+ val secondarySharedPref = userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 11)
+ val secondaryUserDir = Environment.buildPath(
+ context.filesDir,
+ UserFileManagerImpl.ID,
+ "11",
+ UserFileManagerImpl.SHARED_PREFS,
+ TEST_FILE_NAME
+ )
+
+ assertThat(secondarySharedPref).isNotNull()
+ assertThat(secondaryUserDir.exists())
assertThat(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0))
- .isNotEqualTo(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 11))
+ .isNotEqualTo(secondarySharedPref)
}
@Test
@@ -115,6 +135,19 @@ class UserFileManagerImplTest : SysuiTestCase() {
verify(userManager).aliveUsers
assertThat(secondaryUserDir.exists()).isFalse()
assertThat(file.exists()).isFalse()
- dir.deleteRecursively()
+ }
+
+ @Test
+ fun testEnsureParentDirExists() {
+ val file = Environment.buildPath(
+ context.filesDir,
+ UserFileManagerImpl.ID,
+ "11",
+ "files",
+ TEST_FILE_NAME
+ )
+ assertThat(file.parentFile.exists()).isFalse()
+ userFileManager.ensureParentDirExists(file)
+ assertThat(file.parentFile.exists()).isTrue()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 30c1b2594ee8..e2673bb74084 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -145,7 +145,6 @@ import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.PanelViewController;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -1285,6 +1284,29 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
}
@Test
+ public void testPanelClosedWhenClosingQsInSplitShade() {
+ mPanelExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
+ /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
+ enableSplitShade(/* enabled= */ true);
+ mNotificationPanelViewController.setExpandedFraction(1f);
+
+ assertThat(mNotificationPanelViewController.isClosing()).isFalse();
+ mNotificationPanelViewController.animateCloseQs(false);
+ assertThat(mNotificationPanelViewController.isClosing()).isTrue();
+ }
+
+ @Test
+ public void testPanelStaysOpenWhenClosingQs() {
+ mPanelExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
+ /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
+ mNotificationPanelViewController.setExpandedFraction(1f);
+
+ assertThat(mNotificationPanelViewController.isClosing()).isFalse();
+ mNotificationPanelViewController.animateCloseQs(false);
+ assertThat(mNotificationPanelViewController.isClosing()).isFalse();
+ }
+
+ @Test
public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
mNotificationPanelViewController.mQs = mQs;
when(mQsFrame.getX()).thenReturn(0f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 7687d1204541..dd2b66765fae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -29,7 +29,9 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -59,6 +61,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager.KeyguardNotificationSuppressor;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.NotificationStateChangedListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -325,6 +328,38 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
}
@Test
+ public void testUpdateIsPublicMode() {
+ when(mKeyguardStateController.isMethodSecure()).thenReturn(true);
+
+ NotificationStateChangedListener listener = mock(NotificationStateChangedListener.class);
+ mLockscreenUserManager.addNotificationStateChangedListener(listener);
+ mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class));
+
+ // first call explicitly sets user 0 to not public; notifies
+ mLockscreenUserManager.updatePublicMode();
+ assertFalse(mLockscreenUserManager.isLockscreenPublicMode(0));
+ verify(listener).onNotificationStateChanged();
+ clearInvocations(listener);
+
+ // calling again has no changes; does not notify
+ mLockscreenUserManager.updatePublicMode();
+ assertFalse(mLockscreenUserManager.isLockscreenPublicMode(0));
+ verify(listener, never()).onNotificationStateChanged();
+
+ // Calling again with keyguard now showing makes user 0 public; notifies
+ when(mKeyguardStateController.isShowing()).thenReturn(true);
+ mLockscreenUserManager.updatePublicMode();
+ assertTrue(mLockscreenUserManager.isLockscreenPublicMode(0));
+ verify(listener).onNotificationStateChanged();
+ clearInvocations(listener);
+
+ // calling again has no changes; does not notify
+ mLockscreenUserManager.updatePublicMode();
+ assertTrue(mLockscreenUserManager.isLockscreenPublicMode(0));
+ verify(listener, never()).onNotificationStateChanged();
+ }
+
+ @Test
public void testShowSilentNotifications_settingSaysShow() {
mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
index 214ba16dfc44..64d025628754 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
@@ -98,7 +98,7 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() {
@Test
fun testPrepareDialogForApp_onlyDefaultChannel() {
- group.channels = listOf(channelDefault)
+ group.addChannel(channelDefault)
controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
setOf(channelDefault), appIcon, clickListener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 371119cc6d01..4ccbc6d45e63 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -490,7 +490,7 @@ public class AutoTileManagerTest extends SysuiTestCase {
mAutoTileManager.init();
when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true);
mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false);
- verify(mQsTileHost, times(1)).removeTile(safetyComponent);
+ verify(mQsTileHost, times(1)).removeTile(TEST_CUSTOM_SAFETY_SPEC);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index d79f3361408b..7b7a48be5b17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -22,26 +22,28 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.StatusBarManager;
import android.os.PowerManager;
import android.os.Vibrator;
import android.testing.AndroidTestingRunner;
+import android.view.InsetsVisibilities;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.FakeMetricsLogger;
+import com.android.internal.statusbar.LetterboxDetails;
+import com.android.internal.view.AppearanceRegion;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.shade.NotificationPanelViewController;
-import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
-import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -60,6 +62,7 @@ import java.util.Optional;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
+
@Mock private CentralSurfaces mCentralSurfaces;
@Mock private ShadeController mShadeController;
@Mock private CommandQueue mCommandQueue;
@@ -74,14 +77,12 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private AssistManager mAssistManager;
@Mock private DozeServiceHost mDozeServiceHost;
- @Mock private StatusBarStateControllerImpl mStatusBarStateController;
- @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
@Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
@Mock private PowerManager mPowerManager;
@Mock private VibratorHelper mVibratorHelper;
@Mock private Vibrator mVibrator;
- @Mock private LightBarController mLightBarController;
@Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
+ @Mock private SystemBarAttributesListener mSystemBarAttributesListener;
CentralSurfacesCommandQueueCallbacks mSbcqCallbacks;
@@ -106,16 +107,14 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
mStatusBarKeyguardViewManager,
mAssistManager,
mDozeServiceHost,
- mStatusBarStateController,
- mNotificationShadeWindowView,
mNotificationStackScrollLayoutController,
mStatusBarHideIconsForBouncerManager,
mPowerManager,
mVibratorHelper,
Optional.of(mVibrator),
- mLightBarController,
new DisableFlagsLogger(),
- DEFAULT_DISPLAY);
+ DEFAULT_DISPLAY,
+ mSystemBarAttributesListener);
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
when(mRemoteInputQuickSettingsDisabler.adjustDisableFlags(anyInt()))
@@ -170,5 +169,59 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
verify(mDozeServiceHost).setAlwaysOnSuppressed(false);
}
+ @Test
+ public void onSystemBarAttributesChanged_forwardsToSysBarAttrsListener() {
+ int displayId = DEFAULT_DISPLAY;
+ int appearance = 123;
+ AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{};
+ boolean navbarColorManagedByIme = true;
+ int behavior = 456;
+ InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
+ String packageName = "test package name";
+ LetterboxDetails[] letterboxDetails = new LetterboxDetails[]{};
+
+ mSbcqCallbacks.onSystemBarAttributesChanged(
+ displayId,
+ appearance,
+ appearanceRegions,
+ navbarColorManagedByIme,
+ behavior,
+ requestedVisibilities,
+ packageName,
+ letterboxDetails);
+
+ verify(mSystemBarAttributesListener).onSystemBarAttributesChanged(
+ displayId,
+ appearance,
+ appearanceRegions,
+ navbarColorManagedByIme,
+ behavior,
+ requestedVisibilities,
+ packageName,
+ letterboxDetails
+ );
+ }
+ @Test
+ public void onSystemBarAttributesChanged_differentDisplayId_doesNotForwardToAttrsListener() {
+ int appearance = 123;
+ AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{};
+ boolean navbarColorManagedByIme = true;
+ int behavior = 456;
+ InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
+ String packageName = "test package name";
+ LetterboxDetails[] letterboxDetails = new LetterboxDetails[]{};
+
+ mSbcqCallbacks.onSystemBarAttributesChanged(
+ DEFAULT_DISPLAY + 1,
+ appearance,
+ appearanceRegions,
+ navbarColorManagedByIme,
+ behavior,
+ requestedVisibilities,
+ packageName,
+ letterboxDetails);
+
+ verifyZeroInteractions(mSystemBarAttributesListener);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
new file mode 100644
index 000000000000..0531bc79d22a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
@@ -0,0 +1,205 @@
+/*
+ * 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.statusbar.phone
+
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.WindowInsetsController
+import android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS
+import androidx.test.filters.SmallTest
+import com.android.internal.statusbar.LetterboxDetails
+import com.android.internal.view.AppearanceRegion
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
+import com.google.common.truth.Expect
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class LetterboxAppearanceCalculatorTest : SysuiTestCase() {
+
+ companion object {
+ private const val DEFAULT_APPEARANCE = 0
+ private const val TEST_APPEARANCE = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
+ private val TEST_APPEARANCE_REGION_BOUNDS = Rect(0, 0, 20, 100)
+ private val TEST_APPEARANCE_REGION =
+ AppearanceRegion(TEST_APPEARANCE, TEST_APPEARANCE_REGION_BOUNDS)
+ private val TEST_APPEARANCE_REGIONS = arrayOf(TEST_APPEARANCE_REGION)
+ private val TEST_WINDOW_BOUNDS = Rect(0, 0, 500, 500)
+ }
+
+ @get:Rule var expect = Expect.create()
+
+ @Mock private lateinit var lightBarController: LightBarController
+ @Mock private lateinit var statusBarBoundsProvider: StatusBarBoundsProvider
+ @Mock private lateinit var statusBarFragmentComponent: StatusBarFragmentComponent
+ @Mock private lateinit var dumpManager: DumpManager
+
+ private lateinit var calculator: LetterboxAppearanceCalculator
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(statusBarFragmentComponent.boundsProvider).thenReturn(statusBarBoundsProvider)
+ calculator = LetterboxAppearanceCalculator(lightBarController, dumpManager)
+ calculator.onStatusBarViewInitialized(statusBarFragmentComponent)
+ }
+
+ @Test
+ fun getLetterboxAppearance_overlapStartSide_returnsOriginalWithScrim() {
+ whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+ val letterbox = letterboxWithInnerBounds(Rect(50, 50, 150, 150))
+
+ val letterboxAppearance =
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+ expect
+ .that(letterboxAppearance.appearance)
+ .isEqualTo(TEST_APPEARANCE or APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS)
+ expect.that(letterboxAppearance.appearanceRegions).isEqualTo(TEST_APPEARANCE_REGIONS)
+ }
+
+ @Test
+ fun getLetterboxAppearance_overlapEndSide_returnsOriginalWithScrim() {
+ whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+ val letterbox = letterboxWithInnerBounds(Rect(150, 50, 250, 150))
+
+ val letterboxAppearance =
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+ expect
+ .that(letterboxAppearance.appearance)
+ .isEqualTo(TEST_APPEARANCE or APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS)
+ expect.that(letterboxAppearance.appearanceRegions).isEqualTo(TEST_APPEARANCE_REGIONS)
+ }
+
+ @Test
+ fun getLetterboxAppearance_noOverlap_returnsAppearanceWithoutScrim() {
+ whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+ val letterbox = letterboxWithInnerBounds(Rect(101, 0, 199, 100))
+
+ val letterboxAppearance =
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+ assertThat(letterboxAppearance.appearance).isEqualTo(TEST_APPEARANCE)
+ }
+
+ @Test
+ fun getLetterboxAppearance_letterboxContainsStartSide_returnsAppearanceWithoutScrim() {
+ whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+ val letterbox = letterboxWithInnerBounds(Rect(0, 0, 101, 101))
+
+ val letterboxAppearance =
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+ assertThat(letterboxAppearance.appearance).isEqualTo(TEST_APPEARANCE)
+ }
+
+ @Test
+ fun getLetterboxAppearance_letterboxContainsEndSide_returnsAppearanceWithoutScrim() {
+ whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+ val letterbox = letterboxWithInnerBounds(Rect(199, 0, 301, 101))
+
+ val letterboxAppearance =
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+ assertThat(letterboxAppearance.appearance).isEqualTo(TEST_APPEARANCE)
+ }
+
+ @Test
+ fun getLetterboxAppearance_letterboxContainsEntireStatusBar_returnsAppearanceWithoutScrim() {
+ whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+ val letterbox = letterboxWithInnerBounds(Rect(0, 0, 300, 100))
+
+ val letterboxAppearance =
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+ assertThat(letterboxAppearance.appearance).isEqualTo(TEST_APPEARANCE)
+ }
+
+ @Test
+ fun getLetterboxAppearance_returnsAdaptedAppearanceRegions_basedOnLetterboxInnerBounds() {
+ whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 0, 0))
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(0, 0, 0, 0))
+ val letterbox = letterboxWithInnerBounds(Rect(150, 0, 300, 800))
+ val letterboxRegion = TEST_APPEARANCE_REGION.copy(bounds = letterbox.letterboxFullBounds)
+
+ val letterboxAppearance =
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE, arrayOf(letterboxRegion), arrayOf(letterbox))
+
+ val letterboxAdaptedRegion = letterboxRegion.copy(bounds = letterbox.letterboxInnerBounds)
+ assertThat(letterboxAppearance.appearanceRegions.toList()).contains(letterboxAdaptedRegion)
+ assertThat(letterboxAppearance.appearanceRegions.toList()).doesNotContain(letterboxRegion)
+ }
+
+ @Test
+ fun getLetterboxAppearance_returnsDefaultAppearanceRegions_basedOnLetterboxOuterBounds() {
+ whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 0, 0))
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(0, 0, 0, 0))
+ val letterbox =
+ letterboxWithBounds(
+ innerBounds = Rect(left = 25, top = 0, right = 75, bottom = 100),
+ fullBounds = Rect(left = 0, top = 0, right = 100, bottom = 100))
+ val letterboxRegion = TEST_APPEARANCE_REGION.copy(bounds = letterbox.letterboxFullBounds)
+
+ val letterboxAppearance =
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE, arrayOf(letterboxRegion), arrayOf(letterbox))
+
+ val outerRegions =
+ listOf(
+ AppearanceRegion(
+ DEFAULT_APPEARANCE, Rect(left = 0, top = 0, right = 25, bottom = 100)),
+ AppearanceRegion(
+ DEFAULT_APPEARANCE, Rect(left = 75, top = 0, right = 100, bottom = 100)),
+ )
+ assertThat(letterboxAppearance.appearanceRegions.toList())
+ .containsAtLeastElementsIn(outerRegions)
+ }
+
+ private fun letterboxWithBounds(innerBounds: Rect, fullBounds: Rect) =
+ LetterboxDetails(innerBounds, fullBounds, TEST_APPEARANCE)
+
+ private fun letterboxWithInnerBounds(innerBounds: Rect) =
+ letterboxWithBounds(innerBounds, fullBounds = TEST_WINDOW_BOUNDS)
+}
+
+private fun AppearanceRegion.copy(appearance: Int = this.appearance, bounds: Rect = this.bounds) =
+ AppearanceRegion(appearance, bounds)
+
+private fun Rect(left: Int, top: Int, right: Int, bottom: Int) = Rect(left, top, right, bottom)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index ba29e953c73d..9892448aed03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -26,6 +26,7 @@ import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.PanelViewController
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.unfold.SysUIUnfoldComponent
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
index 8d686ae94e79..d6c995bef229 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
@@ -20,6 +20,7 @@ import android.view.MotionEvent
import android.view.ViewGroup
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.PanelViewController
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt
new file mode 100644
index 000000000000..fa7b2599c108
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt
@@ -0,0 +1,250 @@
+package com.android.systemui.statusbar.phone
+
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.view.InsetsVisibilities
+import android.view.WindowInsetsController
+import android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
+import android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
+import android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS
+import android.view.WindowInsetsController.Appearance
+import androidx.test.filters.SmallTest
+import com.android.internal.statusbar.LetterboxDetails
+import com.android.internal.view.AppearanceRegion
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+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.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SystemBarAttributesListenerTest : SysuiTestCase() {
+
+ @Mock private lateinit var dumpManager: DumpManager
+ @Mock private lateinit var lightBarController: LightBarController
+ @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
+ @Mock private lateinit var letterboxAppearanceCalculator: LetterboxAppearanceCalculator
+ @Mock private lateinit var featureFlags: FeatureFlags
+ @Mock private lateinit var centralSurfaces: CentralSurfaces
+
+ private lateinit var sysBarAttrsListener: SystemBarAttributesListener
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ whenever(
+ letterboxAppearanceCalculator.getLetterboxAppearance(
+ anyInt(), anyObject(), anyObject()))
+ .thenReturn(TEST_LETTERBOX_APPEARANCE)
+
+ sysBarAttrsListener =
+ SystemBarAttributesListener(
+ centralSurfaces,
+ featureFlags,
+ letterboxAppearanceCalculator,
+ statusBarStateController,
+ lightBarController,
+ dumpManager)
+ }
+
+ @Test
+ fun onSysBarAttrsChanged_forwardsAppearanceToCentralSurfaces() {
+ val appearance = APPEARANCE_LIGHT_STATUS_BARS or APPEARANCE_LIGHT_NAVIGATION_BARS
+
+ changeSysBarAttrs(appearance)
+
+ verify(centralSurfaces).setAppearance(appearance)
+ }
+
+ @Test
+ fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToCentralSurfaces() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_LETTERBOX_DETAILS)
+
+ verify(centralSurfaces).setAppearance(TEST_LETTERBOX_APPEARANCE.appearance)
+ }
+
+ @Test
+ fun onSysBarAttrsChanged_flagTrue_noLetterbox_forwardsOriginalAppearanceToCtrlSrfcs() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+
+ changeSysBarAttrs(TEST_APPEARANCE, arrayOf<LetterboxDetails>())
+
+ verify(centralSurfaces).setAppearance(TEST_APPEARANCE)
+ }
+
+ @Test
+ fun onSysBarAttrsChanged_forwardsAppearanceToStatusBarStateController() {
+ changeSysBarAttrs(TEST_APPEARANCE)
+
+ verify(statusBarStateController)
+ .setSystemBarAttributes(eq(TEST_APPEARANCE), anyInt(), any(), any())
+ }
+
+ @Test
+ fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToStatusBarStateCtrl() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_LETTERBOX_DETAILS)
+
+ verify(statusBarStateController)
+ .setSystemBarAttributes(
+ eq(TEST_LETTERBOX_APPEARANCE.appearance), anyInt(), any(), any())
+ }
+
+ @Test
+ fun onSysBarAttrsChanged_forwardsAppearanceToLightBarController() {
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS)
+
+ verify(lightBarController)
+ .onStatusBarAppearanceChanged(
+ eq(TEST_APPEARANCE_REGIONS), anyBoolean(), anyInt(), anyBoolean())
+ }
+
+ @Test
+ fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToLightBarController() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+
+ verify(lightBarController)
+ .onStatusBarAppearanceChanged(
+ eq(TEST_LETTERBOX_APPEARANCE.appearanceRegions),
+ anyBoolean(),
+ anyInt(),
+ anyBoolean())
+ }
+
+ @Test
+ fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToStatusBarStateController() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+ reset(centralSurfaces, lightBarController, statusBarStateController)
+
+ sysBarAttrsListener.onStatusBarBoundsChanged()
+
+ verify(statusBarStateController)
+ .setSystemBarAttributes(
+ eq(TEST_LETTERBOX_APPEARANCE.appearance), anyInt(), any(), any())
+ }
+
+ @Test
+ fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToLightBarController() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+ reset(centralSurfaces, lightBarController, statusBarStateController)
+
+ sysBarAttrsListener.onStatusBarBoundsChanged()
+
+ verify(lightBarController)
+ .onStatusBarAppearanceChanged(
+ eq(TEST_LETTERBOX_APPEARANCE.appearanceRegions),
+ anyBoolean(),
+ anyInt(),
+ anyBoolean())
+ }
+
+ @Test
+ fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToCentralSurfaces() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+ reset(centralSurfaces, lightBarController, statusBarStateController)
+
+ sysBarAttrsListener.onStatusBarBoundsChanged()
+
+ verify(centralSurfaces).setAppearance(TEST_LETTERBOX_APPEARANCE.appearance)
+ }
+
+ @Test
+ fun onStatusBarBoundsChanged_previousCallEmptyLetterbox_doesNothing() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf())
+ reset(centralSurfaces, lightBarController, statusBarStateController)
+
+ sysBarAttrsListener.onStatusBarBoundsChanged()
+
+ verifyZeroInteractions(centralSurfaces, lightBarController, statusBarStateController)
+ }
+
+ @Test
+ fun onStatusBarBoundsChanged_flagFalse_doesNothing() {
+ whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(false)
+ changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+ reset(centralSurfaces, lightBarController, statusBarStateController)
+
+ sysBarAttrsListener.onStatusBarBoundsChanged()
+
+ verifyZeroInteractions(centralSurfaces, lightBarController, statusBarStateController)
+ }
+
+ private fun changeSysBarAttrs(@Appearance appearance: Int) {
+ changeSysBarAttrs(appearance, arrayOf<LetterboxDetails>())
+ }
+
+ private fun changeSysBarAttrs(
+ @Appearance appearance: Int,
+ letterboxDetails: Array<LetterboxDetails>
+ ) {
+ changeSysBarAttrs(appearance, arrayOf(), letterboxDetails)
+ }
+
+ private fun changeSysBarAttrs(
+ @Appearance appearance: Int,
+ appearanceRegions: Array<AppearanceRegion>
+ ) {
+ changeSysBarAttrs(appearance, appearanceRegions, arrayOf())
+ }
+
+ private fun changeSysBarAttrs(
+ @Appearance appearance: Int,
+ appearanceRegions: Array<AppearanceRegion>,
+ letterboxDetails: Array<LetterboxDetails>
+ ) {
+ sysBarAttrsListener.onSystemBarAttributesChanged(
+ Display.DEFAULT_DISPLAY,
+ appearance,
+ appearanceRegions,
+ /* navbarColorManagedByIme= */ false,
+ WindowInsetsController.BEHAVIOR_DEFAULT,
+ InsetsVisibilities(),
+ "package name",
+ letterboxDetails)
+ }
+
+ companion object {
+ private const val TEST_APPEARANCE =
+ APPEARANCE_LIGHT_STATUS_BARS or APPEARANCE_LIGHT_NAVIGATION_BARS
+ private val TEST_APPEARANCE_REGION = AppearanceRegion(TEST_APPEARANCE, Rect(0, 0, 150, 300))
+ private val TEST_APPEARANCE_REGIONS = arrayOf(TEST_APPEARANCE_REGION)
+ private val TEST_LETTERBOX_DETAILS =
+ arrayOf(
+ LetterboxDetails(
+ /* letterboxInnerBounds= */ Rect(0, 0, 0, 0),
+ /* letterboxFullBounds= */ Rect(0, 0, 0, 0),
+ /* appAppearance= */ 0))
+ private val TEST_LETTERBOX_APPEARANCE =
+ LetterboxAppearance(/* appearance= */ APPEARANCE_LOW_PROFILE_BARS, arrayOf())
+ }
+}
+
+private fun <T> anyObject(): T {
+ return Mockito.anyObject<T>()
+}
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 09d7c03c2091..359a780d2a94 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
@@ -77,6 +77,7 @@ import org.mockito.Mockito.doNothing
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.eq
import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@@ -269,6 +270,8 @@ class UserSwitcherControllerTest : SysuiTestCase() {
`when`(userManager.createGuest(any())).thenReturn(guestInfo)
userSwitcherController.onUserListItemClicked(emptyGuestUserRecord, null)
+ bgExecutor.runAllReady()
+ uiExecutor.runAllReady()
testableLooper.processAllMessages()
verify(interactionJankMonitor).begin(any())
verify(latencyTracker).onActionStart(LatencyTracker.ACTION_USER_SWITCH)
@@ -294,6 +297,8 @@ class UserSwitcherControllerTest : SysuiTestCase() {
`when`(userManager.createGuest(any())).thenReturn(guestInfo)
userSwitcherController.onUserListItemClicked(emptyGuestUserRecord, dialogShower)
+ bgExecutor.runAllReady()
+ uiExecutor.runAllReady()
testableLooper.processAllMessages()
verify(dialogShower).dismiss()
}
@@ -584,4 +589,24 @@ class UserSwitcherControllerTest : SysuiTestCase() {
broadcastReceiverCaptor.value.onReceive(context, intent)
verify(cb).onUserSwitched()
}
+
+ @Test
+ fun onUserItemClicked_guest_runsOnBgThread() {
+ val dialogShower = mock(UserSwitchDialogController.DialogShower::class.java)
+ val guestUserRecord = UserSwitcherController.UserRecord(
+ null,
+ picture,
+ true /* guest */,
+ false /* current */,
+ false /* isAddUser */,
+ false /* isRestricted */,
+ true /* isSwitchToEnabled */,
+ false /* isAddSupervisedUser */)
+
+ userSwitcherController.onUserListItemClicked(guestUserRecord, dialogShower)
+ assertTrue(bgExecutor.numPending() > 0)
+ verify(userManager, never()).createGuest(context)
+ bgExecutor.runAllReady()
+ verify(userManager).createGuest(context)
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
new file mode 100644
index 000000000000..a85ae7df546b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
@@ -0,0 +1,73 @@
+package com.android.systemui.user
+
+import android.content.pm.UserInfo
+import android.graphics.Bitmap
+import android.os.UserManager
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.time.FakeSystemClock
+import java.util.function.Consumer
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class UserCreatorTest : SysuiTestCase() {
+ companion object {
+ const val USER_NAME = "abc"
+ }
+
+ @Mock
+ private lateinit var userCreator: UserCreator
+ @Mock
+ private lateinit var userManager: UserManager
+ private lateinit var mainExecutor: FakeExecutor
+ private lateinit var bgExecutor: FakeExecutor
+ private lateinit var user: UserInfo
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ mainExecutor = FakeExecutor(FakeSystemClock())
+ bgExecutor = FakeExecutor(FakeSystemClock())
+ userCreator = UserCreator(context, userManager, mainExecutor, bgExecutor)
+ user = Mockito.mock(UserInfo::class.java)
+ Mockito.`when`(userManager.createUser(USER_NAME, UserManager.USER_TYPE_FULL_SECONDARY, 0))
+ .thenReturn(user)
+ }
+
+ @Test
+ fun testCreateUser_threadingOrder() {
+ val successCallback = Mockito.mock(Consumer::class.java)
+ val errorCallback = Mockito.mock(Runnable::class.java)
+
+ userCreator.createUser(
+ USER_NAME,
+ null,
+ successCallback as Consumer<UserInfo?>,
+ errorCallback)
+
+ verify(userManager, never()).createUser(USER_NAME, UserManager.USER_TYPE_FULL_SECONDARY, 0)
+ bgExecutor.runAllReady()
+ verify(successCallback, never()).accept(user)
+ mainExecutor.runAllReady()
+ verify(userManager, never()).setUserIcon(anyInt(), any(Bitmap::class.java))
+ bgExecutor.runAllReady()
+
+ verify(userManager).createUser(USER_NAME, UserManager.USER_TYPE_FULL_SECONDARY, 0)
+ verify(userManager).setUserIcon(anyInt(), any(Bitmap::class.java))
+ verify(successCallback).accept(user)
+ }
+}
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 0a4ecb227548..f903c2005ae3 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -298,6 +298,10 @@ message SystemMessage {
// Notify the user to setup their dock
NOTE_SETUP_DOCK = 72;
+ // Inform the user of wifi apm state changes.
+ // Package: android
+ NOTE_WIFI_APM_NOTIFICATION = 73;
+
// ADD_NEW_IDS_ABOVE_THIS_LINE
// Legacy IDs with arbitrary values appear below
// Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
index e8cf2f748c88..a68fc9ab2290 100644
--- a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
+++ b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
@@ -26,7 +26,6 @@ import android.sax.TextElementListener;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
-import android.text.format.Time;
import android.util.Log;
import android.util.Xml;
import com.android.internal.util.XmlUtils;
@@ -39,6 +38,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.time.Instant;
import com.android.frameworks.saxtests.R;
@@ -225,8 +225,7 @@ public class SafeSaxTest extends AndroidTestCase {
.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
// TODO(tomtaylor): programmatically get the timezone
- video.dateAdded = new Time(Time.TIMEZONE_UTC);
- video.dateAdded.parse3339(body);
+ video.dateAdded = Instant.parse(body);
}
});
@@ -472,8 +471,7 @@ public class SafeSaxTest extends AndroidTestCase {
if (uri.equals(ATOM_NAMESPACE)) {
if (localName.equals("published")) {
// TODO(tomtaylor): programmatically get the timezone
- video.dateAdded = new Time(Time.TIMEZONE_UTC);
- video.dateAdded.parse3339(takeText());
+ video.dateAdded = Instant.parse(takeText());
return;
}
@@ -532,7 +530,7 @@ public class SafeSaxTest extends AndroidTestCase {
public float rating; // ranges from 0.0 to 5.0
public Boolean triedToLoadThumbnail;
public String authorName;
- public Time dateAdded;
+ public Instant dateAdded;
public String category;
public String tags;
public String description;
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 97582044fa0b..dac23a775d56 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -819,7 +819,7 @@ public abstract class PackageManagerInternal {
@NonNull String packageName);
/**
- * Returns {@code true} if the the signing information for {@code clientUid} is sufficient
+ * Returns {@code true} if the signing information for {@code clientUid} is sufficient
* to gain access gated by {@code capability}. This can happen if the two UIDs have the
* same signing information, if the signing information {@code clientUid} indicates that
* it has the signing certificate for {@code serverUid} in its signing history (if it was
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 73d9cc759b10..d29e25c3faff 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -862,10 +862,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
return list;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.SHUTDOWN)
@Override
public void shutdown() {
// TODO: remove from aidl if nobody calls externally
- mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
Slog.i(TAG, "Shutting down");
}
@@ -1203,9 +1203,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
setUidOnMeteredNetworkList(uid, true, enable);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.NETWORK_SETTINGS)
@Override
public boolean setDataSaverModeEnabled(boolean enable) {
- mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG);
if (DBG) Log.d(TAG, "setDataSaverMode: " + enable);
synchronized (mQuotaLock) {
@@ -1741,9 +1741,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
return NetdUtils.removeRoutesFromLocalNetwork(mNetdService, routes);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
@Override
public boolean isNetworkRestricted(int uid) {
- mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
return isNetworkRestrictedInternal(uid);
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index c5b5fb941e05..002aa773d85a 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -4413,7 +4413,7 @@ public final class ActiveServices {
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
thread.scheduleCreateService(r, r.serviceInfo,
- mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
+ null /* compatInfo (unused but need to keep method signature) */,
app.mState.getReportedProcState());
r.postNotification();
created = true;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9f0aeec40bd7..5729a06830cf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4980,7 +4980,6 @@ public class ActivityManagerService extends IActivityManager.Stub
PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
try {
thread.scheduleCreateBackupAgent(backupTarget.appInfo,
- compatibilityInfoForPackage(backupTarget.appInfo),
backupTarget.backupMode, backupTarget.userId, backupTarget.operationType);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
@@ -12900,8 +12899,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (thread != null) {
if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
try {
- thread.scheduleCreateBackupAgent(app,
- compatibilityInfoForPackage(app), backupMode, targetUserId,
+ thread.scheduleCreateBackupAgent(app, backupMode, targetUserId,
operationType);
} catch (RemoteException e) {
// Will time out on the backup manager side
@@ -13027,8 +13025,7 @@ public class ActivityManagerService extends IActivityManager.Stub
final IApplicationThread thread = proc.getThread();
if (thread != null) {
try {
- thread.scheduleDestroyBackupAgent(appInfo,
- compatibilityInfoForPackage(appInfo), userId);
+ thread.scheduleDestroyBackupAgent(appInfo, userId);
} catch (Exception e) {
Slog.e(TAG, "Exception when unbinding backup agent:");
e.printStackTrace();
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 0cd1bfa3740a..6d520c3c6be8 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -361,7 +361,7 @@ public final class BroadcastQueue {
mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
- mService.compatibilityInfoForPackage(r.curReceiver.applicationInfo),
+ null /* compatInfo (unused but need to keep method signature) */,
r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
app.mState.getReportedProcState());
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index 7371d07183a9..33e407025ae6 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -564,10 +564,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return res;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
@Override
public byte[] getCurrentStats(List<ParcelFileDescriptor> historic) {
- mAm.mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.PACKAGE_USAGE_STATS, null);
Parcel current = Parcel.obtain();
synchronized (mLock) {
long now = SystemClock.uptimeMillis();
@@ -619,11 +618,10 @@ public final class ProcessStatsService extends IProcessStats.Stub {
* @return List of proto binary of individual commit files or one that is merged from them;
* the merged, final ProcessStats object.
*/
+ @android.annotation.EnforcePermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
@Override
public long getCommittedStatsMerged(long highWaterMarkMs, int section, boolean doAggregate,
List<ParcelFileDescriptor> committedStats, ProcessStats mergedStats) {
- mAm.mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.PACKAGE_USAGE_STATS, null);
long newHighWaterMark = highWaterMarkMs;
mFileLock.lock();
@@ -708,10 +706,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return fds[0];
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
@Override
public ParcelFileDescriptor getStatsOverTime(long minTime) {
- mAm.mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.PACKAGE_USAGE_STATS, null);
Parcel current = Parcel.obtain();
long curTime;
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 18d5194e8bc0..e40925605899 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3904,6 +3904,36 @@ public class AudioService extends IAudioService.Stub
}
}
+ private void setLeAudioVolumeOnModeUpdate(int mode) {
+ switch (mode) {
+ case AudioSystem.MODE_IN_COMMUNICATION:
+ case AudioSystem.MODE_IN_CALL:
+ case AudioSystem.MODE_NORMAL:
+ break;
+ case AudioSystem.MODE_RINGTONE:
+ // not changing anything for ringtone
+ return;
+ case AudioSystem.MODE_CURRENT:
+ case AudioSystem.MODE_INVALID:
+ default:
+ // don't know what to do in this case, better bail
+ return;
+ }
+
+ int streamType = getBluetoothContextualVolumeStream(mode);
+
+ // Currently, DEVICE_OUT_BLE_HEADSET is the only output type for LE_AUDIO profile.
+ // (See AudioDeviceBroker#createBtDeviceInfo())
+ int index = mStreamStates[streamType].getIndex(AudioSystem.DEVICE_OUT_BLE_HEADSET);
+ int maxIndex = mStreamStates[streamType].getMaxIndex();
+
+ if (DEBUG_VOL) {
+ Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex index="
+ + index + " maxIndex=" + maxIndex + " streamType=" + streamType);
+ }
+ mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
+ }
+
private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
String caller, String attributionTag, int uid,
boolean hasModifyAudioSettings) {
@@ -5276,6 +5306,10 @@ public class AudioService extends IAudioService.Stub
// change of mode may require volume to be re-applied on some devices
updateAbsVolumeMultiModeDevices(previousMode, mode);
+ // Forcefully set LE audio volume as a workaround, since the value of 'device'
+ // is not DEVICE_OUT_BLE_* even when BLE is connected.
+ setLeAudioVolumeOnModeUpdate(mode);
+
// when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
// connections not started by the application changing the mode when pid changes
mDeviceBroker.postSetModeOwnerPid(pid, mode);
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index cd5960ffbf32..1def72b2987f 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -46,6 +46,8 @@ import android.util.Log;
import android.util.Pair;
import android.util.SparseIntArray;
+import com.android.internal.annotations.GuardedBy;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -103,10 +105,6 @@ public class SpatializerHelper {
AudioDeviceInfo.TYPE_BLE_BROADCAST
};
- private static final int[] WIRELESS_SPEAKER_TYPES = {
- AudioDeviceInfo.TYPE_BLE_SPEAKER,
- };
-
// Spatializer state machine
private static final int STATE_UNINITIALIZED = 0;
private static final int STATE_NOT_SUPPORTED = 1;
@@ -166,6 +164,7 @@ public class SpatializerHelper {
* List of devices where Spatial Audio is possible. Each device can be enabled or disabled
* (== user choice to use or not)
*/
+ @GuardedBy("this")
private final ArrayList<SADeviceState> mSADevices = new ArrayList<>(0);
//------------------------------------------------------
@@ -520,30 +519,30 @@ public class SpatializerHelper {
* set to true if the device is added to the list, otherwise, if already
* present, the setting is left untouched.
*/
+ @GuardedBy("this")
private void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada,
boolean forceEnable) {
if (!isDeviceCompatibleWithSpatializationModes(ada)) {
return;
}
loglogi("addCompatibleAudioDevice: dev=" + ada);
- boolean isInList = false;
+ final SADeviceState deviceState = findDeviceStateForAudioDeviceAttributes(ada);
SADeviceState deviceUpdated = null; // non-null on update.
-
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- isInList = true;
- if (forceEnable) {
- deviceState.mEnabled = true;
- deviceUpdated = deviceState;
- }
- break;
+ if (deviceState != null) {
+ if (forceEnable && !deviceState.mEnabled) {
+ deviceUpdated = deviceState;
+ deviceUpdated.mEnabled = true;
}
- }
- if (!isInList) {
- final SADeviceState deviceState = new SADeviceState(ada.getType(), ada.getAddress());
- deviceState.mEnabled = true;
- mSADevices.add(deviceState);
- deviceUpdated = deviceState;
+ } else {
+ // When adding, force the device type to be a canonical one.
+ final int canonicalDeviceType = getCanonicalDeviceType(ada.getType());
+ if (canonicalDeviceType == AudioDeviceInfo.TYPE_UNKNOWN) {
+ Log.e(TAG, "addCompatibleAudioDevice with incompatible AudioDeviceAttributes "
+ + ada);
+ return;
+ }
+ deviceUpdated = new SADeviceState(canonicalDeviceType, ada.getAddress());
+ mSADevices.add(deviceUpdated);
}
if (deviceUpdated != null) {
onRoutingUpdated();
@@ -574,90 +573,95 @@ public class SpatializerHelper {
synchronized void removeCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
loglogi("removeCompatibleAudioDevice: dev=" + ada);
- SADeviceState deviceUpdated = null; // non-null on update.
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- deviceState.mEnabled = false;
- deviceUpdated = deviceState;
- break;
- }
- }
- if (deviceUpdated != null) {
+ final SADeviceState deviceState = findDeviceStateForAudioDeviceAttributes(ada);
+ if (deviceState != null && deviceState.mEnabled) {
+ deviceState.mEnabled = false;
onRoutingUpdated();
mAudioService.persistSpatialAudioDeviceSettings();
- logDeviceState(deviceUpdated, "removeCompatibleAudioDevice");
+ logDeviceState(deviceState, "removeCompatibleAudioDevice");
}
}
/**
+ * Returns a possibly aliased device type which is used
+ * for spatial audio settings (or TYPE_UNKNOWN if it doesn't exist).
+ */
+ private static @AudioDeviceInfo.AudioDeviceType int getCanonicalDeviceType(int deviceType) {
+ if (isWireless(deviceType)) return deviceType;
+
+ final int spatMode = SPAT_MODE_FOR_DEVICE_TYPE.get(deviceType, Integer.MIN_VALUE);
+ if (spatMode == SpatializationMode.SPATIALIZER_TRANSAURAL) {
+ return AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+ } else if (spatMode == SpatializationMode.SPATIALIZER_BINAURAL) {
+ return AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
+ }
+ return AudioDeviceInfo.TYPE_UNKNOWN;
+ }
+
+ /**
+ * Returns the Spatial Audio device state for an audio device attributes
+ * or null if it does not exist.
+ */
+ @GuardedBy("this")
+ @Nullable
+ private SADeviceState findDeviceStateForAudioDeviceAttributes(AudioDeviceAttributes ada) {
+ final int deviceType = ada.getType();
+ final boolean isWireless = isWireless(deviceType);
+ final int canonicalDeviceType = getCanonicalDeviceType(deviceType);
+
+ for (SADeviceState deviceState : mSADevices) {
+ if (deviceState.mDeviceType == canonicalDeviceType
+ && (!isWireless || ada.getAddress().equals(deviceState.mDeviceAddress))) {
+ return deviceState;
+ }
+ }
+ return null;
+ }
+
+ /**
* Return if Spatial Audio is enabled and available for the given device
* @param ada
* @return a pair of boolean, 1/ enabled? 2/ available?
*/
private synchronized Pair<Boolean, Boolean> evaluateState(AudioDeviceAttributes ada) {
- // if not a wireless device, this value will be overwritten to map the type
- // to TYPE_BUILTIN_SPEAKER or TYPE_WIRED_HEADPHONES
- @AudioDeviceInfo.AudioDeviceType int deviceType = ada.getType();
-
- // if not a wireless device: find if media device is in the speaker, wired headphones
- if (!isWireless(deviceType)) {
- // is the device type capable of doing SA?
- if (!mSACapableDeviceTypes.contains(deviceType)) {
- Log.i(TAG, "Device incompatible with Spatial Audio dev:" + ada);
- return new Pair<>(false, false);
- }
- // what spatialization mode to use for this device?
- final int spatMode = SPAT_MODE_FOR_DEVICE_TYPE.get(deviceType, Integer.MIN_VALUE);
- if (spatMode == Integer.MIN_VALUE) {
- // error case, device not found
- Log.e(TAG, "no spatialization mode found for device type:" + deviceType);
- return new Pair<>(false, false);
- }
- // map the spatialization mode to the SPEAKER or HEADPHONES device
- if (spatMode == SpatializationMode.SPATIALIZER_TRANSAURAL) {
- deviceType = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
- } else {
- deviceType = AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
- }
- } else { // wireless device
- if (isWirelessSpeaker(deviceType) && !mTransauralSupported) {
- Log.i(TAG, "Device incompatible with Spatial Audio (no transaural) dev:"
- + ada);
- return new Pair<>(false, false);
- }
- if (!mBinauralSupported) {
- Log.i(TAG, "Device incompatible with Spatial Audio (no binaural) dev:"
- + ada);
- return new Pair<>(false, false);
- }
+ final @AudioDeviceInfo.AudioDeviceType int deviceType = ada.getType();
+ // is the device type capable of doing SA?
+ if (!mSACapableDeviceTypes.contains(deviceType)) {
+ Log.i(TAG, "Device incompatible with Spatial Audio dev:" + ada);
+ return new Pair<>(false, false);
}
-
- boolean enabled = false;
- boolean available = false;
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- available = true;
- enabled = deviceState.mEnabled;
- break;
- }
+ // what spatialization mode to use for this device?
+ final int spatMode = SPAT_MODE_FOR_DEVICE_TYPE.get(deviceType, Integer.MIN_VALUE);
+ if (spatMode == Integer.MIN_VALUE) {
+ // error case, device not found
+ Log.e(TAG, "no spatialization mode found for device type:" + deviceType);
+ return new Pair<>(false, false);
+ }
+ final SADeviceState deviceState = findDeviceStateForAudioDeviceAttributes(ada);
+ if (deviceState == null) {
+ // no matching device state?
+ Log.i(TAG, "no spatialization device state found for Spatial Audio device:" + ada);
+ return new Pair<>(false, false);
}
- return new Pair<>(enabled, available);
+ // found the matching device state.
+ return new Pair<>(deviceState.mEnabled, true /* available */);
}
private synchronized void addWirelessDeviceIfNew(@NonNull AudioDeviceAttributes ada) {
if (!isDeviceCompatibleWithSpatializationModes(ada)) {
return;
}
- boolean knownDevice = false;
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- knownDevice = true;
- break;
+ if (findDeviceStateForAudioDeviceAttributes(ada) == null) {
+ // wireless device types should be canonical, but we translate to be sure.
+ final int canonicalDeviceType = getCanonicalDeviceType((ada.getType()));
+ if (canonicalDeviceType == AudioDeviceInfo.TYPE_UNKNOWN) {
+ Log.e(TAG, "addWirelessDeviceIfNew with incompatible AudioDeviceAttributes "
+ + ada);
+ return;
}
- }
- if (!knownDevice) {
- final SADeviceState deviceState = new SADeviceState(ada.getType(), ada.getAddress());
+ final SADeviceState deviceState =
+ new SADeviceState(canonicalDeviceType, ada.getAddress());
mSADevices.add(deviceState);
mAudioService.persistSpatialAudioDeviceSettings();
logDeviceState(deviceState, "addWirelessDeviceIfNew"); // may be updated later.
@@ -699,12 +703,7 @@ public class SpatializerHelper {
if (ada.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
return false;
}
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- return true;
- }
- }
- return false;
+ return findDeviceStateForAudioDeviceAttributes(ada) != null;
}
private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes,
@@ -1086,20 +1085,18 @@ public class SpatializerHelper {
Log.v(TAG, "no headtracking support, ignoring setHeadTrackerEnabled to " + enabled
+ " for " + ada);
}
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- if (!deviceState.mHasHeadTracker) {
- Log.e(TAG, "Called setHeadTrackerEnabled enabled:" + enabled
- + " device:" + ada + " on a device without headtracker");
- return;
- }
- Log.i(TAG, "setHeadTrackerEnabled enabled:" + enabled + " device:" + ada);
- deviceState.mHeadTrackerEnabled = enabled;
- mAudioService.persistSpatialAudioDeviceSettings();
- logDeviceState(deviceState, "setHeadTrackerEnabled");
- break;
- }
+ final SADeviceState deviceState = findDeviceStateForAudioDeviceAttributes(ada);
+ if (deviceState == null) return;
+ if (!deviceState.mHasHeadTracker) {
+ Log.e(TAG, "Called setHeadTrackerEnabled enabled:" + enabled
+ + " device:" + ada + " on a device without headtracker");
+ return;
}
+ Log.i(TAG, "setHeadTrackerEnabled enabled:" + enabled + " device:" + ada);
+ deviceState.mHeadTrackerEnabled = enabled;
+ mAudioService.persistSpatialAudioDeviceSettings();
+ logDeviceState(deviceState, "setHeadTrackerEnabled");
+
// check current routing to see if it affects the headtracking mode
if (ROUTING_DEVICES[0].getType() == ada.getType()
&& ROUTING_DEVICES[0].getAddress().equals(ada.getAddress())) {
@@ -1113,12 +1110,8 @@ public class SpatializerHelper {
Log.v(TAG, "no headtracking support, hasHeadTracker always false for " + ada);
return false;
}
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- return deviceState.mHasHeadTracker;
- }
- }
- return false;
+ final SADeviceState deviceState = findDeviceStateForAudioDeviceAttributes(ada);
+ return deviceState != null && deviceState.mHasHeadTracker;
}
/**
@@ -1131,15 +1124,14 @@ public class SpatializerHelper {
Log.v(TAG, "no headtracking support, setHasHeadTracker always false for " + ada);
return false;
}
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- if (!deviceState.mHasHeadTracker) {
- deviceState.mHasHeadTracker = true;
- mAudioService.persistSpatialAudioDeviceSettings();
- logDeviceState(deviceState, "setHasHeadTracker");
- }
- return deviceState.mHeadTrackerEnabled;
+ final SADeviceState deviceState = findDeviceStateForAudioDeviceAttributes(ada);
+ if (deviceState != null) {
+ if (!deviceState.mHasHeadTracker) {
+ deviceState.mHasHeadTracker = true;
+ mAudioService.persistSpatialAudioDeviceSettings();
+ logDeviceState(deviceState, "setHasHeadTracker");
}
+ return deviceState.mHeadTrackerEnabled;
}
Log.e(TAG, "setHasHeadTracker: device not found for:" + ada);
return false;
@@ -1150,15 +1142,9 @@ public class SpatializerHelper {
Log.v(TAG, "no headtracking support, isHeadTrackerEnabled always false for " + ada);
return false;
}
- for (SADeviceState deviceState : mSADevices) {
- if (deviceState.matchesAudioDeviceAttributes(ada)) {
- if (!deviceState.mHasHeadTracker) {
- return false;
- }
- return deviceState.mHeadTrackerEnabled;
- }
- }
- return false;
+ final SADeviceState deviceState = findDeviceStateForAudioDeviceAttributes(ada);
+ return deviceState != null
+ && deviceState.mHasHeadTracker && deviceState.mHeadTrackerEnabled;
}
synchronized boolean isHeadTrackerAvailable() {
@@ -1582,12 +1568,6 @@ public class SpatializerHelper {
mDeviceType, mDeviceAddress == null ? "" : mDeviceAddress);
}
- public boolean matchesAudioDeviceAttributes(AudioDeviceAttributes ada) {
- final int deviceType = ada.getType();
- final boolean wireless = isWireless(deviceType);
- return (deviceType == mDeviceType)
- && (!wireless || ada.getAddress().equals(mDeviceAddress));
- }
}
/*package*/ synchronized String getSADeviceSettings() {
@@ -1608,7 +1588,10 @@ public class SpatializerHelper {
// small list, not worth overhead of Arrays.stream(devSettings)
for (String setting : devSettings) {
SADeviceState devState = SADeviceState.fromPersistedString(setting);
+ // Note if the device is not compatible with spatialization mode
+ // or the device type is not canonical, it is ignored.
if (devState != null
+ && devState.mDeviceType == getCanonicalDeviceType(devState.mDeviceType)
&& isDeviceCompatibleWithSpatializationModes(
devState.getAudioDeviceAttributes())) {
mSADevices.add(devState);
@@ -1645,15 +1628,6 @@ public class SpatializerHelper {
return false;
}
- private static boolean isWirelessSpeaker(@AudioDeviceInfo.AudioDeviceType int deviceType) {
- for (int type : WIRELESS_SPEAKER_TYPES) {
- if (type == deviceType) {
- return true;
- }
- }
- return false;
- }
-
private int getHeadSensorHandleUpdateTracker() {
int headHandle = -1;
UUID routingDeviceUuid = mAudioService.getDeviceSensorUuid(ROUTING_DEVICES[0]);
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 076ac2b4bfe7..6f9a17682dd7 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -43,6 +43,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -63,6 +64,7 @@ import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
+import android.util.SafetyProtectionUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -1181,9 +1183,19 @@ public class ClipboardService extends SystemService {
String message =
getContext().getString(R.string.pasted_from_clipboard, callingAppLabel);
Slog.i(TAG, message);
- Toast.makeText(
- getContext(), UiThread.get().getLooper(), message, Toast.LENGTH_SHORT)
- .show();
+ Toast toastToShow;
+ if (SafetyProtectionUtils.shouldShowSafetyProtectionResources(getContext())) {
+ Drawable safetyProtectionIcon = getContext()
+ .getDrawable(R.drawable.ic_safety_protection);
+ toastToShow = Toast.makeCustomToastWithIcon(getContext(),
+ UiThread.get().getLooper(), message,
+ Toast.LENGTH_SHORT, safetyProtectionIcon);
+ } else {
+ toastToShow = Toast.makeText(
+ getContext(), UiThread.get().getLooper(), message,
+ Toast.LENGTH_SHORT);
+ }
+ toastToShow.show();
} catch (PackageManager.NameNotFoundException e) {
// do nothing
}
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 6fd88411593f..114690a03324 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -46,7 +46,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.os.BackgroundThread;
import com.android.server.EventLogTags;
-import com.android.server.display.DisplayPowerController.BrightnessEvent;
+import com.android.server.display.brightness.BrightnessEvent;
import java.io.PrintWriter;
@@ -337,14 +337,15 @@ class AutomaticBrightnessController {
float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
if (brightnessEvent != null) {
- brightnessEvent.lux =
- mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT;
- brightnessEvent.preThresholdLux = mPreThresholdLux;
- brightnessEvent.preThresholdBrightness = mPreThresholdBrightness;
- brightnessEvent.recommendedBrightness = mScreenAutoBrightness;
- brightnessEvent.flags |= (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0)
+ brightnessEvent.setLux(
+ mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ brightnessEvent.setPreThresholdLux(mPreThresholdLux);
+ brightnessEvent.setPreThresholdBrightness(mPreThresholdBrightness);
+ brightnessEvent.setRecommendedBrightness(mScreenAutoBrightness);
+ brightnessEvent.setFlags(brightnessEvent.getFlags()
+ | (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0)
| (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE
- ? BrightnessEvent.FLAG_DOZE_SCALE : 0);
+ ? BrightnessEvent.FLAG_DOZE_SCALE : 0));
}
if (!mAmbientLuxValid) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 95c8fef12976..4e33fd07c28e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -67,6 +67,8 @@ import com.android.internal.util.RingBuffer;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
+import com.android.server.display.brightness.BrightnessEvent;
+import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
import com.android.server.display.utils.SensorUtils;
@@ -76,7 +78,6 @@ import com.android.server.display.whitebalance.DisplayWhiteBalanceSettings;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
-import java.util.Objects;
/**
* Controls the power state of the display.
@@ -1430,7 +1431,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// we broadcast this change through setting.
final float unthrottledBrightnessState = brightnessState;
if (mBrightnessThrottler.isThrottled()) {
- mTempBrightnessEvent.thermalMax = mBrightnessThrottler.getBrightnessCap();
+ mTempBrightnessEvent.setThermalMax(mBrightnessThrottler.getBrightnessCap());
brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap());
mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED);
if (!mAppliedThrottling) {
@@ -1551,8 +1552,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
// done in HighBrightnessModeController.
if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
- && ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0
- || (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) {
+ && ((mBrightnessReason.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
+ || (mBrightnessReason.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
+ == 0)) {
// We want to scale HDR brightness level with the SDR level
animateValue = mHbmController.getHdrBrightnessValue();
}
@@ -1615,7 +1617,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
+ mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
+ "', previous reason: '" + mBrightnessReason + "'.");
mBrightnessReason.set(mBrightnessReasonTemp);
- } else if (mBrightnessReasonTemp.reason == BrightnessReason.REASON_MANUAL
+ } else if (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_MANUAL
&& userSetBrightnessChanged) {
Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment.");
}
@@ -1624,17 +1626,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Log brightness events when a detail of significance has changed. Generally this is the
// brightness itself changing, but also includes data like HBM cap, thermal throttling
// brightness cap, RBC state, etc.
- mTempBrightnessEvent.time = System.currentTimeMillis();
- mTempBrightnessEvent.brightness = brightnessState;
- mTempBrightnessEvent.reason.set(mBrightnessReason);
- mTempBrightnessEvent.hbmMax = mHbmController.getCurrentBrightnessMax();
- mTempBrightnessEvent.hbmMode = mHbmController.getHighBrightnessMode();
- mTempBrightnessEvent.flags |= (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0);
+ mTempBrightnessEvent.setTime(System.currentTimeMillis());
+ mTempBrightnessEvent.setBrightness(brightnessState);
+ mTempBrightnessEvent.setReason(mBrightnessReason);
+ mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax());
+ mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode());
+ mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
+ | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0));
// Temporary is what we use during slider interactions. We avoid logging those so that
// we don't spam logcat when the slider is being used.
boolean tempToTempTransition =
- mTempBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY
- && mLastBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY;
+ mTempBrightnessEvent.getReason().getReason() == BrightnessReason.REASON_TEMPORARY
+ && mLastBrightnessEvent.getReason().getReason()
+ == BrightnessReason.REASON_TEMPORARY;
if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition)
|| brightnessAdjustmentFlags != 0) {
mLastBrightnessEvent.copyFrom(mTempBrightnessEvent);
@@ -1642,8 +1646,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Adjustment flags (and user-set flag) only get added after the equality checks since
// they are transient.
- newEvent.adjustmentFlags = brightnessAdjustmentFlags;
- newEvent.flags |= (userSetBrightnessChanged ? BrightnessEvent.FLAG_USER_SET : 0);
+ newEvent.setAdjustmentFlags(brightnessAdjustmentFlags);
+ newEvent.setFlags(newEvent.getFlags() | (userSetBrightnessChanged
+ ? BrightnessEvent.FLAG_USER_SET : 0));
Slog.i(TAG, newEvent.toString(/* includeTime= */ false));
if (mBrightnessEventRingBuffer != null) {
@@ -2734,117 +2739,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
- class BrightnessEvent {
- static final int FLAG_RBC = 0x1;
- static final int FLAG_INVALID_LUX = 0x2;
- static final int FLAG_DOZE_SCALE = 0x3;
- static final int FLAG_USER_SET = 0x4;
-
- public final BrightnessReason reason = new BrightnessReason();
-
- public int displayId;
- public float lux;
- public float preThresholdLux;
- public long time;
- public float brightness;
- public float recommendedBrightness;
- public float preThresholdBrightness;
- public float hbmMax;
- public float thermalMax;
- public int hbmMode;
- public int flags;
- public int adjustmentFlags;
-
- BrightnessEvent(BrightnessEvent that) {
- copyFrom(that);
- }
-
- BrightnessEvent(int displayId) {
- this.displayId = displayId;
- reset();
- }
-
- void copyFrom(BrightnessEvent that) {
- displayId = that.displayId;
- time = that.time;
- lux = that.lux;
- preThresholdLux = that.preThresholdLux;
- brightness = that.brightness;
- recommendedBrightness = that.recommendedBrightness;
- preThresholdBrightness = that.preThresholdBrightness;
- hbmMax = that.hbmMax;
- thermalMax = that.thermalMax;
- flags = that.flags;
- hbmMode = that.hbmMode;
- reason.set(that.reason);
- adjustmentFlags = that.adjustmentFlags;
- }
-
- void reset() {
- time = SystemClock.uptimeMillis();
- brightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- recommendedBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- lux = 0;
- preThresholdLux = 0;
- preThresholdBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- hbmMax = PowerManager.BRIGHTNESS_MAX;
- thermalMax = PowerManager.BRIGHTNESS_MAX;
- flags = 0;
- hbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
- reason.set(null);
- adjustmentFlags = 0;
- }
-
- boolean equalsMainData(BrightnessEvent that) {
- // This equals comparison purposefully ignores time since it is regularly changing and
- // we don't want to log a brightness event just because the time changed.
- return displayId == that.displayId
- && Float.floatToRawIntBits(brightness)
- == Float.floatToRawIntBits(that.brightness)
- && Float.floatToRawIntBits(recommendedBrightness)
- == Float.floatToRawIntBits(that.recommendedBrightness)
- && Float.floatToRawIntBits(preThresholdBrightness)
- == Float.floatToRawIntBits(that.preThresholdBrightness)
- && Float.floatToRawIntBits(lux) == Float.floatToRawIntBits(that.lux)
- && Float.floatToRawIntBits(preThresholdLux)
- == Float.floatToRawIntBits(that.preThresholdLux)
- && Float.floatToRawIntBits(hbmMax) == Float.floatToRawIntBits(that.hbmMax)
- && hbmMode == that.hbmMode
- && Float.floatToRawIntBits(thermalMax)
- == Float.floatToRawIntBits(that.thermalMax)
- && flags == that.flags
- && adjustmentFlags == that.adjustmentFlags
- && reason.equals(that.reason);
- }
-
- public String toString(boolean includeTime) {
- return (includeTime ? TimeUtils.formatForLogging(time) + " - " : "")
- + "BrightnessEvent: "
- + "disp=" + displayId
- + ", brt=" + brightness + ((flags & FLAG_USER_SET) != 0 ? "(user_set)" : "")
- + ", rcmdBrt=" + recommendedBrightness
- + ", preBrt=" + preThresholdBrightness
- + ", lux=" + lux
- + ", preLux=" + preThresholdLux
- + ", hbmMax=" + hbmMax
- + ", hbmMode=" + BrightnessInfo.hbmToString(hbmMode)
- + ", thrmMax=" + thermalMax
- + ", flags=" + flagsToString()
- + ", reason=" + reason.toString(adjustmentFlags);
- }
-
- @Override
- public String toString() {
- return toString(/* includeTime */ true);
- }
- private String flagsToString() {
- return ((flags & FLAG_USER_SET) != 0 ? "user_set " : "")
- + ((flags & FLAG_RBC) != 0 ? "rbc " : "")
- + ((flags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "")
- + ((flags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : "");
- }
- }
private final class DisplayControllerHandler extends Handler {
public DisplayControllerHandler(Looper looper) {
@@ -2996,137 +2891,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
- /**
- * Stores data about why the brightness was changed. Made up of one main
- * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*}
- * modifiers.
- */
- private final class BrightnessReason {
- static final int REASON_UNKNOWN = 0;
- static final int REASON_MANUAL = 1;
- static final int REASON_DOZE = 2;
- static final int REASON_DOZE_DEFAULT = 3;
- static final int REASON_AUTOMATIC = 4;
- static final int REASON_SCREEN_OFF = 5;
- static final int REASON_VR = 6;
- static final int REASON_OVERRIDE = 7;
- static final int REASON_TEMPORARY = 8;
- static final int REASON_BOOST = 9;
- static final int REASON_MAX = REASON_BOOST;
-
- static final int MODIFIER_DIMMED = 0x1;
- static final int MODIFIER_LOW_POWER = 0x2;
- static final int MODIFIER_HDR = 0x4;
- static final int MODIFIER_THROTTLED = 0x8;
- static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR
- | MODIFIER_THROTTLED;
-
- // ADJUSTMENT_*
- // These things can happen at any point, even if the main brightness reason doesn't
- // fundamentally change, so they're not stored.
-
- // Auto-brightness adjustment factor changed
- static final int ADJUSTMENT_AUTO_TEMP = 0x1;
- // Temporary adjustment to the auto-brightness adjustment factor.
- static final int ADJUSTMENT_AUTO = 0x2;
-
- // One of REASON_*
- public int reason;
- // Any number of MODIFIER_*
- public int modifier;
-
- public void set(BrightnessReason other) {
- setReason(other == null ? REASON_UNKNOWN : other.reason);
- setModifier(other == null ? 0 : other.modifier);
- }
-
- public void setReason(int reason) {
- if (reason < REASON_UNKNOWN || reason > REASON_MAX) {
- Slog.w(TAG, "brightness reason out of bounds: " + reason);
- } else {
- this.reason = reason;
- }
- }
-
- public void setModifier(int modifier) {
- if ((modifier & ~MODIFIER_MASK) != 0) {
- Slog.w(TAG, "brightness modifier out of bounds: 0x"
- + Integer.toHexString(modifier));
- } else {
- this.modifier = modifier;
- }
- }
-
- public void addModifier(int modifier) {
- setModifier(modifier | this.modifier);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof BrightnessReason)) {
- return false;
- }
- BrightnessReason other = (BrightnessReason) obj;
- return other.reason == reason && other.modifier == modifier;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(reason, modifier);
- }
-
- @Override
- public String toString() {
- return toString(0);
- }
-
- public String toString(int adjustments) {
- final StringBuilder sb = new StringBuilder();
- sb.append(reasonToString(reason));
- sb.append(" [");
- if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) {
- sb.append(" temp_adj");
- }
- if ((adjustments & ADJUSTMENT_AUTO) != 0) {
- sb.append(" auto_adj");
- }
- if ((modifier & MODIFIER_LOW_POWER) != 0) {
- sb.append(" low_pwr");
- }
- if ((modifier & MODIFIER_DIMMED) != 0) {
- sb.append(" dim");
- }
- if ((modifier & MODIFIER_HDR) != 0) {
- sb.append(" hdr");
- }
- if ((modifier & MODIFIER_THROTTLED) != 0) {
- sb.append(" throttled");
- }
- int strlen = sb.length();
- if (sb.charAt(strlen - 1) == '[') {
- sb.setLength(strlen - 2);
- } else {
- sb.append(" ]");
- }
- return sb.toString();
- }
-
- private String reasonToString(int reason) {
- switch (reason) {
- case REASON_MANUAL: return "manual";
- case REASON_DOZE: return "doze";
- case REASON_DOZE_DEFAULT: return "doze_default";
- case REASON_AUTOMATIC: return "automatic";
- case REASON_SCREEN_OFF: return "screen_off";
- case REASON_VR: return "vr";
- case REASON_OVERRIDE: return "override";
- case REASON_TEMPORARY: return "temporary";
- case REASON_BOOST: return "boost";
- default: return Integer.toString(reason);
- }
- }
- }
-
static class CachedBrightnessInfo {
public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
public MutableFloat adjustedBrightness =
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
new file mode 100644
index 000000000000..6698612dc652
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
@@ -0,0 +1,262 @@
+/*
+ * 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.display.brightness;
+
+import android.hardware.display.BrightnessInfo;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.TimeUtils;
+
+/**
+ * Represents a particular brightness change event.
+ */
+public final class BrightnessEvent {
+ public static final int FLAG_RBC = 0x1;
+ public static final int FLAG_INVALID_LUX = 0x2;
+ public static final int FLAG_DOZE_SCALE = 0x3;
+ public static final int FLAG_USER_SET = 0x4;
+
+ private BrightnessReason mReason = new BrightnessReason();
+ private int mDisplayId;
+ private float mLux;
+ private float mPreThresholdLux;
+ private long mTime;
+ private float mBrightness;
+ private float mRecommendedBrightness;
+ private float mPreThresholdBrightness;
+ private float mHbmMax;
+ private float mThermalMax;
+ private int mHbmMode;
+ private int mFlags;
+ private int mAdjustmentFlags;
+
+ public BrightnessEvent(BrightnessEvent that) {
+ copyFrom(that);
+ }
+
+ public BrightnessEvent(int displayId) {
+ this.mDisplayId = displayId;
+ reset();
+ }
+
+ /**
+ * A utility to clone a brightness event into another event
+ *
+ * @param that BrightnessEvent which is to be copied
+ */
+ public void copyFrom(BrightnessEvent that) {
+ mDisplayId = that.getDisplayId();
+ mTime = that.getTime();
+ mLux = that.getLux();
+ mPreThresholdLux = that.getPreThresholdLux();
+ mBrightness = that.getBrightness();
+ mRecommendedBrightness = that.getRecommendedBrightness();
+ mPreThresholdBrightness = that.getPreThresholdBrightness();
+ mHbmMax = that.getHbmMax();
+ mThermalMax = that.getThermalMax();
+ mFlags = that.getFlags();
+ mHbmMode = that.getHbmMode();
+ mReason.set(that.getReason());
+ mAdjustmentFlags = that.getAdjustmentFlags();
+ }
+
+ /**
+ * A utility to reset the BrightnessEvent to default values
+ */
+ public void reset() {
+ mTime = SystemClock.uptimeMillis();
+ mBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ mRecommendedBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ mLux = 0;
+ mPreThresholdLux = 0;
+ mPreThresholdBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ mHbmMax = PowerManager.BRIGHTNESS_MAX;
+ mThermalMax = PowerManager.BRIGHTNESS_MAX;
+ mFlags = 0;
+ mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
+ mReason.set(null);
+ mAdjustmentFlags = 0;
+ }
+
+ /**
+ * A utility to compare two BrightnessEvents. This purposefully ignores comparing time as the
+ * two events might have been created at different times, but essentially hold the same
+ * underlying values
+ *
+ * @param that The brightnessEvent with which the current brightnessEvent is to be compared
+ * @return A boolean value representing if the two events are same or not.
+ */
+ public boolean equalsMainData(BrightnessEvent that) {
+ // This equals comparison purposefully ignores time since it is regularly changing and
+ // we don't want to log a brightness event just because the time changed.
+ return mDisplayId == that.mDisplayId
+ && Float.floatToRawIntBits(mBrightness)
+ == Float.floatToRawIntBits(that.mBrightness)
+ && Float.floatToRawIntBits(mRecommendedBrightness)
+ == Float.floatToRawIntBits(that.mRecommendedBrightness)
+ && Float.floatToRawIntBits(mPreThresholdBrightness)
+ == Float.floatToRawIntBits(that.mPreThresholdBrightness)
+ && Float.floatToRawIntBits(mLux) == Float.floatToRawIntBits(that.mLux)
+ && Float.floatToRawIntBits(mPreThresholdLux)
+ == Float.floatToRawIntBits(that.mPreThresholdLux)
+ && Float.floatToRawIntBits(mHbmMax) == Float.floatToRawIntBits(that.mHbmMax)
+ && mHbmMode == that.mHbmMode
+ && Float.floatToRawIntBits(mThermalMax)
+ == Float.floatToRawIntBits(that.mThermalMax)
+ && mFlags == that.mFlags
+ && mAdjustmentFlags == that.mAdjustmentFlags
+ && mReason.equals(that.mReason);
+ }
+
+ /**
+ * A utility to stringify a BrightnessEvent
+ * @param includeTime Indicates if the time field is to be added in the stringify version of the
+ * BrightnessEvent
+ * @return A stringified BrightnessEvent
+ */
+ public String toString(boolean includeTime) {
+ return (includeTime ? TimeUtils.formatForLogging(mTime) + " - " : "")
+ + "BrightnessEvent: "
+ + "disp=" + mDisplayId
+ + ", brt=" + mBrightness + ((mFlags & FLAG_USER_SET) != 0 ? "(user_set)" : "")
+ + ", rcmdBrt=" + mRecommendedBrightness
+ + ", preBrt=" + mPreThresholdBrightness
+ + ", lux=" + mLux
+ + ", preLux=" + mPreThresholdLux
+ + ", hbmMax=" + mHbmMax
+ + ", hbmMode=" + BrightnessInfo.hbmToString(mHbmMode)
+ + ", thrmMax=" + mThermalMax
+ + ", flags=" + flagsToString()
+ + ", reason=" + mReason.toString(mAdjustmentFlags);
+ }
+
+ @Override
+ public String toString() {
+ return toString(/* includeTime */ true);
+ }
+
+ public void setReason(BrightnessReason reason) {
+ this.mReason = reason;
+ }
+
+ public BrightnessReason getReason() {
+ return mReason;
+ }
+
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ public void setDisplayId(int displayId) {
+ this.mDisplayId = displayId;
+ }
+
+ public float getLux() {
+ return mLux;
+ }
+
+ public void setLux(float lux) {
+ this.mLux = lux;
+ }
+
+ public float getPreThresholdLux() {
+ return mPreThresholdLux;
+ }
+
+ public void setPreThresholdLux(float preThresholdLux) {
+ this.mPreThresholdLux = preThresholdLux;
+ }
+
+ public long getTime() {
+ return mTime;
+ }
+
+ public void setTime(long time) {
+ this.mTime = time;
+ }
+
+ public float getBrightness() {
+ return mBrightness;
+ }
+
+ public void setBrightness(float brightness) {
+ this.mBrightness = brightness;
+ }
+
+ public float getRecommendedBrightness() {
+ return mRecommendedBrightness;
+ }
+
+ public void setRecommendedBrightness(float recommendedBrightness) {
+ this.mRecommendedBrightness = recommendedBrightness;
+ }
+
+ public float getPreThresholdBrightness() {
+ return mPreThresholdBrightness;
+ }
+
+ public void setPreThresholdBrightness(float preThresholdBrightness) {
+ this.mPreThresholdBrightness = preThresholdBrightness;
+ }
+
+ public float getHbmMax() {
+ return mHbmMax;
+ }
+
+ public void setHbmMax(float hbmMax) {
+ this.mHbmMax = hbmMax;
+ }
+
+ public float getThermalMax() {
+ return mThermalMax;
+ }
+
+ public void setThermalMax(float thermalMax) {
+ this.mThermalMax = thermalMax;
+ }
+
+ public int getHbmMode() {
+ return mHbmMode;
+ }
+
+ public void setHbmMode(int hbmMode) {
+ this.mHbmMode = hbmMode;
+ }
+
+ public int getFlags() {
+ return mFlags;
+ }
+
+ public void setFlags(int flags) {
+ this.mFlags = flags;
+ }
+
+ public int getAdjustmentFlags() {
+ return mAdjustmentFlags;
+ }
+
+ public void setAdjustmentFlags(int adjustmentFlags) {
+ this.mAdjustmentFlags = adjustmentFlags;
+ }
+
+ private String flagsToString() {
+ return ((mFlags & FLAG_USER_SET) != 0 ? "user_set " : "")
+ + ((mFlags & FLAG_RBC) != 0 ? "rbc " : "")
+ + ((mFlags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "")
+ + ((mFlags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : "");
+ }
+}
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessReason.java b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
new file mode 100644
index 000000000000..d8eacd930d40
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
@@ -0,0 +1,200 @@
+/*
+ * 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.display.brightness;
+
+import android.util.Slog;
+
+import java.util.Objects;
+
+/**
+ * Stores data about why the brightness was changed. Made up of one main
+ * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*}
+ * modifiers.
+ */
+public final class BrightnessReason {
+ private static final String TAG = "BrightnessReason";
+
+ public static final int REASON_UNKNOWN = 0;
+ public static final int REASON_MANUAL = 1;
+ public static final int REASON_DOZE = 2;
+ public static final int REASON_DOZE_DEFAULT = 3;
+ public static final int REASON_AUTOMATIC = 4;
+ public static final int REASON_SCREEN_OFF = 5;
+ public static final int REASON_VR = 6;
+ public static final int REASON_OVERRIDE = 7;
+ public static final int REASON_TEMPORARY = 8;
+ public static final int REASON_BOOST = 9;
+ public static final int REASON_MAX = REASON_BOOST;
+
+ public static final int MODIFIER_DIMMED = 0x1;
+ public static final int MODIFIER_LOW_POWER = 0x2;
+ public static final int MODIFIER_HDR = 0x4;
+ public static final int MODIFIER_THROTTLED = 0x8;
+ public static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR
+ | MODIFIER_THROTTLED;
+
+ // ADJUSTMENT_*
+ // These things can happen at any point, even if the main brightness reason doesn't
+ // fundamentally change, so they're not stored.
+
+ // Auto-brightness adjustment factor changed
+ public static final int ADJUSTMENT_AUTO_TEMP = 0x1;
+ // Temporary adjustment to the auto-brightness adjustment factor.
+ public static final int ADJUSTMENT_AUTO = 0x2;
+
+ // One of REASON_*
+ private int mReason;
+ // Any number of MODIFIER_*
+ private int mModifier;
+
+ /**
+ * A utility to clone a BrightnessReason from another BrightnessReason event
+ *
+ * @param other The BrightnessReason object which is to be cloned
+ */
+ public void set(BrightnessReason other) {
+ setReason(other == null ? REASON_UNKNOWN : other.mReason);
+ setModifier(other == null ? 0 : other.mModifier);
+ }
+
+ /**
+ * A utility to add a modifier to the BrightnessReason object
+ *
+ * @param modifier The modifier which is to be added
+ */
+ public void addModifier(int modifier) {
+ setModifier(modifier | this.mModifier);
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof BrightnessReason)) {
+ return false;
+ }
+ BrightnessReason other = (BrightnessReason) obj;
+ return other.mReason == mReason && other.mModifier == mModifier;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mReason, mModifier);
+ }
+
+ @Override
+ public String toString() {
+ return toString(0);
+ }
+
+ /**
+ * A utility to stringify a BrightnessReason
+ *
+ * @param adjustments Indicates if the adjustments field is to be added in the stringify version
+ * of the BrightnessReason
+ * @return A stringified BrightnessReason
+ */
+ public String toString(int adjustments) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append(reasonToString(mReason));
+ sb.append(" [");
+ if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) {
+ sb.append(" temp_adj");
+ }
+ if ((adjustments & ADJUSTMENT_AUTO) != 0) {
+ sb.append(" auto_adj");
+ }
+ if ((mModifier & MODIFIER_LOW_POWER) != 0) {
+ sb.append(" low_pwr");
+ }
+ if ((mModifier & MODIFIER_DIMMED) != 0) {
+ sb.append(" dim");
+ }
+ if ((mModifier & MODIFIER_HDR) != 0) {
+ sb.append(" hdr");
+ }
+ if ((mModifier & MODIFIER_THROTTLED) != 0) {
+ sb.append(" throttled");
+ }
+ int strlen = sb.length();
+ if (sb.charAt(strlen - 1) == '[') {
+ sb.setLength(strlen - 2);
+ } else {
+ sb.append(" ]");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * A utility to set the reason of the BrightnessReason object
+ *
+ * @param reason The value to which the reason is to be updated.
+ */
+ public void setReason(int reason) {
+ if (reason < REASON_UNKNOWN || reason > REASON_MAX) {
+ Slog.w(TAG, "brightness reason out of bounds: " + reason);
+ } else {
+ this.mReason = reason;
+ }
+ }
+
+ public int getReason() {
+ return mReason;
+ }
+
+ public int getModifier() {
+ return mModifier;
+ }
+
+ /**
+ * A utility to set the modified of the current BrightnessReason object
+ *
+ * @param modifier The value to which the modifier is to be updated
+ */
+ public void setModifier(int modifier) {
+ if ((modifier & ~MODIFIER_MASK) != 0) {
+ Slog.w(TAG, "brightness modifier out of bounds: 0x"
+ + Integer.toHexString(modifier));
+ } else {
+ this.mModifier = modifier;
+ }
+ }
+
+ private String reasonToString(int reason) {
+ switch (reason) {
+ case REASON_MANUAL:
+ return "manual";
+ case REASON_DOZE:
+ return "doze";
+ case REASON_DOZE_DEFAULT:
+ return "doze_default";
+ case REASON_AUTOMATIC:
+ return "automatic";
+ case REASON_SCREEN_OFF:
+ return "screen_off";
+ case REASON_VR:
+ return "vr";
+ case REASON_OVERRIDE:
+ return "override";
+ case REASON_TEMPORARY:
+ return "temporary";
+ case REASON_BOOST:
+ return "boost";
+ default:
+ return Integer.toString(reason);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 44aefccaeaf6..fe9e68d285cd 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -897,17 +897,6 @@ public class InputManagerService extends IInputManager.Stub
throw new IllegalStateException("Injection should not result in TARGET_MISMATCH"
+ " when it is not targeted into to a specific uid.");
}
- // TODO(b/228161340): Remove the fallback of targeting injection into all windows
- // when the caller has the injection permission.
- // Explicitly maintain the same behavior as previous versions of Android, where
- // injection is allowed into all windows if the caller has the INJECT_EVENTS
- // permission, even if it is targeting a certain uid.
- if (checkCallingPermission(android.Manifest.permission.INJECT_EVENTS,
- "injectInputEvent-target-mismatch-fallback")) {
- Slog.w(TAG, "Targeted input event was not directed at a window owned by uid "
- + targetUid + ". Falling back to injecting into all windows.");
- return injectInputEventToTarget(event, mode, Process.INVALID_UID);
- }
throw new IllegalArgumentException(
"Targeted input event injection from pid " + pid
+ " was not directed at a window owned by uid "
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 794c06fec5ae..af95b4f54eb4 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -64,7 +64,6 @@ import android.annotation.EnforcePermission;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
import android.annotation.UiThread;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -1766,8 +1765,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
mLastSwitchUserId = userId;
// mSettings should be created before buildInputMethodListLocked
- mSettings = new InputMethodSettings(
- mRes, context.getContentResolver(), mMethodMap, userId, !mSystemReady);
+ mSettings = new InputMethodSettings(mContext, mMethodMap, userId, !mSystemReady);
updateCurrentProfileIds();
AdditionalSubtypeUtils.load(mAdditionalSubtypeMap, userId);
@@ -2139,8 +2137,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
//TODO(b/197848765): This can be optimized by caching multi-user methodMaps/methodList.
//TODO(b/210039666): use cache.
final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(mContext.getResources(),
- mContext.getContentResolver(), methodMap, userId, true);
+ final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap,
+ userId, true);
final InputMethodInfo imi = methodMap.get(settings.getSelectedInputMethod());
return imi != null && imi.supportsStylusHandwriting();
}
@@ -2172,8 +2170,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
return mSettings.getEnabledInputMethodListLocked();
}
final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(mContext.getResources(),
- mContext.getContentResolver(), methodMap, userId, true);
+ final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap, userId,
+ true);
return settings.getEnabledInputMethodListLocked();
}
@@ -2203,21 +2201,20 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
* @param imiId if null, returns enabled subtypes for the current {@link InputMethodInfo}.
* @param allowsImplicitlySelectedSubtypes {@code true} to return the implicitly selected
* subtypes.
+ * @param userId the user ID to be queried about.
*/
@Override
public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
- boolean allowsImplicitlySelectedSubtypes) {
- final int callingUserId = UserHandle.getCallingUserId();
+ boolean allowsImplicitlySelectedSubtypes, @UserIdInt int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
+
synchronized (ImfLock.class) {
- final int[] resolvedUserIds = InputMethodUtils.resolveUserId(callingUserId,
- mSettings.getCurrentUserId(), null);
- if (resolvedUserIds.length != 1) {
- return Collections.emptyList();
- }
final long ident = Binder.clearCallingIdentity();
try {
return getEnabledInputMethodSubtypeListLocked(imiId,
- allowsImplicitlySelectedSubtypes, resolvedUserIds[0]);
+ allowsImplicitlySelectedSubtypes, userId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -2239,17 +2236,17 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
return Collections.emptyList();
}
return mSettings.getEnabledInputMethodSubtypeListLocked(
- mContext, imi, allowsImplicitlySelectedSubtypes);
+ imi, allowsImplicitlySelectedSubtypes);
}
final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
final InputMethodInfo imi = methodMap.get(imiId);
if (imi == null) {
return Collections.emptyList();
}
- final InputMethodSettings settings = new InputMethodSettings(mContext.getResources(),
- mContext.getContentResolver(), methodMap, userId, true);
+ final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap, userId,
+ true);
return settings.getEnabledInputMethodSubtypeListLocked(
- mContext, imi, allowsImplicitlySelectedSubtypes);
+ imi, allowsImplicitlySelectedSubtypes);
}
/**
@@ -3068,7 +3065,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
for (int i = 0; i < numImes; ++i) {
final InputMethodInfo imi = imes.get(i);
final List<InputMethodSubtype> subtypes =
- mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true);
+ mSettings.getEnabledInputMethodSubtypeListLocked(imi, true);
final int subtypeCount = subtypes.size();
if (subtypeCount == 0) {
++nonAuxCount;
@@ -3576,23 +3573,18 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
int windowFlags, @Nullable EditorInfo editorInfo,
IRemoteInputConnection inputConnection,
IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion,
+ int unverifiedTargetSdkVersion, @UserIdInt int userId,
@NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
- return startInputOrWindowGainedFocusInternal(startInputReason, client, windowToken,
- startInputFlags, softInputMode, windowFlags, editorInfo, inputConnection,
- remoteAccessibilityInputConnection, unverifiedTargetSdkVersion,
- imeDispatcher);
- }
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+
+ if (editorInfo == null || editorInfo.targetInputMethodUser == null
+ || editorInfo.targetInputMethodUser.getIdentifier() != userId) {
+ throw new InvalidParameterException("EditorInfo#targetInputMethodUser must also be "
+ + "specified for cross-user startInputOrWindowGainedFocus()");
+ }
+ }
- @NonNull
- private InputBindResult startInputOrWindowGainedFocusInternal(
- @StartInputReason int startInputReason, IInputMethodClient client, IBinder windowToken,
- @StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode,
- int windowFlags, @Nullable EditorInfo editorInfo,
- @Nullable IRemoteInputConnection inputConnection,
- @Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion,
- @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
if (windowToken == null) {
Slog.e(TAG, "windowToken cannot be null.");
return InputBindResult.NULL;
@@ -3602,26 +3594,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
"IMMS.startInputOrWindowGainedFocus");
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#startInputOrWindowGainedFocus");
- final int callingUserId = UserHandle.getCallingUserId();
- final int userId;
- if (editorInfo != null && editorInfo.targetInputMethodUser != null
- && editorInfo.targetInputMethodUser.getIdentifier() != callingUserId) {
- mContext.enforceCallingPermission(
- Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- "Using EditorInfo.targetInputMethodUser requires"
- + " INTERACT_ACROSS_USERS_FULL.");
- userId = editorInfo.targetInputMethodUser.getIdentifier();
- if (!mUserManagerInternal.isUserRunning(userId)) {
- // There is a chance that we hit here because of race condition. Let's just
- // return an error code instead of crashing the caller process, which at
- // least has INTERACT_ACROSS_USERS_FULL permission thus is likely to be an
- // important process.
- Slog.e(TAG, "User #" + userId + " is not running.");
- return InputBindResult.INVALID_USER;
- }
- } else {
- userId = callingUserId;
- }
final InputBindResult result;
synchronized (ImfLock.class) {
final long ident = Binder.clearCallingIdentity();
@@ -3670,9 +3642,19 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
+ " softInputMode=" + InputMethodDebug.softInputModeToString(softInputMode)
+ " windowFlags=#" + Integer.toHexString(windowFlags)
+ " unverifiedTargetSdkVersion=" + unverifiedTargetSdkVersion
+ + " userId=" + userId
+ " imeDispatcher=" + imeDispatcher);
}
+ if (!mUserManagerInternal.isUserRunning(userId)) {
+ // There is a chance that we hit here because of race condition. Let's just
+ // return an error code instead of crashing the caller process, which at
+ // least has INTERACT_ACROSS_USERS_FULL permission thus is likely to be an
+ // important process.
+ Slog.w(TAG, "User #" + userId + " is not running.");
+ return InputBindResult.INVALID_USER;
+ }
+
final ClientState cs = mClients.get(client.asBinder());
if (cs == null) {
throw new IllegalArgumentException("unknown client " + client.asBinder());
@@ -4162,28 +4144,19 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
- public InputMethodSubtype getLastInputMethodSubtype() {
+ public InputMethodSubtype getLastInputMethodSubtype(@UserIdInt int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
synchronized (ImfLock.class) {
- if (!calledFromValidUserLocked()) {
- return null;
- }
- final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
- // TODO: Handle the case of the last IME with no subtypes
- if (lastIme == null || TextUtils.isEmpty(lastIme.first)
- || TextUtils.isEmpty(lastIme.second)) return null;
- final InputMethodInfo lastImi = mMethodMap.get(lastIme.first);
- if (lastImi == null) return null;
- try {
- final int lastSubtypeHash = Integer.parseInt(lastIme.second);
- final int lastSubtypeId = SubtypeUtils.getSubtypeIdFromHashCode(lastImi,
- lastSubtypeHash);
- if (lastSubtypeId < 0 || lastSubtypeId >= lastImi.getSubtypeCount()) {
- return null;
- }
- return lastImi.getSubtypeAt(lastSubtypeId);
- } catch (NumberFormatException e) {
- return null;
+ if (mSettings.getCurrentUserId() == userId) {
+ return mSettings.getLastInputMethodSubtypeLocked();
}
+
+ final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
+ final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap,
+ userId, false);
+ return settings.getLastInputMethodSubtypeLocked();
}
}
@@ -4566,6 +4539,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
@BinderThread
+ @EnforcePermission(Manifest.permission.CONTROL_UI_TRACING)
@Override
public void startImeTrace() {
ImeTracing.getInstance().startTrace(null /* printwriter */);
@@ -4581,6 +4555,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
@BinderThread
+ @EnforcePermission(Manifest.permission.CONTROL_UI_TRACING)
@Override
public void stopImeTrace() {
ImeTracing.getInstance().stopTrace(null /* printwriter */);
@@ -5309,18 +5284,38 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
/**
* Gets the current subtype of this input method.
+ *
+ * @param userId User ID to be queried about.
+ * @return The current {@link InputMethodSubtype} for the specified user.
*/
+ @Nullable
@Override
- public InputMethodSubtype getCurrentInputMethodSubtype() {
+ public InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
synchronized (ImfLock.class) {
- // TODO: Make this work even for non-current users?
- if (!calledFromValidUserLocked()) {
- return null;
+ if (mSettings.getCurrentUserId() == userId) {
+ return getCurrentInputMethodSubtypeLocked();
}
- return getCurrentInputMethodSubtypeLocked();
+
+ final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
+ final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap,
+ userId, false);
+ return settings.getCurrentInputMethodSubtypeForNonCurrentUsers();
}
}
+ /**
+ * Returns the current {@link InputMethodSubtype} for the current user.
+ *
+ * <p>CAVEATS: You must also update
+ * {@link InputMethodSettings#getCurrentInputMethodSubtypeForNonCurrentUsers()}
+ * when you update the algorithm of this method.</p>
+ *
+ * <p>TODO: Address code duplication between this and
+ * {@link InputMethodSettings#getCurrentInputMethodSubtypeForNonCurrentUsers()}.</p>
+ */
@GuardedBy("ImfLock.class")
InputMethodSubtype getCurrentInputMethodSubtypeLocked() {
String selectedMethodId = getSelectedMethodIdLocked();
@@ -5340,7 +5335,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// the most applicable subtype from explicitly or implicitly enabled
// subtypes.
List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
- mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true);
+ mSettings.getEnabledInputMethodSubtypeListLocked(imi, true);
// If there is only one explicitly or implicitly enabled subtype,
// just returns it.
if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
@@ -5384,9 +5379,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
return true;
}
final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(
- mContext.getResources(), mContext.getContentResolver(), methodMap,
- userId, false);
+ final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap, userId,
+ false);
if (!methodMap.containsKey(imeId)
|| !settings.getEnabledInputMethodListLocked().contains(methodMap.get(imeId))) {
return false; // IME is not found or not enabled.
@@ -5458,8 +5452,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
return true;
}
final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(
- mContext.getResources(), mContext.getContentResolver(), methodMap,
+ final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap,
userId, false);
if (!methodMap.containsKey(imeId)) {
return false; // IME is not found.
@@ -5879,22 +5872,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
mService = service;
}
- @RequiresPermission(allOf = {
- Manifest.permission.DUMP,
- Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- Manifest.permission.WRITE_SECURE_SETTINGS,
- })
@BinderThread
@ShellCommandResult
@Override
public int onCommand(@Nullable String cmd) {
- // For shell command, require all the permissions here in favor of code simplicity.
- Arrays.asList(
- Manifest.permission.DUMP,
- Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- Manifest.permission.WRITE_SECURE_SETTINGS
- ).forEach(permission -> mService.mContext.enforceCallingPermission(permission, null));
-
final long identity = Binder.clearCallingIdentity();
try {
return onCommandWithSystemIdentity(cmd);
@@ -6173,8 +6154,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
} else {
final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(mContext.getResources(),
- mContext.getContentResolver(), methodMap, userId, false);
+ final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap,
+ userId, false);
if (enabled) {
if (!methodMap.containsKey(imeId)) {
failedToEnableUnknownIme = true;
@@ -6310,9 +6291,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
methodMap, methodList, DirectBootAwareness.AUTO);
- final InputMethodSettings settings = new InputMethodSettings(
- mContext.getResources(), mContext.getContentResolver(), methodMap,
- userId, false);
+ final InputMethodSettings settings = new InputMethodSettings(mContext,
+ methodMap, userId, false);
nextEnabledImes = InputMethodInfoUtils.getDefaultEnabledImes(mContext,
methodList);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
index a64322625797..c83a96938325 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -200,7 +200,7 @@ final class InputMethodSubtypeSwitchingController {
continue;
}
final List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList =
- mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true);
+ mSettings.getEnabledInputMethodSubtypeListLocked(imi, true);
final ArraySet<String> enabledSubtypeSet = new ArraySet<>();
for (InputMethodSubtype subtype : explicitlyOrImplicitlyEnabledSubtypeList) {
enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
index 3373f0c436f9..dd43e90c548b 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
@@ -233,6 +233,7 @@ final class InputMethodUtils {
* TODO: Move all putters and getters of settings to this class.
* TODO(b/235661780): Make the setting supports multi-users.
*/
+ @UserHandleAware
public static class InputMethodSettings {
private final TextUtils.SimpleStringSplitter mInputMethodSplitter =
new TextUtils.SimpleStringSplitter(INPUT_METHOD_SEPARATOR);
@@ -240,6 +241,8 @@ final class InputMethodUtils {
private final TextUtils.SimpleStringSplitter mSubtypeSplitter =
new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATOR);
+ @NonNull
+ private final Context mUserAwareContext;
private final Resources mRes;
private final ContentResolver mResolver;
private final ArrayMap<String, InputMethodInfo> mMethodMap;
@@ -299,11 +302,14 @@ final class InputMethodUtils {
return imsList;
}
- InputMethodSettings(Resources res, ContentResolver resolver,
+ InputMethodSettings(@NonNull Context context,
ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId,
boolean copyOnWrite) {
- mRes = res;
- mResolver = resolver;
+ mUserAwareContext = context.getUserId() == userId
+ ? context
+ : context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
+ mRes = mUserAwareContext.getResources();
+ mResolver = mUserAwareContext.getContentResolver();
mMethodMap = methodMap;
switchCurrentUser(userId, copyOnWrite);
}
@@ -405,14 +411,13 @@ final class InputMethodUtils {
}
List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked(
- Context context, InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes) {
+ InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes) {
List<InputMethodSubtype> enabledSubtypes =
getEnabledInputMethodSubtypeListLocked(imi);
if (allowsImplicitlySelectedSubtypes && enabledSubtypes.isEmpty()) {
- enabledSubtypes = SubtypeUtils.getImplicitlyApplicableSubtypesLocked(
- context.getResources(), imi);
+ enabledSubtypes = SubtypeUtils.getImplicitlyApplicableSubtypesLocked(mRes, imi);
}
- return InputMethodSubtype.sort(context, 0, imi, enabledSubtypes);
+ return InputMethodSubtype.sort(imi, enabledSubtypes);
}
List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked(InputMethodInfo imi) {
@@ -592,6 +597,27 @@ final class InputMethodUtils {
return getLastSubtypeForInputMethodLockedInternal(null);
}
+ @Nullable
+ InputMethodSubtype getLastInputMethodSubtypeLocked() {
+ final Pair<String, String> lastIme = getLastInputMethodAndSubtypeLocked();
+ // TODO: Handle the case of the last IME with no subtypes
+ if (lastIme == null || TextUtils.isEmpty(lastIme.first)
+ || TextUtils.isEmpty(lastIme.second)) return null;
+ final InputMethodInfo lastImi = mMethodMap.get(lastIme.first);
+ if (lastImi == null) return null;
+ try {
+ final int lastSubtypeHash = Integer.parseInt(lastIme.second);
+ final int lastSubtypeId = SubtypeUtils.getSubtypeIdFromHashCode(lastImi,
+ lastSubtypeHash);
+ if (lastSubtypeId < 0 || lastSubtypeId >= lastImi.getSubtypeCount()) {
+ return null;
+ }
+ return lastImi.getSubtypeAt(lastSubtypeId);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
String getLastSubtypeForInputMethodLocked(String imeId) {
Pair<String, String> ime = getLastSubtypeForInputMethodLockedInternal(imeId);
if (ime != null) {
@@ -792,6 +818,56 @@ final class InputMethodUtils {
}
}
+ /**
+ * A variant of {@link InputMethodManagerService#getCurrentInputMethodSubtypeLocked()} for
+ * non-current users.
+ *
+ * <p>TODO: Address code duplication between this and
+ * {@link InputMethodManagerService#getCurrentInputMethodSubtypeLocked()}.</p>
+ *
+ * @return {@link InputMethodSubtype} if exists. {@code null} otherwise.
+ */
+ @Nullable
+ InputMethodSubtype getCurrentInputMethodSubtypeForNonCurrentUsers() {
+ final String selectedMethodId = getSelectedInputMethod();
+ if (selectedMethodId == null) {
+ return null;
+ }
+ final InputMethodInfo imi = mMethodMap.get(selectedMethodId);
+ if (imi == null || imi.getSubtypeCount() == 0) {
+ return null;
+ }
+
+ final int subtypeHashCode = getSelectedInputMethodSubtypeHashCode();
+ if (subtypeHashCode != InputMethodUtils.NOT_A_SUBTYPE_ID) {
+ final int subtypeIndex = SubtypeUtils.getSubtypeIdFromHashCode(imi,
+ subtypeHashCode);
+ if (subtypeIndex >= 0) {
+ return imi.getSubtypeAt(subtypeIndex);
+ }
+ }
+
+ // If there are no selected subtypes, the framework will try to find the most applicable
+ // subtype from explicitly or implicitly enabled subtypes.
+ final List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
+ getEnabledInputMethodSubtypeListLocked(imi, true);
+ // If there is only one explicitly or implicitly enabled subtype, just returns it.
+ if (explicitlyOrImplicitlyEnabledSubtypes.isEmpty()) {
+ return null;
+ }
+ if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
+ return explicitlyOrImplicitlyEnabledSubtypes.get(0);
+ }
+ final InputMethodSubtype subtype = SubtypeUtils.findLastResortApplicableSubtypeLocked(
+ mRes, explicitlyOrImplicitlyEnabledSubtypes, SubtypeUtils.SUBTYPE_MODE_KEYBOARD,
+ null, true);
+ if (subtype != null) {
+ return subtype;
+ }
+ return SubtypeUtils.findLastResortApplicableSubtypeLocked(mRes,
+ explicitlyOrImplicitlyEnabledSubtypes, null, null, true);
+ }
+
public void dumpLocked(final Printer pw, final String prefix) {
pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
pw.println(prefix + "mCurrentProfileIds=" + Arrays.toString(mCurrentProfileIds));
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 25d7d9f766a1..8c03ead9ac09 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -16,7 +16,6 @@
package com.android.server.location;
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
import static android.app.compat.CompatChanges.isChangeEnabled;
@@ -430,7 +429,9 @@ public class LocationManagerService extends ILocationManager.Stub implements
// initialize gnss last because it has no awareness of boot phases and blindly assumes that
// all other location providers are loaded at initialization
- if (GnssNative.isSupported()) {
+ boolean hasLocationFeature = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LOCATION);
+ if (hasLocationFeature && GnssNative.isSupported()) {
GnssConfiguration gnssConfiguration = new GnssConfiguration(mContext);
GnssNative gnssNative = GnssNative.create(mInjector, gnssConfiguration);
mGnssManagerService = new GnssManagerService(mContext, mInjector, gnssNative);
diff --git a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
index 12f8776a8e18..1435016fc55a 100644
--- a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
@@ -21,6 +21,7 @@ import android.os.PersistableBundle;
import android.os.SystemProperties;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -73,6 +74,8 @@ public class GnssConfiguration {
static final String CONFIG_NFW_PROXY_APPS = "NFW_PROXY_APPS";
private static final String CONFIG_ENABLE_PSDS_PERIODIC_DOWNLOAD =
"ENABLE_PSDS_PERIODIC_DOWNLOAD";
+ private static final String CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL =
+ "ENABLE_ACTIVE_SIM_EMERGENCY_SUPL";
static final String CONFIG_LONGTERM_PSDS_SERVER_1 = "LONGTERM_PSDS_SERVER_1";
static final String CONFIG_LONGTERM_PSDS_SERVER_2 = "LONGTERM_PSDS_SERVER_2";
static final String CONFIG_LONGTERM_PSDS_SERVER_3 = "LONGTERM_PSDS_SERVER_3";
@@ -207,6 +210,14 @@ public class GnssConfiguration {
}
/**
+ * Returns true if during an emergency call, the GnssConfiguration of the activeSubId will be
+ * injected for the emergency SUPL flow; Returns false otherwise. Default false if not set.
+ */
+ boolean isActiveSimEmergencySuplEnabled() {
+ return getBooleanConfig(CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL, false);
+ }
+
+ /**
* Returns true if a long-term PSDS server is configured.
*/
boolean isLongTermPsdsServerConfigured() {
@@ -232,16 +243,31 @@ public class GnssConfiguration {
/**
* Loads the GNSS properties from carrier config file followed by the properties from
- * gps debug config file.
+ * gps debug config file, and injects the GNSS properties into the HAL.
*/
void reloadGpsProperties() {
- if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + mProperties.size());
- loadPropertiesFromCarrierConfig();
+ reloadGpsProperties(/* inEmergency= */ false, /* activeSubId= */ -1);
+ }
- String lpp_prof = SystemProperties.get(LPP_PROFILE);
- if (!TextUtils.isEmpty(lpp_prof)) {
- // override default value of this if lpp_prof is not empty
- mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
+ /**
+ * Loads the GNSS properties from carrier config file followed by the properties from
+ * gps debug config file, and injects the GNSS properties into the HAL.
+ */
+ void reloadGpsProperties(boolean inEmergency, int activeSubId) {
+ if (DEBUG) {
+ Log.d(TAG,
+ "Reset GPS properties, previous size = " + mProperties.size() + ", inEmergency:"
+ + inEmergency + ", activeSubId=" + activeSubId);
+ }
+ loadPropertiesFromCarrierConfig(inEmergency, activeSubId);
+
+ if (isSimAbsent(mContext)) {
+ // Use the default SIM's LPP profile when SIM is absent.
+ String lpp_prof = SystemProperties.get(LPP_PROFILE);
+ if (!TextUtils.isEmpty(lpp_prof)) {
+ // override default value of this if lpp_prof is not empty
+ mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
+ }
}
/*
@@ -322,16 +348,19 @@ public class GnssConfiguration {
/**
* Loads GNSS properties from carrier config file.
*/
- void loadPropertiesFromCarrierConfig() {
+ void loadPropertiesFromCarrierConfig(boolean inEmergency, int activeSubId) {
CarrierConfigManager configManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (configManager == null) {
return;
}
- int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
- PersistableBundle configs = SubscriptionManager.isValidSubscriptionId(ddSubId)
- ? configManager.getConfigForSubId(ddSubId) : configManager.getConfig();
+ int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ if (inEmergency && activeSubId >= 0) {
+ subId = activeSubId;
+ }
+ PersistableBundle configs = SubscriptionManager.isValidSubscriptionId(subId)
+ ? configManager.getConfigForSubId(subId) : configManager.getConfig();
if (configs == null) {
if (DEBUG) Log.d(TAG, "SIM not ready, use default carrier config.");
configs = CarrierConfigManager.getDefaultConfig();
@@ -422,6 +451,12 @@ public class GnssConfiguration {
return gnssConfiguartionIfaceVersion.mMajor < 2;
}
+ private static boolean isSimAbsent(Context context) {
+ TelephonyManager phone = (TelephonyManager) context.getSystemService(
+ Context.TELEPHONY_SERVICE);
+ return phone.getSimState() == TelephonyManager.SIM_STATE_ABSENT;
+ }
+
private static native HalInterfaceVersion native_get_gnss_configuration_version();
private static native boolean native_set_supl_version(int version);
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index f5c2bbc8d5a2..a6a3db11b729 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -126,6 +126,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
/**
* A GNSS implementation of LocationProvider used by LocationManager.
@@ -359,8 +360,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
}
}
if (isKeepLppProfile) {
- // load current properties for the carrier
- mGnssConfiguration.loadPropertiesFromCarrierConfig();
+ // load current properties for the carrier of ddSubId
+ mGnssConfiguration.loadPropertiesFromCarrierConfig(/* inEmergency= */ false,
+ /* activeSubId= */ -1);
String lpp_profile = mGnssConfiguration.getLppProfile();
// set the persist property LPP_PROFILE for the value
if (lpp_profile != null) {
@@ -431,13 +433,38 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
// this approach is just fine because events are posted to our handler anyway
mGnssConfiguration = mGnssNative.getConfiguration();
// Create a GPS net-initiated handler (also needed by handleInitialize)
+ GpsNetInitiatedHandler.EmergencyCallCallback emergencyCallCallback =
+ new GpsNetInitiatedHandler.EmergencyCallCallback() {
+
+ @Override
+ public void onEmergencyCallStart(int subId) {
+ if (!mGnssConfiguration.isActiveSimEmergencySuplEnabled()) {
+ return;
+ }
+ mHandler.post(() -> mGnssConfiguration.reloadGpsProperties(
+ mNIHandler.getInEmergency(), subId));
+ }
+
+ @Override
+ public void onEmergencyCallEnd() {
+ if (!mGnssConfiguration.isActiveSimEmergencySuplEnabled()) {
+ return;
+ }
+ mHandler.postDelayed(() -> mGnssConfiguration.reloadGpsProperties(
+ /* inEmergency= */ false,
+ SubscriptionManager.getDefaultDataSubscriptionId()),
+ TimeUnit.SECONDS.toMillis(mGnssConfiguration.getEsExtensionSec()));
+ }
+ };
mNIHandler = new GpsNetInitiatedHandler(context,
mNetInitiatedListener,
+ emergencyCallCallback,
mSuplEsEnabled);
// Trigger PSDS data download when the network comes up after booting.
mPendingDownloadPsdsTypes.add(GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
- GnssLocationProvider.this::onNetworkAvailable, mHandler.getLooper(), mNIHandler);
+ GnssLocationProvider.this::onNetworkAvailable,
+ mHandler.getLooper(), mNIHandler);
mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this);
mGnssSatelliteBlocklistHelper =
@@ -1694,9 +1721,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
int type = AGPS_SETID_TYPE_NONE;
String setId = null;
- int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
- if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
- phone = phone.createForSubscriptionId(ddSubId);
+ int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ if (mNIHandler.getInEmergency() && mNetworkConnectivityHandler.getActiveSubId() >= 0) {
+ subId = mNetworkConnectivityHandler.getActiveSubId();
+ }
+ if (SubscriptionManager.isValidSubscriptionId(subId)) {
+ phone = phone.createForSubscriptionId(subId);
}
if ((flags & AGPS_REQUEST_SETID_IMSI) == AGPS_REQUEST_SETID_IMSI) {
setId = phone.getSubscriberId();
diff --git a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
index aba7572ee1a0..6f890cda5964 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
@@ -190,7 +190,7 @@ class GnssNetworkConnectivityHandler {
mContext = context;
mGnssNetworkListener = gnssNetworkListener;
- SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+ SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
if (subManager != null) {
subManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
}
@@ -311,6 +311,13 @@ class GnssNetworkConnectivityHandler {
}
/**
+ * Returns the active Sub ID for emergency SUPL connection.
+ */
+ int getActiveSubId() {
+ return mActiveSubId;
+ }
+
+ /**
* Called from native code to update AGPS connection status, or to request or release a SUPL
* connection.
*
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index f9dd7a9e3da4..884ae171ba5f 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -33,10 +33,10 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSW
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
+import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY;
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
import static com.android.internal.widget.LockPatternUtils.PROFILE_KEY_NAME_DECRYPT;
import static com.android.internal.widget.LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
@@ -139,7 +139,7 @@ import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.locksettings.LockSettingsStorage.PersistentData;
import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
+import com.android.server.locksettings.SyntheticPasswordManager.SyntheticPassword;
import com.android.server.locksettings.SyntheticPasswordManager.TokenType;
import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
import com.android.server.pm.UserManagerInternal;
@@ -199,8 +199,8 @@ public class LockSettingsService extends ILockSettings.Stub {
private static final int PROFILE_KEY_IV_SIZE = 12;
private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
- private static final String PREV_SYNTHETIC_PASSWORD_HANDLE_KEY = "prev-sp-handle";
- private static final String SYNTHETIC_PASSWORD_UPDATE_TIME_KEY = "sp-handle-ts";
+ private static final String PREV_LSKF_BASED_PROTECTOR_ID_KEY = "prev-sp-handle";
+ private static final String LSKF_LAST_CHANGED_TIME_KEY = "sp-handle-ts";
private static final String USER_SERIAL_NUMBER_KEY = "serial-number";
// Duration that LockSettingsService will store the gatekeeper password for. This allows
@@ -787,28 +787,28 @@ public class LockSettingsService extends ILockSettings.Stub {
// credential and still needs to be passed to the HAL once that credential is
// removed.
if (mUserManager.getUserInfo(userId).isPrimary() && !isUserSecure(userId)) {
- tryDeriveAuthTokenForUnsecuredPrimaryUser(userId);
+ tryDeriveVendorAuthSecretForUnsecuredPrimaryUser(userId);
}
}
});
}
- private void tryDeriveAuthTokenForUnsecuredPrimaryUser(@UserIdInt int userId) {
+ private void tryDeriveVendorAuthSecretForUnsecuredPrimaryUser(@UserIdInt int userId) {
synchronized (mSpManager) {
- // Make sure the user has a synthetic password to derive
+ // If there is no SP, then there is no vendor auth secret.
if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
return;
}
- final long handle = getSyntheticPasswordHandleLocked(userId);
+ final long protectorId = getCurrentLskfBasedProtectorId(userId);
AuthenticationResult result =
- mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
- handle, LockscreenCredential.createNone(), userId, null);
- if (result.authToken != null) {
- Slog.i(TAG, "Retrieved auth token for user " + userId);
- onAuthTokenKnownForUser(userId, result.authToken);
+ mSpManager.unlockLskfBasedProtector(getGateKeeperService(), protectorId,
+ LockscreenCredential.createNone(), userId, null);
+ if (result.syntheticPassword != null) {
+ Slog.i(TAG, "Unwrapped SP for unsecured primary user " + userId);
+ onSyntheticPasswordKnown(userId, result.syntheticPassword);
} else {
- Slog.e(TAG, "Auth token not available for user " + userId);
+ Slog.e(TAG, "Failed to unwrap SP for unsecured primary user " + userId);
}
}
}
@@ -912,7 +912,7 @@ public class LockSettingsService extends ILockSettings.Stub {
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
mSpManager.migrateFrpPasswordLocked(
- getSyntheticPasswordHandleLocked(userInfo.id),
+ getCurrentLskfBasedProtectorId(userInfo.id),
userInfo,
redactActualQualityToMostLenientEquivalentQuality(actualQuality));
}
@@ -1168,8 +1168,8 @@ public class LockSettingsService extends ILockSettings.Stub {
}
synchronized (mSpManager) {
if (isSyntheticPasswordBasedCredentialLocked(userId)) {
- final long handle = getSyntheticPasswordHandleLocked(userId);
- int rawType = mSpManager.getCredentialType(handle, userId);
+ final long protectorId = getCurrentLskfBasedProtectorId(userId);
+ int rawType = mSpManager.getCredentialType(protectorId, userId);
if (rawType != CREDENTIAL_TYPE_PASSWORD_OR_PIN) {
return rawType;
}
@@ -1604,13 +1604,13 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.e(TAG, "Failed to decrypt child profile key", e);
}
}
- final long origHandle = getSyntheticPasswordHandleLocked(userId);
- AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
- getGateKeeperService(), origHandle, savedCredential, userId, null);
+ final long oldProtectorId = getCurrentLskfBasedProtectorId(userId);
+ AuthenticationResult authResult = mSpManager.unlockLskfBasedProtector(
+ getGateKeeperService(), oldProtectorId, savedCredential, userId, null);
VerifyCredentialResponse response = authResult.gkResponse;
- AuthenticationToken auth = authResult.authToken;
+ SyntheticPassword sp = authResult.syntheticPassword;
- if (auth == null) {
+ if (sp == null) {
if (response == null
|| response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
Slog.w(TAG, "Failed to enroll: incorrect credential.");
@@ -1624,9 +1624,9 @@ public class LockSettingsService extends ILockSettings.Stub {
throw new IllegalStateException("password change failed");
}
- onAuthTokenKnownForUser(userId, auth);
- setLockCredentialWithAuthTokenLocked(credential, auth, userId);
- mSpManager.destroyPasswordBasedSyntheticPassword(origHandle, userId);
+ onSyntheticPasswordKnown(userId, sp);
+ setLockCredentialWithSpLocked(credential, sp, userId);
+ mSpManager.destroyLskfBasedProtector(oldProtectorId, userId);
sendCredentialsOnChangeIfRequired(credential, userId, isLockTiedToParent);
return true;
}
@@ -1832,9 +1832,9 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.w(TAG, "Escrow token is disabled on the current user");
return false;
}
- AuthenticationResult authResult = mSpManager.unwrapWeakTokenBasedSyntheticPassword(
+ AuthenticationResult authResult = mSpManager.unlockWeakTokenBasedProtector(
getGateKeeperService(), handle, token, userId);
- if (authResult.authToken == null) {
+ if (authResult.syntheticPassword == null) {
Slog.w(TAG, "Invalid escrow token supplied");
return false;
}
@@ -1929,7 +1929,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
- /** Unlock disk encryption */
+ /** Unlock file-based encryption */
private void unlockUserKey(int userId, byte[] secret) {
final UserInfo userInfo = mUserManager.getUserInfo(userId);
try {
@@ -2112,20 +2112,20 @@ public class LockSettingsService extends ILockSettings.Stub {
progressCallback);
}
- long handle = getSyntheticPasswordHandleLocked(userId);
- authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
- getGateKeeperService(), handle, credential, userId, progressCallback);
+ long protectorId = getCurrentLskfBasedProtectorId(userId);
+ authResult = mSpManager.unlockLskfBasedProtector(
+ getGateKeeperService(), protectorId, credential, userId, progressCallback);
response = authResult.gkResponse;
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
// credential has matched
mBiometricDeferredQueue.addPendingLockoutResetForUser(userId,
- authResult.authToken.deriveGkPassword());
+ authResult.syntheticPassword.deriveGkPassword());
// perform verifyChallenge with synthetic password which generates the real GK auth
// token and response for the current user
- response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
- 0L /* challenge */, userId);
+ response = mSpManager.verifyChallenge(getGateKeeperService(),
+ authResult.syntheticPassword, 0L /* challenge */, userId);
if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
// This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't
// match the recorded GK password handle.
@@ -2135,11 +2135,11 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
- onCredentialVerified(authResult.authToken,
+ onCredentialVerified(authResult.syntheticPassword,
PasswordMetrics.computeForCredential(credential), userId);
if ((flags & VERIFY_FLAG_REQUEST_GK_PW_HANDLE) != 0) {
final long gkHandle = storeGatekeeperPasswordTemporarily(
- authResult.authToken.deriveGkPassword());
+ authResult.syntheticPassword.deriveGkPassword());
response = new VerifyCredentialResponse.Builder()
.setGatekeeperPasswordHandle(gkHandle)
.build();
@@ -2213,9 +2213,9 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
- private PasswordMetrics loadPasswordMetrics(AuthenticationToken auth, int userHandle) {
+ private PasswordMetrics loadPasswordMetrics(SyntheticPassword sp, int userHandle) {
synchronized (mSpManager) {
- return mSpManager.getPasswordMetrics(auth, getSyntheticPasswordHandleLocked(userHandle),
+ return mSpManager.getPasswordMetrics(sp, getCurrentLskfBasedProtectorId(userHandle),
userHandle);
}
}
@@ -2489,24 +2489,23 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
- private void onAuthTokenKnownForUser(@UserIdInt int userId, AuthenticationToken auth) {
+ private void onSyntheticPasswordKnown(@UserIdInt int userId, SyntheticPassword sp) {
if (mInjector.isGsiRunning()) {
Slog.w(TAG, "Running in GSI; skipping calls to AuthSecret and RebootEscrow");
return;
}
- mRebootEscrowManager.callToRebootEscrowIfNeeded(userId, auth.getVersion(),
- auth.getSyntheticPassword());
+ mRebootEscrowManager.callToRebootEscrowIfNeeded(userId, sp.getVersion(),
+ sp.getSyntheticPassword());
- callToAuthSecretIfNeeded(userId, auth);
+ callToAuthSecretIfNeeded(userId, sp);
}
- private void callToAuthSecretIfNeeded(@UserIdInt int userId,
- AuthenticationToken auth) {
+ private void callToAuthSecretIfNeeded(@UserIdInt int userId, SyntheticPassword sp) {
// Pass the primary user's auth secret to the HAL
if (mAuthSecretService != null && mUserManager.getUserInfo(userId).isPrimary()) {
try {
- final byte[] rawSecret = auth.deriveVendorAuthSecret();
+ final byte[] rawSecret = sp.deriveVendorAuthSecret();
final ArrayList<Byte> secret = new ArrayList<>(rawSecret.length);
for (int i = 0; i < rawSecret.length; ++i) {
secret.add(rawSecret[i]);
@@ -2519,66 +2518,51 @@ public class LockSettingsService extends ILockSettings.Stub {
}
/**
- * Precondition: vold and keystore unlocked.
+ * Creates the synthetic password (SP) for the given user and protects it with the user's LSKF.
+ * This is called just once in the lifetime of the user: the first time a nonempty LSKF is set,
+ * or when an escrow token is activated on a device with an empty LSKF.
*
- * Create new synthetic password, set up synthetic password blob protected by the supplied
- * user credential, and make the newly-created SP blob active. This is called just once in the
- * lifetime of the user: the first time that a user credential is set (!credential.isNone()), or
- * when an escrow token is activated on an unsecured device (credential.isNone()).
- *
- * The invariant under a synthetic password is:
- * 1. If user credential exists, then both vold and keystore and protected with keys derived
- * from the synthetic password.
- * 2. If user credential does not exist, vold and keystore protection are cleared. This is to
- * make it consistent with current behaviour. It also allows ActivityManager to call
- * unlockUser() with empty secret.
- * 3. Once a user is migrated to have synthetic password, its value will never change, no matter
- * whether the user changes their lockscreen PIN or clear/reset it. When the user clears its
- * lockscreen PIN, we still maintain the existing synthetic password in a password blob
- * protected by a default PIN.
- * 4. The user SID is linked with synthetic password, but its cleared/re-created when the user
- * clears/re-creates their lockscreen PIN.
+ * Maintains the SP invariants described in {@link SyntheticPasswordManager}.
*/
@GuardedBy("mSpManager")
@VisibleForTesting
- AuthenticationToken initializeSyntheticPasswordLocked(LockscreenCredential credential,
+ SyntheticPassword initializeSyntheticPasswordLocked(LockscreenCredential credential,
int userId) {
Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
- Preconditions.checkState(
- getSyntheticPasswordHandleLocked(userId) == SyntheticPasswordManager.DEFAULT_HANDLE,
+ Preconditions.checkState(getCurrentLskfBasedProtectorId(userId) ==
+ SyntheticPasswordManager.NULL_PROTECTOR_ID,
"Cannot reinitialize SP");
- final AuthenticationToken auth = mSpManager.newSyntheticPassword(userId);
- long handle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
- credential, auth, userId);
+ final SyntheticPassword sp = mSpManager.newSyntheticPassword(userId);
+ long protectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(), credential,
+ sp, userId);
if (!credential.isNone()) {
- mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
- mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
- setUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
- setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+ mSpManager.newSidForUser(getGateKeeperService(), sp, userId);
+ mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
+ setUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey());
+ setKeystorePassword(sp.deriveKeyStorePassword(), userId);
} else {
clearUserKeyProtection(userId, null);
setKeystorePassword(null, userId);
gateKeeperClearSecureUserId(userId);
}
fixateNewestUserKeyAuth(userId);
- setSyntheticPasswordHandleLocked(handle, userId);
- onAuthTokenKnownForUser(userId, auth);
- return auth;
+ setCurrentLskfBasedProtectorId(protectorId, userId);
+ onSyntheticPasswordKnown(userId, sp);
+ return sp;
}
@VisibleForTesting
- long getSyntheticPasswordHandleLocked(int userId) {
- return getLong(SYNTHETIC_PASSWORD_HANDLE_KEY,
- SyntheticPasswordManager.DEFAULT_HANDLE, userId);
+ long getCurrentLskfBasedProtectorId(int userId) {
+ return getLong(CURRENT_LSKF_BASED_PROTECTOR_ID_KEY,
+ SyntheticPasswordManager.NULL_PROTECTOR_ID, userId);
}
- private void setSyntheticPasswordHandleLocked(long handle, int userId) {
- final long oldHandle = getSyntheticPasswordHandleLocked(userId);
- setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, handle, userId);
- setLong(PREV_SYNTHETIC_PASSWORD_HANDLE_KEY, oldHandle, userId);
- setLong(SYNTHETIC_PASSWORD_UPDATE_TIME_KEY, System.currentTimeMillis(), userId);
-
+ private void setCurrentLskfBasedProtectorId(long newProtectorId, int userId) {
+ final long oldProtectorId = getCurrentLskfBasedProtectorId(userId);
+ setLong(CURRENT_LSKF_BASED_PROTECTOR_ID_KEY, newProtectorId, userId);
+ setLong(PREV_LSKF_BASED_PROTECTOR_ID_KEY, oldProtectorId, userId);
+ setLong(LSKF_LAST_CHANGED_TIME_KEY, System.currentTimeMillis(), userId);
}
@VisibleForTesting
@@ -2593,8 +2577,8 @@ public class LockSettingsService extends ILockSettings.Stub {
final int type = mStorage.readPersistentDataBlock().type;
return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER;
}
- long handle = getSyntheticPasswordHandleLocked(userId);
- return handle != SyntheticPasswordManager.DEFAULT_HANDLE;
+ long protectorId = getCurrentLskfBasedProtectorId(userId);
+ return protectorId != SyntheticPasswordManager.NULL_PROTECTOR_ID;
}
/**
@@ -2624,8 +2608,7 @@ public class LockSettingsService extends ILockSettings.Stub {
return handle;
}
- private void onCredentialVerified(AuthenticationToken authToken, PasswordMetrics metrics,
- int userId) {
+ private void onCredentialVerified(SyntheticPassword sp, PasswordMetrics metrics, int userId) {
if (metrics != null) {
synchronized (this) {
@@ -2635,21 +2618,21 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.wtf(TAG, "Null metrics after credential verification");
}
- unlockKeystore(authToken.deriveKeyStorePassword(), userId);
+ unlockKeystore(sp.deriveKeyStorePassword(), userId);
{
- final byte[] secret = authToken.deriveDiskEncryptionKey();
+ final byte[] secret = sp.deriveFileBasedEncryptionKey();
unlockUser(userId, secret);
Arrays.fill(secret, (byte) 0);
}
- activateEscrowTokens(authToken, userId);
+ activateEscrowTokens(sp, userId);
if (isProfileWithSeparatedLock(userId)) {
setDeviceUnlockedForUser(userId);
}
mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
- onAuthTokenKnownForUser(userId, authToken);
+ onSyntheticPasswordKnown(userId, sp);
}
private void setDeviceUnlockedForUser(int userId) {
@@ -2658,68 +2641,58 @@ public class LockSettingsService extends ILockSettings.Stub {
}
/**
- * Change the user's lockscreen password by creating a new SP blob and update the handle, based
- * on an existing authentication token. Even though a new SP blob is created, the underlying
- * synthetic password is never changed.
+ * Changes the user's LSKF by creating an LSKF-based protector that uses the new LSKF (which may
+ * be empty) and setting the new protector as the user's current LSKF-based protector. The old
+ * LSKF-based protector is not destroyed, and the SP itself is not changed.
*
- * When clearing credential, we keep the SP unchanged, but clear its password handle so its
- * SID is gone. We also clear password from (software-based) keystore and vold, which will be
- * added back when new password is set in future.
+ * Also maintains the invariants described in {@link SyntheticPasswordManager} by
+ * setting/clearing the protection (by the SP) on the user's file-based encryption key and
+ * auth-bound Keystore keys when the LSKF is added/removed, respectively. If the new LSKF is
+ * nonempty, then the Gatekeeper auth token is also refreshed.
*/
@GuardedBy("mSpManager")
- private long setLockCredentialWithAuthTokenLocked(LockscreenCredential credential,
- AuthenticationToken auth, int userId) {
- if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
+ private long setLockCredentialWithSpLocked(LockscreenCredential credential,
+ SyntheticPassword sp, int userId) {
+ if (DEBUG) Slog.d(TAG, "setLockCredentialWithSpLocked: user=" + userId);
final int savedCredentialType = getCredentialTypeInternal(userId);
- long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
- credential, auth, userId);
+ final long newProtectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(),
+ credential, sp, userId);
final Map<Integer, LockscreenCredential> profilePasswords;
if (!credential.isNone()) {
// not needed by synchronizeUnifiedWorkChallengeForProfiles()
profilePasswords = null;
if (mSpManager.hasSidForUser(userId)) {
- // We are changing password of a secured device, nothing more needed as
- // createPasswordBasedSyntheticPassword has already taken care of maintaining
- // the password handle and SID unchanged.
-
- //refresh auth token
- mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+ mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
} else {
- // A new password is set on a previously-unsecured device, we need to generate
- // a new SID, and re-add keys to vold and keystore.
- mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
- mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
- setUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+ mSpManager.newSidForUser(getGateKeeperService(), sp, userId);
+ mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
+ setUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey());
fixateNewestUserKeyAuth(userId);
- setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+ setKeystorePassword(sp.deriveKeyStorePassword(), userId);
}
} else {
// Cache all profile password if they use unified work challenge. This will later be
// used to clear the profile's password in synchronizeUnifiedWorkChallengeForProfiles()
profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId);
- // we are clearing password of a secured device, so need to nuke SID as well.
mSpManager.clearSidForUser(userId);
gateKeeperClearSecureUserId(userId);
- // Clear key from vold so ActivityManager can just unlock the user with empty secret
- // during boot. Vold storage needs to be unlocked before manipulation of the keys can
- // succeed.
- unlockUserKey(userId, auth.deriveDiskEncryptionKey());
- clearUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+ unlockUserKey(userId, sp.deriveFileBasedEncryptionKey());
+ clearUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey());
fixateNewestUserKeyAuth(userId);
- unlockKeystore(auth.deriveKeyStorePassword(), userId);
+ unlockKeystore(sp.deriveKeyStorePassword(), userId);
setKeystorePassword(null, userId);
removeBiometricsForUser(userId);
}
- setSyntheticPasswordHandleLocked(newHandle, userId);
+ setCurrentLskfBasedProtectorId(newProtectorId, userId);
LockPatternUtils.invalidateCredentialTypeCache();
synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
setUserPasswordMetrics(credential, userId);
mManagedProfilePasswordCache.removePassword(userId);
if (savedCredentialType != CREDENTIAL_TYPE_NONE) {
- mSpManager.destroyAllWeakTokenBasedSyntheticPasswords(userId);
+ mSpManager.destroyAllWeakTokenBasedProtectors(userId);
}
if (profilePasswords != null) {
@@ -2728,7 +2701,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
- return newHandle;
+ return newProtectorId;
}
private void removeBiometricsForUser(int userId) {
@@ -2825,14 +2798,14 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.w(TAG, "Synthetic password not enabled");
return null;
}
- long handle = getSyntheticPasswordHandleLocked(userId);
- AuthenticationResult auth = mSpManager.unwrapPasswordBasedSyntheticPassword(
- getGateKeeperService(), handle, currentCredential, userId, null);
- if (auth.authToken == null) {
+ long protectorId = getCurrentLskfBasedProtectorId(userId);
+ AuthenticationResult auth = mSpManager.unlockLskfBasedProtector(
+ getGateKeeperService(), protectorId, currentCredential, userId, null);
+ if (auth.syntheticPassword == null) {
Slog.w(TAG, "Current credential is incorrect");
return null;
}
- return auth.authToken.derivePasswordHashFactor();
+ return auth.syntheticPassword.derivePasswordHashFactor();
}
} finally {
scheduleGc();
@@ -2843,46 +2816,47 @@ public class LockSettingsService extends ILockSettings.Stub {
@NonNull EscrowTokenStateChangeCallback callback) {
if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId + ", type=" + type);
synchronized (mSpManager) {
- // Migrate to synthetic password based credentials if the user has no password,
- // the token can then be activated immediately.
- AuthenticationToken auth = null;
+ // If the user has no LSKF, then the token can be activated immediately, after creating
+ // the user's SP if it doesn't already exist. Otherwise, the token can't be activated
+ // until the SP is unlocked by another protector (normally the LSKF-based one).
+ SyntheticPassword sp = null;
if (!isUserSecure(userId)) {
- long handle = getSyntheticPasswordHandleLocked(userId);
- if (handle == SyntheticPasswordManager.DEFAULT_HANDLE) {
- auth = initializeSyntheticPasswordLocked(LockscreenCredential.createNone(),
+ long protectorId = getCurrentLskfBasedProtectorId(userId);
+ if (protectorId == SyntheticPasswordManager.NULL_PROTECTOR_ID) {
+ sp = initializeSyntheticPasswordLocked(LockscreenCredential.createNone(),
userId);
} else {
- auth = mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
- handle, LockscreenCredential.createNone(), userId, null).authToken;
+ sp = mSpManager.unlockLskfBasedProtector(getGateKeeperService(), protectorId,
+ LockscreenCredential.createNone(), userId, null).syntheticPassword;
}
}
disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
if (!mSpManager.hasEscrowData(userId)) {
throw new SecurityException("Escrow token is disabled on the current user");
}
- long handle = mSpManager.createTokenBasedSyntheticPassword(token, type, userId,
- callback);
- if (auth != null) {
- mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+ long handle = mSpManager.addPendingToken(token, type, userId, callback);
+ if (sp != null) {
+ // Activate the token immediately
+ mSpManager.createTokenBasedProtector(handle, sp, userId);
}
return handle;
}
}
- private void activateEscrowTokens(AuthenticationToken auth, int userId) {
+ private void activateEscrowTokens(SyntheticPassword sp, int userId) {
if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
synchronized (mSpManager) {
disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
for (long handle : mSpManager.getPendingTokensForUser(userId)) {
Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
- mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+ mSpManager.createTokenBasedProtector(handle, sp, userId);
}
}
}
private boolean isEscrowTokenActive(long handle, int userId) {
synchronized (mSpManager) {
- return mSpManager.existsHandle(handle, userId);
+ return mSpManager.protectorExists(handle, userId);
}
}
@@ -2896,15 +2870,15 @@ public class LockSettingsService extends ILockSettings.Stub {
private boolean removeEscrowToken(long handle, int userId) {
synchronized (mSpManager) {
- if (handle == getSyntheticPasswordHandleLocked(userId)) {
- Slog.w(TAG, "Cannot remove password handle");
+ if (handle == getCurrentLskfBasedProtectorId(userId)) {
+ Slog.w(TAG, "Escrow token handle equals LSKF-based protector ID");
return false;
}
if (mSpManager.removePendingToken(handle, userId)) {
return true;
}
- if (mSpManager.existsHandle(handle, userId)) {
- mSpManager.destroyTokenBasedSyntheticPassword(handle, userId);
+ if (mSpManager.protectorExists(handle, userId)) {
+ mSpManager.destroyTokenBasedProtector(handle, userId);
return true;
} else {
return false;
@@ -2946,23 +2920,23 @@ public class LockSettingsService extends ILockSettings.Stub {
private boolean setLockCredentialWithTokenInternalLocked(LockscreenCredential credential,
long tokenHandle, byte[] token, int userId) {
final AuthenticationResult result;
- result = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(), tokenHandle,
- token, userId);
- if (result.authToken == null) {
+ result = mSpManager.unlockTokenBasedProtector(getGateKeeperService(), tokenHandle, token,
+ userId);
+ if (result.syntheticPassword == null) {
Slog.w(TAG, "Invalid escrow token supplied");
return false;
}
if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
// Most likely, an untrusted credential reset happened in the past which
// changed the synthetic password
- Slog.e(TAG, "Obsolete token: synthetic password derived but it fails GK "
+ Slog.e(TAG, "Obsolete token: synthetic password decrypted but it fails GK "
+ "verification.");
return false;
}
- onAuthTokenKnownForUser(userId, result.authToken);
- long oldHandle = getSyntheticPasswordHandleLocked(userId);
- setLockCredentialWithAuthTokenLocked(credential, result.authToken, userId);
- mSpManager.destroyPasswordBasedSyntheticPassword(oldHandle, userId);
+ onSyntheticPasswordKnown(userId, result.syntheticPassword);
+ final long oldProtectorId = getCurrentLskfBasedProtectorId(userId);
+ setLockCredentialWithSpLocked(credential, result.syntheticPassword, userId);
+ mSpManager.destroyLskfBasedProtector(oldProtectorId, userId);
return true;
}
@@ -2973,16 +2947,16 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.w(TAG, "Escrow token is disabled on the current user");
return false;
}
- authResult = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(),
- tokenHandle, token, userId);
- if (authResult.authToken == null) {
+ authResult = mSpManager.unlockTokenBasedProtector(getGateKeeperService(), tokenHandle,
+ token, userId);
+ if (authResult.syntheticPassword == null) {
Slog.w(TAG, "Invalid escrow token supplied");
return false;
}
}
- onCredentialVerified(authResult.authToken,
- loadPasswordMetrics(authResult.authToken, userId), userId);
+ onCredentialVerified(authResult.syntheticPassword,
+ loadPasswordMetrics(authResult.syntheticPassword, userId), userId);
return true;
}
@@ -3037,11 +3011,11 @@ public class LockSettingsService extends ILockSettings.Stub {
pw.println("User " + userId);
pw.increaseIndent();
synchronized (mSpManager) {
- pw.println(String.format("SP Handle: %x",
- getSyntheticPasswordHandleLocked(userId)));
- pw.println(String.format("Last changed: %s (%x)",
- timestampToString(getLong(SYNTHETIC_PASSWORD_UPDATE_TIME_KEY, 0, userId)),
- getLong(PREV_SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId)));
+ pw.println(String.format("LSKF-based SP protector ID: %x",
+ getCurrentLskfBasedProtectorId(userId)));
+ pw.println(String.format("LSKF last changed: %s (previous protector: %x)",
+ timestampToString(getLong(LSKF_LAST_CHANGED_TIME_KEY, 0, userId)),
+ getLong(PREV_LSKF_BASED_PROTECTOR_ID_KEY, 0, userId)));
}
try {
pw.println(String.format("SID: %x",
@@ -3340,14 +3314,15 @@ public class LockSettingsService extends ILockSettings.Stub {
}
@Override
- public void onRebootEscrowRestored(byte spVersion, byte[] syntheticPassword, int userId) {
- SyntheticPasswordManager.AuthenticationToken
- authToken = new SyntheticPasswordManager.AuthenticationToken(spVersion);
- authToken.recreateDirectly(syntheticPassword);
+ public void onRebootEscrowRestored(byte spVersion, byte[] rawSyntheticPassword,
+ int userId) {
+ SyntheticPasswordManager.SyntheticPassword
+ sp = new SyntheticPasswordManager.SyntheticPassword(spVersion);
+ sp.recreateDirectly(rawSyntheticPassword);
synchronized (mSpManager) {
- mSpManager.verifyChallenge(getGateKeeperService(), authToken, 0L, userId);
+ mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
}
- onCredentialVerified(authToken, loadPasswordMetrics(authToken, userId), userId);
+ onCredentialVerified(sp, loadPasswordMetrics(sp, userId), userId);
}
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
index 92bb26a60f7b..e5b50362b03d 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -380,29 +380,30 @@ class LockSettingsStorage {
}
}
- public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
+ public void writeSyntheticPasswordState(int userId, long protectorId, String name,
+ byte[] data) {
ensureSyntheticPasswordDirectoryForUser(userId);
- writeFile(getSyntheticPasswordStateFileForUser(userId, handle, name), data);
+ writeFile(getSyntheticPasswordStateFileForUser(userId, protectorId, name), data);
}
- public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
- return readFile(getSyntheticPasswordStateFileForUser(userId, handle, name));
+ public byte[] readSyntheticPasswordState(int userId, long protectorId, String name) {
+ return readFile(getSyntheticPasswordStateFileForUser(userId, protectorId, name));
}
- public void deleteSyntheticPasswordState(int userId, long handle, String name) {
- deleteFile(getSyntheticPasswordStateFileForUser(userId, handle, name));
+ public void deleteSyntheticPasswordState(int userId, long protectorId, String name) {
+ deleteFile(getSyntheticPasswordStateFileForUser(userId, protectorId, name));
}
- public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
+ public Map<Integer, List<Long>> listSyntheticPasswordProtectorsForAllUsers(String stateName) {
Map<Integer, List<Long>> result = new ArrayMap<>();
final UserManager um = UserManager.get(mContext);
for (UserInfo user : um.getUsers()) {
- result.put(user.id, listSyntheticPasswordHandlesForUser(stateName, user.id));
+ result.put(user.id, listSyntheticPasswordProtectorsForUser(stateName, user.id));
}
return result;
}
- public List<Long> listSyntheticPasswordHandlesForUser(String stateName, int userId) {
+ public List<Long> listSyntheticPasswordProtectorsForUser(String stateName, int userId) {
File baseDir = getSyntheticPasswordDirectoryForUser(userId);
List<Long> result = new ArrayList<>();
File[] files = baseDir.listFiles();
@@ -415,7 +416,7 @@ class LockSettingsStorage {
try {
result.add(Long.parseUnsignedLong(parts[0], 16));
} catch (NumberFormatException e) {
- Slog.e(TAG, "Failed to parse handle " + parts[0]);
+ Slog.e(TAG, "Failed to parse protector ID " + parts[0]);
}
}
}
@@ -435,8 +436,8 @@ class LockSettingsStorage {
}
}
- private File getSyntheticPasswordStateFileForUser(int userId, long handle, String name) {
- String fileName = formatSimple("%016x.%s", handle, name);
+ private File getSyntheticPasswordStateFileForUser(int userId, long protectorId, String name) {
+ String fileName = formatSimple("%016x.%s", protectorId, name);
return new File(getSyntheticPasswordDirectoryForUser(userId), fileName);
}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
index c8f1cb29d826..b06af8e5a385 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
@@ -17,6 +17,7 @@
package com.android.server.locksettings;
import android.security.AndroidKeyStoreMaintenance;
+import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
@@ -52,7 +53,7 @@ public class SyntheticPasswordCrypto {
private static final int PROFILE_KEY_IV_SIZE = 12;
private static final int DEFAULT_TAG_LENGTH_BITS = 128;
private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
- private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
+ private static final byte[] PROTECTOR_SECRET_PERSONALIZATION = "application-id".getBytes();
// Time between the user credential is verified with GK and the decryption of synthetic password
// under the auth-bound key. This should always happen one after the other, but give it 15
// seconds just to be sure.
@@ -127,15 +128,19 @@ public class SyntheticPasswordCrypto {
}
}
- public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] applicationId) {
+ /**
+ * Decrypt a legacy SP blob which did the Keystore and software encryption layers in the wrong
+ * order.
+ */
+ public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] protectorSecret) {
try {
KeyStore keyStore = getKeyStore();
- SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
- if (decryptionKey == null) {
+ SecretKey keyStoreKey = (SecretKey) keyStore.getKey(keyAlias, null);
+ if (keyStoreKey == null) {
throw new IllegalStateException("SP key is missing: " + keyAlias);
}
- byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
- return decrypt(decryptionKey, intermediate);
+ byte[] intermediate = decrypt(protectorSecret, PROTECTOR_SECRET_PERSONALIZATION, blob);
+ return decrypt(keyStoreKey, intermediate);
} catch (Exception e) {
Slog.e(TAG, "Failed to decrypt V1 blob", e);
throw new IllegalStateException("Failed to decrypt blob", e);
@@ -157,16 +162,19 @@ public class SyntheticPasswordCrypto {
return keyStore;
}
- public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
+ /**
+ * Decrypts an SP blob that was created by {@link #createBlob}.
+ */
+ public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] protectorSecret) {
try {
final KeyStore keyStore = getKeyStore();
- SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
- if (decryptionKey == null) {
+ SecretKey keyStoreKey = (SecretKey) keyStore.getKey(keyAlias, null);
+ if (keyStoreKey == null) {
throw new IllegalStateException("SP key is missing: " + keyAlias);
}
- byte[] intermediate = decrypt(decryptionKey, blob);
- return decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
+ byte[] intermediate = decrypt(keyStoreKey, blob);
+ return decrypt(protectorSecret, PROTECTOR_SECRET_PERSONALIZATION, intermediate);
} catch (CertificateException | IOException | BadPaddingException
| IllegalBlockSizeException
| KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
@@ -177,11 +185,22 @@ public class SyntheticPasswordCrypto {
}
}
- public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
+ /**
+ * Creates a new SP blob by encrypting the given data. Two encryption layers are applied: an
+ * inner layer using a hash of protectorSecret as the key, and an outer layer using a new
+ * Keystore key with the given alias and optionally bound to a SID.
+ *
+ * The reason we use a layer of software encryption, instead of using protectorSecret as the
+ * applicationId of the Keystore key, is to work around buggy KeyMint implementations that don't
+ * cryptographically bind the applicationId to the key. The Keystore layer has to be the outer
+ * layer, so that LSKF verification is ratelimited by Gatekeeper when Weaver is unavailable.
+ */
+ public static byte[] createBlob(String keyAlias, byte[] data, byte[] protectorSecret,
+ long sid) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
keyGenerator.init(AES_KEY_LENGTH * 8, new SecureRandom());
- SecretKey secretKey = keyGenerator.generateKey();
+ SecretKey keyStoreKey = keyGenerator.generateKey();
final KeyStore keyStore = getKeyStore();
KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
@@ -192,12 +211,28 @@ public class SyntheticPasswordCrypto {
.setBoundToSpecificSecureUserId(sid)
.setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
}
+ final KeyProtection protNonRollbackResistant = builder.build();
+ builder.setRollbackResistant(true);
+ final KeyProtection protRollbackResistant = builder.build();
+ final KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(keyStoreKey);
+ try {
+ keyStore.setEntry(keyAlias, entry, protRollbackResistant);
+ Slog.i(TAG, "Using rollback-resistant key");
+ } catch (KeyStoreException e) {
+ if (!(e.getCause() instanceof android.security.KeyStoreException)) {
+ throw e;
+ }
+ int errorCode = ((android.security.KeyStoreException) e.getCause()).getErrorCode();
+ if (errorCode != KeymasterDefs.KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE) {
+ throw e;
+ }
+ Slog.w(TAG, "Rollback-resistant keys unavailable. Falling back to "
+ + "non-rollback-resistant key");
+ keyStore.setEntry(keyAlias, entry, protNonRollbackResistant);
+ }
- keyStore.setEntry(keyAlias,
- new KeyStore.SecretKeyEntry(secretKey),
- builder.build());
- byte[] intermediate = encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, data);
- return encrypt(secretKey, intermediate);
+ byte[] intermediate = encrypt(protectorSecret, PROTECTOR_SECRET_PERSONALIZATION, data);
+ return encrypt(keyStoreKey, intermediate);
} catch (CertificateException | IOException | BadPaddingException
| IllegalBlockSizeException
| KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index f5151c4ace19..2d0143abb93f 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -68,32 +68,42 @@ import java.util.Set;
/**
- * A class that maintains the wrapping of synthetic password by user credentials or escrow tokens.
- * It's (mostly) a pure storage for synthetic passwords, providing APIs to creating and destroying
- * synthetic password blobs which are wrapped by user credentials or escrow tokens.
+ * A class that manages a user's synthetic password (SP) ({@link #SyntheticPassword}), along with a
+ * set of SP protectors that are independent ways that the SP is protected.
*
- * Here is the assumptions it makes:
- * Each user has one single synthetic password at any time.
- * The SP has an associated password handle, which binds to the SID for that user. The password
- * handle is persisted by SyntheticPasswordManager internally.
- * If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
+ * Invariants for SPs:
*
- * Information persisted on disk:
- * for each user (stored under DEFAULT_HANDLE):
- * SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
- * credential exists, cleared when user clears their credential.
- * SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
- * tokens. Destroyed when escrow support is turned off for the given user.
+ * - A user's SP never changes, but SP protectors can be added and removed. There is always a
+ * protector that protects the SP with the user's Lock Screen Knowledge Factor (LSKF), a.k.a.
+ * LockscreenCredential. The LSKF may be empty (none). There may be escrow token-based
+ * protectors as well, only for specific use cases such as enterprise-managed users.
*
- * for each SP blob under the user (stored under the corresponding handle):
- * SP_BLOB_NAME: The encrypted synthetic password. Always exists.
- * PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
- * SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
- * purpose of secure deletion. Exists if this is a non-weaver SP
- * (both password and token based), or it's a token-based SP under weaver.
- * WEAVER_SLOT: Metadata about the weaver slot used. Only exists if this is a SP under weaver.
+ * - While the user's LSKF is nonempty, the SP protects the user's CE (credential encrypted)
+ * storage and auth-bound Keystore keys: the user's CE key is encrypted by an SP-derived secret,
+ * and the user's Keystore and Gatekeeper passwords are other SP-derived secrets. However, while
+ * the user's LSKF is empty, these protections are cleared; this is needed to invalidate the
+ * auth-bound keys and make UserController.unlockUser() work with an empty secret.
*
+ * Files stored on disk for each user:
+ * For the SP itself, stored under NULL_PROTECTOR_ID:
+ * SP_HANDLE_NAME: GateKeeper password handle of a password derived from the SP. Only exists
+ * while the LSKF is nonempty.
+ * SP_E0_NAME, SP_P1_NAME: Information needed to create and use escrow token-based protectors.
+ * Deleted when escrow token support is disabled for the user.
*
+ * For each protector, stored under the corresponding protector ID:
+ * SP_BLOB_NAME: The encrypted SP secret (the SP itself or the P0 value). Always exists.
+ * PASSWORD_DATA_NAME: Data used for LSKF verification, such as the scrypt salt and
+ * parameters. Only exists for LSKF-based protectors.
+ * PASSWORD_METRICS_NAME: Metrics about the LSKF, encrypted by a key derived from the SP.
+ * Only exists for LSKF-based protectors.
+ * SECDISCARDABLE_NAME: A large number of random bytes that all need to be known in order to
+ * decrypt SP_BLOB_NAME. When the protector is deleted, this file is
+ * overwritten and deleted as a "best-effort" attempt to support secure
+ * deletion when hardware support for secure deletion is unavailable.
+ * Doesn't exist for LSKF-based protectors that use Weaver.
+ * WEAVER_SLOT: Contains the Weaver slot number used by this protector. Only exists if the
+ * protector uses Weaver.
*/
public class SyntheticPasswordManager {
private static final String SP_BLOB_NAME = "spblob";
@@ -106,18 +116,24 @@ public class SyntheticPasswordManager {
private static final String WEAVER_SLOT_NAME = "weaver";
private static final String PASSWORD_METRICS_NAME = "metrics";
- public static final long DEFAULT_HANDLE = 0L;
+ // used for files associated with the SP itself, not with a particular protector
+ public static final long NULL_PROTECTOR_ID = 0L;
+
private static final byte[] DEFAULT_PASSWORD = "default-password".getBytes();
private static final byte WEAVER_VERSION = 1;
private static final int INVALID_WEAVER_SLOT = -1;
+ // Careful: the SYNTHETIC_PASSWORD_* version numbers are overloaded to identify both the version
+ // of the protector and the version of the synthetic password itself. All a user's protectors
+ // must use a version that treats the synthetic password itself in a compatible way.
private static final byte SYNTHETIC_PASSWORD_VERSION_V1 = 1;
private static final byte SYNTHETIC_PASSWORD_VERSION_V2 = 2;
private static final byte SYNTHETIC_PASSWORD_VERSION_V3 = 3;
- private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
- private static final byte SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED = 1;
- private static final byte SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED = 2;
+
+ private static final byte PROTECTOR_TYPE_LSKF_BASED = 0;
+ private static final byte PROTECTOR_TYPE_STRONG_TOKEN_BASED = 1;
+ private static final byte PROTECTOR_TYPE_WEAK_TOKEN_BASED = 2;
// 256-bit synthetic password
private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
@@ -147,7 +163,7 @@ public class SyntheticPasswordManager {
static class AuthenticationResult {
// Non-null if password/token passes verification, null otherwise
- @Nullable public AuthenticationToken authToken;
+ @Nullable public SyntheticPassword syntheticPassword;
// OK: password / token passes verification, user has a lockscreen
// null: user does not have a lockscreen (but password / token passes verification)
// ERROR: password / token fails verification
@@ -156,39 +172,34 @@ public class SyntheticPasswordManager {
}
/**
- * This class represents the main cryptographic secret for a given user (a.k.a synthietic
- * password). This secret is derived from the user's lockscreen credential or password escrow
- * token. All other cryptograhic keys related to the user, including disk encryption key,
- * keystore encryption key, gatekeeper auth key, vendor auth secret and others are directly
- * derived from this token.
- * <p>
- * The main secret associated with an authentication token is retrievable from
- * {@link AuthenticationToken#getSyntheticPassword()} and the authentication token can be
- * reconsturcted from the main secret later with
- * {@link AuthenticationToken#recreateDirectly(byte[])}. The first time an authentication token
- * is needed, it should be created with {@link AuthenticationToken#create()} so that the
- * necessary escrow data ({@link #mEncryptedEscrowSplit0} and {@link #mEscrowSplit1}) is
- * properly initialized. The caller can either persist the (non-secret) esscrow data if escrow
- * is required, or discard it to cryptograhically disable escrow. To support escrow, the caller
- * needs to securely store the secret returned from
- * {@link AuthenticationToken#getEscrowSecret()}, and at the time of use, load the escrow data
- * back with {@link AuthenticationToken#setEscrowData(byte[], byte[])} and then re-create the
- * main secret from the escrow secret via
- * {@link AuthenticationToken#recreateFromEscrow(byte[])}.
+ * A synthetic password (SP) is the main cryptographic secret for a user. The SP is used only
+ * as input to a Key Derivation Function (KDF) to derive other keys.
+ *
+ * SPs are created by {@link SyntheticPassword#create()} as the hash of two random values P0 and
+ * P1. E0 (P0 encrypted by an SP-derived key) and P1 can then be stored on-disk. This approach
+ * is used instead of direct random generation of the SP so that escrow token-based protectors
+ * can protect P0 instead of the SP itself. This makes it possible to cryptographically disable
+ * the ability to create and use such protectors by deleting (or never storing) E0 and P1.
+ *
+ * When protecting the SP directly, use {@link SyntheticPassword#getSyntheticPassword()} to get
+ * the raw SP, and later {@link SyntheticPassword#recreateDirectly(byte[])} to re-create the SP.
+ * When protecting P0, use {@link SyntheticPassword#getEscrowSecret()} to get P0, and later
+ * {@link SyntheticPassword#setEscrowData(byte[], byte[])} followed by
+ * {@link SyntheticPassword#recreateFromEscrow()} to re-create the SP.
*/
- static class AuthenticationToken {
+ static class SyntheticPassword {
private final byte mVersion;
/**
* Here is the relationship between these fields:
* Generate two random block P0 and P1. P1 is recorded in mEscrowSplit1 but P0 is not.
* mSyntheticPassword = hash(P0 || P1)
- * E0 = P0 encrypted under syntheticPassword, recoreded in mEncryptedEscrowSplit0.
+ * E0 = P0 encrypted under syntheticPassword, recorded in mEncryptedEscrowSplit0.
*/
private @NonNull byte[] mSyntheticPassword;
private @Nullable byte[] mEncryptedEscrowSplit0;
private @Nullable byte[] mEscrowSplit1;
- AuthenticationToken(byte version) {
+ SyntheticPassword(byte version) {
mVersion = version;
}
@@ -214,7 +225,7 @@ public class SyntheticPasswordManager {
return deriveSubkey(PERSONALIZATION_SP_GK_AUTH);
}
- public byte[] deriveDiskEncryptionKey() {
+ public byte[] deriveFileBasedEncryptionKey() {
return deriveSubkey(PERSONALIZATION_FBE_KEY);
}
@@ -232,8 +243,8 @@ public class SyntheticPasswordManager {
}
/**
- * Assign escrow data to this auth token. This is a prerequisite to call
- * {@link AuthenticationToken#recreateFromEscrow}.
+ * Assigns escrow data to this synthetic password. This is a prerequisite to call
+ * {@link SyntheticPassword#recreateFromEscrow}.
*/
public void setEscrowData(@Nullable byte[] encryptedEscrowSplit0,
@Nullable byte[] escrowSplit1) {
@@ -242,8 +253,8 @@ public class SyntheticPasswordManager {
}
/**
- * Re-creates authentication token from escrow secret (escrowSplit0, returned from
- * {@link AuthenticationToken#getEscrowSecret}). Escrow data needs to be loaded
+ * Re-creates a synthetic password from the escrow secret (escrowSplit0, returned from
+ * {@link SyntheticPassword#getEscrowSecret}). Escrow data needs to be loaded
* by {@link #setEscrowData} before calling this.
*/
public void recreateFromEscrow(byte[] escrowSplit0) {
@@ -253,7 +264,7 @@ public class SyntheticPasswordManager {
}
/**
- * Re-creates authentication token from synthetic password directly.
+ * Re-creates a synthetic password from its raw bytes.
*/
public void recreateDirectly(byte[] syntheticPassword) {
this.mSyntheticPassword = Arrays.copyOf(syntheticPassword, syntheticPassword.length);
@@ -262,8 +273,8 @@ public class SyntheticPasswordManager {
/**
* Generates a new random synthetic password with escrow data.
*/
- static AuthenticationToken create() {
- AuthenticationToken result = new AuthenticationToken(SYNTHETIC_PASSWORD_VERSION_V3);
+ static SyntheticPassword create() {
+ SyntheticPassword result = new SyntheticPassword(SYNTHETIC_PASSWORD_VERSION_V3);
byte[] escrowSplit0 = secureRandom(SYNTHETIC_PASSWORD_LENGTH);
byte[] escrowSplit1 = secureRandom(SYNTHETIC_PASSWORD_LENGTH);
result.recreate(escrowSplit0, escrowSplit1);
@@ -275,7 +286,7 @@ public class SyntheticPasswordManager {
/**
* Re-creates synthetic password from both escrow splits. See javadoc for
- * AuthenticationToken.mSyntheticPassword for details on what each block means.
+ * SyntheticPassword.mSyntheticPassword for details on what each block means.
*/
private void recreate(byte[] escrowSplit0, byte[] escrowSplit1) {
mSyntheticPassword = bytesToHex(SyntheticPasswordCrypto.personalizedHash(
@@ -283,8 +294,8 @@ public class SyntheticPasswordManager {
}
/**
- * Returns the escrow secret that can be used later to reconstruct this authentication
- * token from {@link #recreateFromEscrow(byte[])}. Only possible if escrow is not disabled
+ * Returns the escrow secret that can be used later to reconstruct this synthetic password
+ * from {@link #recreateFromEscrow(byte[])}. Only possible if escrow is not disabled
* (encryptedEscrowSplit0 known).
*/
public byte[] getEscrowSecret() {
@@ -296,16 +307,15 @@ public class SyntheticPasswordManager {
}
/**
- * Returns the raw synthetic password that can be used later to reconstruct this
- * authentication token from {@link #recreateDirectly(byte[])}
+ * Returns the raw synthetic password, for later use with {@link #recreateDirectly(byte[])}.
*/
public byte[] getSyntheticPassword() {
return mSyntheticPassword;
}
/**
- * Returns the version of this AuthenticationToken for use with reconstructing
- * this with a synthetic password version.
+ * Returns the version number of this synthetic password. This version number determines
+ * the algorithm used to derive subkeys.
*/
public byte getVersion() {
return mVersion;
@@ -318,8 +328,8 @@ public class SyntheticPasswordManager {
byte scryptLogP;
public int credentialType;
byte[] salt;
- // For GateKeeper-based credential, this is the password handle returned by GK,
- // for weaver-based credential, this is empty.
+ // If Weaver is available, then this field is empty. Otherwise, it is the Gatekeeper
+ // password handle that resulted from enrolling the hashed LSKF.
public byte[] passwordHandle;
public static PasswordData create(int passwordType) {
@@ -377,13 +387,14 @@ public class SyntheticPasswordManager {
static class SyntheticPasswordBlob {
byte mVersion;
- byte mType;
+ byte mProtectorType;
byte[] mContent;
- public static SyntheticPasswordBlob create(byte version, byte type, byte[] content) {
+ public static SyntheticPasswordBlob create(byte version, byte protectorType,
+ byte[] content) {
SyntheticPasswordBlob result = new SyntheticPasswordBlob();
result.mVersion = version;
- result.mType = type;
+ result.mProtectorType = protectorType;
result.mContent = content;
return result;
}
@@ -391,7 +402,7 @@ public class SyntheticPasswordManager {
public static SyntheticPasswordBlob fromBytes(byte[] data) {
SyntheticPasswordBlob result = new SyntheticPasswordBlob();
result.mVersion = data[0];
- result.mType = data[1];
+ result.mProtectorType = data[1];
result.mContent = Arrays.copyOfRange(data, 2, data.length);
return result;
}
@@ -399,7 +410,7 @@ public class SyntheticPasswordManager {
public byte[] toByte() {
byte[] blob = new byte[mContent.length + 1 + 1];
blob[0] = mVersion;
- blob[1] = mType;
+ blob[1] = mProtectorType;
System.arraycopy(mContent, 0, blob, 2, mContent.length);
return blob;
}
@@ -569,9 +580,10 @@ public class SyntheticPasswordManager {
}
public void removeUser(IGateKeeperService gatekeeper, int userId) {
- for (long handle : mStorage.listSyntheticPasswordHandlesForUser(SP_BLOB_NAME, userId)) {
- destroyWeaverSlot(handle, userId);
- destroySPBlobKey(getKeyName(handle));
+ for (long protectorId : mStorage.listSyntheticPasswordProtectorsForUser(SP_BLOB_NAME,
+ userId)) {
+ destroyWeaverSlot(protectorId, userId);
+ destroySPBlobKey(getKeyName(protectorId));
}
// Remove potential persistent state (in RPMB), to prevent them from accumulating and
// causing problems.
@@ -582,8 +594,8 @@ public class SyntheticPasswordManager {
}
}
- int getCredentialType(long handle, int userId) {
- byte[] passwordData = loadState(PASSWORD_DATA_NAME, handle, userId);
+ int getCredentialType(long protectorId, int userId) {
+ byte[] passwordData = loadState(PASSWORD_DATA_NAME, protectorId, userId);
if (passwordData == null) {
Slog.w(TAG, "getCredentialType: encountered empty password data for user " + userId);
return LockPatternUtils.CREDENTIAL_TYPE_NONE;
@@ -599,9 +611,7 @@ public class SyntheticPasswordManager {
}
/**
- * Initializes a new Authentication token for the given user.
- *
- * The authentication token will bear a randomly-generated synthetic password.
+ * Creates a new synthetic password (SP) for the given user.
*
* Any existing SID for the user is cleared.
*
@@ -609,22 +619,21 @@ public class SyntheticPasswordManager {
* an escrow scheme. This information can be removed with {@link #destroyEscrowData} if
* password escrow should be disabled completely on the given user.
*/
- AuthenticationToken newSyntheticPassword(int userId) {
+ SyntheticPassword newSyntheticPassword(int userId) {
clearSidForUser(userId);
- AuthenticationToken result = AuthenticationToken.create();
+ SyntheticPassword result = SyntheticPassword.create();
saveEscrowData(result, userId);
return result;
}
/**
* Enroll a new password handle and SID for the given synthetic password and persist it on disk.
- * Used when adding password to previously-unsecured devices.
+ * Used when the LSKF is changed from empty to nonempty.
*/
- public void newSidForUser(IGateKeeperService gatekeeper, AuthenticationToken authToken,
- int userId) {
+ public void newSidForUser(IGateKeeperService gatekeeper, SyntheticPassword sp, int userId) {
GateKeeperResponse response;
try {
- response = gatekeeper.enroll(userId, null, null, authToken.deriveGkPassword());
+ response = gatekeeper.enroll(userId, null, null, sp.deriveGkPassword());
} catch (RemoteException e) {
throw new IllegalStateException("Failed to create new SID for user", e);
}
@@ -637,49 +646,48 @@ public class SyntheticPasswordManager {
// Nuke the SP handle (and as a result, its SID) for the given user.
public void clearSidForUser(int userId) {
- destroyState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+ destroyState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId);
}
public boolean hasSidForUser(int userId) {
- return hasState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+ return hasState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId);
}
- // if null, it means there is no SID associated with the user
- // This can happen if the user is migrated to SP but currently
- // do not have a lockscreen password.
+ // If this returns null, it means there is no SID associated with the user. This happens if the
+ // user has an empty LSKF, but does have an SP.
private byte[] loadSyntheticPasswordHandle(int userId) {
- return loadState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+ return loadState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId);
}
private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) {
- saveState(SP_HANDLE_NAME, spHandle, DEFAULT_HANDLE, userId);
+ saveState(SP_HANDLE_NAME, spHandle, NULL_PROTECTOR_ID, userId);
}
- private boolean loadEscrowData(AuthenticationToken authToken, int userId) {
- byte[] e0 = loadState(SP_E0_NAME, DEFAULT_HANDLE, userId);
- byte[] p1 = loadState(SP_P1_NAME, DEFAULT_HANDLE, userId);
- authToken.setEscrowData(e0, p1);
+ private boolean loadEscrowData(SyntheticPassword sp, int userId) {
+ byte[] e0 = loadState(SP_E0_NAME, NULL_PROTECTOR_ID, userId);
+ byte[] p1 = loadState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
+ sp.setEscrowData(e0, p1);
return e0 != null && p1 != null;
}
- private void saveEscrowData(AuthenticationToken authToken, int userId) {
- saveState(SP_E0_NAME, authToken.mEncryptedEscrowSplit0, DEFAULT_HANDLE, userId);
- saveState(SP_P1_NAME, authToken.mEscrowSplit1, DEFAULT_HANDLE, userId);
+ private void saveEscrowData(SyntheticPassword sp, int userId) {
+ saveState(SP_E0_NAME, sp.mEncryptedEscrowSplit0, NULL_PROTECTOR_ID, userId);
+ saveState(SP_P1_NAME, sp.mEscrowSplit1, NULL_PROTECTOR_ID, userId);
}
public boolean hasEscrowData(int userId) {
- return hasState(SP_E0_NAME, DEFAULT_HANDLE, userId)
- && hasState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+ return hasState(SP_E0_NAME, NULL_PROTECTOR_ID, userId)
+ && hasState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
}
public void destroyEscrowData(int userId) {
- destroyState(SP_E0_NAME, DEFAULT_HANDLE, userId);
- destroyState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+ destroyState(SP_E0_NAME, NULL_PROTECTOR_ID, userId);
+ destroyState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
}
- private int loadWeaverSlot(long handle, int userId) {
+ private int loadWeaverSlot(long protectorId, int userId) {
final int LENGTH = Byte.BYTES + Integer.BYTES;
- byte[] data = loadState(WEAVER_SLOT_NAME, handle, userId);
+ byte[] data = loadState(WEAVER_SLOT_NAME, protectorId, userId);
if (data == null || data.length != LENGTH) {
return INVALID_WEAVER_SLOT;
}
@@ -687,22 +695,22 @@ public class SyntheticPasswordManager {
buffer.put(data, 0, data.length);
buffer.flip();
if (buffer.get() != WEAVER_VERSION) {
- Slog.e(TAG, "Invalid weaver slot version of handle " + handle);
+ Slog.e(TAG, "Invalid weaver slot version for protector " + protectorId);
return INVALID_WEAVER_SLOT;
}
return buffer.getInt();
}
- private void saveWeaverSlot(int slot, long handle, int userId) {
+ private void saveWeaverSlot(int slot, long protectorId, int userId) {
ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Integer.BYTES);
buffer.put(WEAVER_VERSION);
buffer.putInt(slot);
- saveState(WEAVER_SLOT_NAME, buffer.array(), handle, userId);
+ saveState(WEAVER_SLOT_NAME, buffer.array(), protectorId, userId);
}
- private void destroyWeaverSlot(long handle, int userId) {
- int slot = loadWeaverSlot(handle, userId);
- destroyState(WEAVER_SLOT_NAME, handle, userId);
+ private void destroyWeaverSlot(long protectorId, int userId) {
+ int slot = loadWeaverSlot(protectorId, userId);
+ destroyState(WEAVER_SLOT_NAME, protectorId, userId);
if (slot != INVALID_WEAVER_SLOT) {
Set<Integer> usedSlots = getUsedWeaverSlots();
if (!usedSlots.contains(slot)) {
@@ -726,12 +734,12 @@ public class SyntheticPasswordManager {
* unintentionally.
*/
private Set<Integer> getUsedWeaverSlots() {
- Map<Integer, List<Long>> slotHandles = mStorage.listSyntheticPasswordHandlesForAllUsers(
- WEAVER_SLOT_NAME);
+ Map<Integer, List<Long>> protectorIds =
+ mStorage.listSyntheticPasswordProtectorsForAllUsers(WEAVER_SLOT_NAME);
HashSet<Integer> slots = new HashSet<>();
- for (Map.Entry<Integer, List<Long>> entry : slotHandles.entrySet()) {
- for (Long handle : entry.getValue()) {
- int slot = loadWeaverSlot(handle, entry.getKey());
+ for (Map.Entry<Integer, List<Long>> entry : protectorIds.entrySet()) {
+ for (Long protectorId : entry.getValue()) {
+ int slot = loadWeaverSlot(protectorId, entry.getKey());
slots.add(slot);
}
}
@@ -750,29 +758,24 @@ public class SyntheticPasswordManager {
}
/**
- * Create a new password based SP blob based on the supplied authentication token, such that
- * a future successful authentication with unwrapPasswordBasedSyntheticPassword() would result
- * in the same authentication token.
+ * Creates a protector that protects the user's SP with the given LSKF (which may be empty).
*
- * This method only creates SP blob wrapping around the given synthetic password and does not
- * handle logic around SID or SP handle. The caller should separately ensure that the user's SID
- * is consistent with the device state by calling other APIs in this class.
+ * This method only creates a new protector that isn't referenced by anything; it doesn't handle
+ * any higher-level tasks involved in changing the LSKF.
*
- * @see #newSidForUser
- * @see #clearSidForUser
- * @return a new password handle for the wrapped SP blob
- * @throw IllegalStateException if creation fails.
+ * @return the ID of the new protector
+ * @throws IllegalStateException on failure
*/
- public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
- LockscreenCredential credential, AuthenticationToken authToken, int userId) {
- long handle = generateHandle();
+ public long createLskfBasedProtector(IGateKeeperService gatekeeper,
+ LockscreenCredential credential, SyntheticPassword sp, int userId) {
+ long protectorId = generateProtectorId();
PasswordData pwd = PasswordData.create(credential.getType());
byte[] pwdToken = computePasswordToken(credential, pwd);
final long sid;
- final byte[] applicationId;
+ final byte[] protectorSecret;
if (isWeaverAvailable()) {
- // Weaver based user password
+ // Protector uses Weaver to verify the LSKF
int weaverSlot = getNextAvailableWeaverSlot();
Slog.i(TAG, "Weaver enroll password to slot " + weaverSlot + " for user " + userId);
byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken),
@@ -781,15 +784,17 @@ public class SyntheticPasswordManager {
throw new IllegalStateException(
"Fail to enroll user password under weaver " + userId);
}
- saveWeaverSlot(weaverSlot, handle, userId);
+ saveWeaverSlot(weaverSlot, protectorId, userId);
mPasswordSlotManager.markSlotInUse(weaverSlot);
// No need to pass in quality since the credential type already encodes sufficient info
synchronizeWeaverFrpPassword(pwd, 0, userId, weaverSlot);
pwd.passwordHandle = null;
sid = GateKeeper.INVALID_SECURE_USER_ID;
- applicationId = transformUnderWeaverSecret(pwdToken, weaverSecret);
+ protectorSecret = transformUnderWeaverSecret(pwdToken, weaverSecret);
} else {
+ // Protector uses Gatekeeper to verify the LSKF
+
// In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
// to prevent them from accumulating and causing problems.
try {
@@ -797,30 +802,30 @@ public class SyntheticPasswordManager {
} catch (RemoteException ignore) {
Slog.w(TAG, "Failed to clear SID from gatekeeper");
}
- // GateKeeper based user password
GateKeeperResponse response;
try {
response = gatekeeper.enroll(fakeUid(userId), null, null,
passwordTokenToGkInput(pwdToken));
} catch (RemoteException e) {
- throw new IllegalStateException("Failed to enroll password for new SP blob", e);
+ throw new IllegalStateException("Failed to enroll LSKF for new SP protector for "
+ + "user " + userId, e);
}
if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
- throw new IllegalStateException(
- "Fail to enroll user password when creating SP for user " + userId);
+ throw new IllegalStateException("Failed to enroll LSKF for new SP protector for "
+ + "user " + userId);
}
pwd.passwordHandle = response.getPayload();
sid = sidFromPasswordHandle(pwd.passwordHandle);
- applicationId = transformUnderSecdiscardable(pwdToken,
- createSecdiscardable(handle, userId));
+ protectorSecret = transformUnderSecdiscardable(pwdToken,
+ createSecdiscardable(protectorId, userId));
// No need to pass in quality since the credential type already encodes sufficient info
synchronizeFrpPassword(pwd, 0, userId);
}
- saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
- savePasswordMetrics(credential, authToken, handle, userId);
- createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
- applicationId, sid, userId);
- return handle;
+ saveState(PASSWORD_DATA_NAME, pwd.toBytes(), protectorId, userId);
+ savePasswordMetrics(credential, sp, protectorId, userId);
+ createSyntheticPasswordBlob(protectorId, PROTECTOR_TYPE_LSKF_BASED, sp, protectorSecret,
+ sid, userId);
+ return protectorId;
}
public VerifyCredentialResponse verifyFrpCredential(IGateKeeperService gatekeeper,
@@ -858,13 +863,14 @@ public class SyntheticPasswordManager {
}
- public void migrateFrpPasswordLocked(long handle, UserInfo userInfo, int requestedQuality) {
+ public void migrateFrpPasswordLocked(long protectorId, UserInfo userInfo,
+ int requestedQuality) {
if (mStorage.getPersistentDataBlockManager() != null
&& LockPatternUtils.userOwnsFrpCredential(mContext, userInfo)) {
- PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle,
+ PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, protectorId,
userInfo.id));
if (pwd.credentialType != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
- int weaverSlot = loadWeaverSlot(handle, userInfo.id);
+ int weaverSlot = loadWeaverSlot(protectorId, userInfo.id);
if (weaverSlot != INVALID_WEAVER_SLOT) {
synchronizeWeaverFrpPassword(pwd, requestedQuality, userInfo.id, weaverSlot);
} else {
@@ -905,12 +911,17 @@ public class SyntheticPasswordManager {
private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>();
/**
- * Create a token based Synthetic password of the given type for the given user.
- * @return the handle of the token
+ * Caches a pending escrow token in memory and pre-allocates an ID for a new SP protector. This
+ * ID also serves as a handle for the pending token.
+ *
+ * This method doesn't persist any data, and it doesn't require access to the SP.
+ * {@link #createTokenBasedProtector} can be called later to actually create the protector.
+ *
+ * @return the token handle
*/
- public long createTokenBasedSyntheticPassword(byte[] token, @TokenType int type, int userId,
+ public long addPendingToken(byte[] token, @TokenType int type, int userId,
@Nullable EscrowTokenStateChangeCallback changeCallback) {
- long handle = generateHandle();
+ long tokenHandle = generateProtectorId(); // tokenHandle is reused as protectorId later
if (!tokenMap.containsKey(userId)) {
tokenMap.put(userId, new ArrayMap<>());
}
@@ -928,8 +939,8 @@ public class SyntheticPasswordManager {
tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable);
tokenData.mCallback = changeCallback;
- tokenMap.get(userId).put(handle, tokenData);
- return handle;
+ tokenMap.get(userId).put(tokenHandle, tokenData);
+ return tokenHandle;
}
public Set<Long> getPendingTokensForUser(int userId) {
@@ -940,23 +951,22 @@ public class SyntheticPasswordManager {
}
/** Remove the given pending token. */
- public boolean removePendingToken(long handle, int userId) {
+ public boolean removePendingToken(long tokenHandle, int userId) {
if (!tokenMap.containsKey(userId)) {
return false;
}
- return tokenMap.get(userId).remove(handle) != null;
+ return tokenMap.get(userId).remove(tokenHandle) != null;
}
- public boolean activateTokenBasedSyntheticPassword(long handle, AuthenticationToken authToken,
- int userId) {
+ public boolean createTokenBasedProtector(long tokenHandle, SyntheticPassword sp, int userId) {
if (!tokenMap.containsKey(userId)) {
return false;
}
- TokenData tokenData = tokenMap.get(userId).get(handle);
+ TokenData tokenData = tokenMap.get(userId).get(tokenHandle);
if (tokenData == null) {
return false;
}
- if (!loadEscrowData(authToken, userId)) {
+ if (!loadEscrowData(sp, userId)) {
Slog.w(TAG, "User is not escrowable");
return false;
}
@@ -967,51 +977,52 @@ public class SyntheticPasswordManager {
Slog.e(TAG, "Failed to enroll weaver secret when activating token");
return false;
}
- saveWeaverSlot(slot, handle, userId);
+ saveWeaverSlot(slot, tokenHandle, userId);
mPasswordSlotManager.markSlotInUse(slot);
}
- saveSecdiscardable(handle, tokenData.secdiscardableOnDisk, userId);
- createSyntheticPasswordBlob(handle, getTokenBasedBlobType(tokenData.mType), authToken,
+ saveSecdiscardable(tokenHandle, tokenData.secdiscardableOnDisk, userId);
+ createSyntheticPasswordBlob(tokenHandle, getTokenBasedProtectorType(tokenData.mType), sp,
tokenData.aggregatedSecret, 0L, userId);
- tokenMap.get(userId).remove(handle);
+ tokenMap.get(userId).remove(tokenHandle);
if (tokenData.mCallback != null) {
- tokenData.mCallback.onEscrowTokenActivated(handle, userId);
+ tokenData.mCallback.onEscrowTokenActivated(tokenHandle, userId);
}
return true;
}
- private void createSyntheticPasswordBlob(long handle, byte type, AuthenticationToken authToken,
- byte[] applicationId, long sid, int userId) {
- final byte[] secret;
- if (type == SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED
- || type == SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED) {
- secret = authToken.getEscrowSecret();
+ private void createSyntheticPasswordBlob(long protectorId, byte protectorType,
+ SyntheticPassword sp, byte[] protectorSecret, long sid, int userId) {
+ final byte[] spSecret;
+ if (protectorType == PROTECTOR_TYPE_STRONG_TOKEN_BASED
+ || protectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) {
+ spSecret = sp.getEscrowSecret();
} else {
- secret = authToken.getSyntheticPassword();
+ spSecret = sp.getSyntheticPassword();
}
- byte[] content = createSPBlob(getKeyName(handle), secret, applicationId, sid);
+ byte[] content = createSPBlob(getKeyName(protectorId), spSecret, protectorSecret, sid);
/*
* We can upgrade from v1 to v2 because that's just a change in the way that
* the SP is stored. However, we can't upgrade to v3 because that is a change
* in the way that passwords are derived from the SP.
*/
- byte version = authToken.mVersion == SYNTHETIC_PASSWORD_VERSION_V3
+ byte version = sp.mVersion == SYNTHETIC_PASSWORD_VERSION_V3
? SYNTHETIC_PASSWORD_VERSION_V3 : SYNTHETIC_PASSWORD_VERSION_V2;
- SyntheticPasswordBlob blob = SyntheticPasswordBlob.create(version, type, content);
- saveState(SP_BLOB_NAME, blob.toByte(), handle, userId);
+ SyntheticPasswordBlob blob = SyntheticPasswordBlob.create(version, protectorType, content);
+ saveState(SP_BLOB_NAME, blob.toByte(), protectorId, userId);
}
/**
- * Decrypt a synthetic password by supplying the user credential and corresponding password
- * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
- * verification to referesh the SID & Auth token maintained by the system.
+ * Tries to unlock a user's LSKF-based SP protector, given its ID and the claimed LSKF (which
+ * may be empty). On success, returns the user's synthetic password, and also does a Gatekeeper
+ * verification to refresh the SID and HardwareAuthToken maintained by the system.
*/
- public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
- long handle, @NonNull LockscreenCredential credential, int userId,
+ public AuthenticationResult unlockLskfBasedProtector(IGateKeeperService gatekeeper,
+ long protectorId, @NonNull LockscreenCredential credential, int userId,
ICheckCredentialProgressCallback progressCallback) {
AuthenticationResult result = new AuthenticationResult();
- PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
+ PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, protectorId,
+ userId));
if (!credential.checkAgainstStoredType(pwd.credentialType)) {
Slog.e(TAG, String.format("Credential type mismatch: expected %d actual %d",
@@ -1022,13 +1033,13 @@ public class SyntheticPasswordManager {
byte[] pwdToken = computePasswordToken(credential, pwd);
- final byte[] applicationId;
+ final byte[] protectorSecret;
final long sid;
- int weaverSlot = loadWeaverSlot(handle, userId);
+ int weaverSlot = loadWeaverSlot(protectorId, userId);
if (weaverSlot != INVALID_WEAVER_SLOT) {
- // Weaver based user password
+ // Protector uses Weaver to verify the LSKF
if (!isWeaverAvailable()) {
- Slog.e(TAG, "No weaver service to unwrap password based SP");
+ Slog.e(TAG, "Protector uses Weaver, but Weaver is unavailable");
result.gkResponse = VerifyCredentialResponse.ERROR;
return result;
}
@@ -1037,9 +1048,10 @@ public class SyntheticPasswordManager {
return result;
}
sid = GateKeeper.INVALID_SECURE_USER_ID;
- applicationId = transformUnderWeaverSecret(pwdToken,
+ protectorSecret = transformUnderWeaverSecret(pwdToken,
result.gkResponse.getGatekeeperHAT());
} else {
+ // Protector uses Gatekeeper to verify the LSKF
byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
GateKeeperResponse response;
try {
@@ -1068,7 +1080,7 @@ public class SyntheticPasswordManager {
// Use the reenrollment opportunity to update credential type
// (getting rid of CREDENTIAL_TYPE_PASSWORD_OR_PIN)
pwd.credentialType = credential.getType();
- saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
+ saveState(PASSWORD_DATA_NAME, pwd.toBytes(), protectorId, userId);
synchronizeFrpPassword(pwd, 0, userId);
} else {
Slog.w(TAG, "Fail to re-enroll user password for user " + userId);
@@ -1083,8 +1095,8 @@ public class SyntheticPasswordManager {
return result;
}
sid = sidFromPasswordHandle(pwd.passwordHandle);
- applicationId = transformUnderSecdiscardable(pwdToken,
- loadSecdiscardable(handle, userId));
+ protectorSecret = transformUnderSecdiscardable(pwdToken,
+ loadSecdiscardable(protectorId, userId));
}
// Supplied credential passes first stage weaver/gatekeeper check so it should be correct.
// Notify the callback so the keyguard UI can proceed immediately.
@@ -1095,80 +1107,81 @@ public class SyntheticPasswordManager {
Slog.w(TAG, "progressCallback throws exception", e);
}
}
- result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
- applicationId, sid, userId);
+ result.syntheticPassword = unwrapSyntheticPasswordBlob(protectorId,
+ PROTECTOR_TYPE_LSKF_BASED, protectorSecret, sid, userId);
// Perform verifyChallenge to refresh auth tokens for GK if user password exists.
- result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+ result.gkResponse = verifyChallenge(gatekeeper, result.syntheticPassword, 0L, userId);
// Upgrade case: store the metrics if the device did not have stored metrics before, should
- // only happen once on old synthetic password blobs.
- if (result.authToken != null && !hasPasswordMetrics(handle, userId)) {
- savePasswordMetrics(credential, result.authToken, handle, userId);
+ // only happen once on old protectors.
+ if (result.syntheticPassword != null && !hasPasswordMetrics(protectorId, userId)) {
+ savePasswordMetrics(credential, result.syntheticPassword, protectorId, userId);
}
return result;
}
/**
- * Decrypt a synthetic password by supplying an escrow token and corresponding token
- * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
- * verification to referesh the SID & Auth token maintained by the system.
+ * Tries to unlock a token-based SP protector (weak or strong), given its ID and the claimed
+ * token. On success, returns the user's synthetic password, and also does a Gatekeeper
+ * verification to refresh the SID and HardwareAuthToken maintained by the system.
*/
- public @NonNull AuthenticationResult unwrapTokenBasedSyntheticPassword(
- IGateKeeperService gatekeeper, long handle, byte[] token, int userId) {
- SyntheticPasswordBlob blob = SyntheticPasswordBlob
- .fromBytes(loadState(SP_BLOB_NAME, handle, userId));
- return unwrapTokenBasedSyntheticPasswordInternal(gatekeeper, handle,
- blob.mType, token, userId);
+ public @NonNull AuthenticationResult unlockTokenBasedProtector(
+ IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) {
+ SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME,
+ protectorId, userId));
+ return unlockTokenBasedProtectorInternal(gatekeeper, protectorId, blob.mProtectorType,
+ token, userId);
}
/**
- * Decrypt a synthetic password by supplying an strong escrow token and corresponding token
- * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
- * verification to referesh the SID & Auth token maintained by the system.
+ * Like {@link #unlockTokenBasedProtector}, but throws an exception if the protector is not for
+ * a strong token specifically.
*/
- public @NonNull AuthenticationResult unwrapStrongTokenBasedSyntheticPassword(
- IGateKeeperService gatekeeper, long handle, byte[] token, int userId) {
- return unwrapTokenBasedSyntheticPasswordInternal(gatekeeper, handle,
- SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED, token, userId);
+ public @NonNull AuthenticationResult unlockStrongTokenBasedProtector(
+ IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) {
+ return unlockTokenBasedProtectorInternal(gatekeeper, protectorId,
+ PROTECTOR_TYPE_STRONG_TOKEN_BASED, token, userId);
}
/**
- * Decrypt a synthetic password by supplying a weak escrow token and corresponding token
- * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
- * verification to referesh the SID & Auth token maintained by the system.
+ * Like {@link #unlockTokenBasedProtector}, but throws an exception if the protector is not for
+ * a weak token specifically.
*/
- public @NonNull AuthenticationResult unwrapWeakTokenBasedSyntheticPassword(
- IGateKeeperService gatekeeper, long handle, byte[] token, int userId) {
- return unwrapTokenBasedSyntheticPasswordInternal(gatekeeper, handle,
- SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED, token, userId);
+ public @NonNull AuthenticationResult unlockWeakTokenBasedProtector(
+ IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) {
+ return unlockTokenBasedProtectorInternal(gatekeeper, protectorId,
+ PROTECTOR_TYPE_WEAK_TOKEN_BASED, token, userId);
}
- private @NonNull AuthenticationResult unwrapTokenBasedSyntheticPasswordInternal(
- IGateKeeperService gatekeeper, long handle, byte type, byte[] token, int userId) {
+ private @NonNull AuthenticationResult unlockTokenBasedProtectorInternal(
+ IGateKeeperService gatekeeper, long protectorId, byte expectedProtectorType,
+ byte[] token, int userId) {
AuthenticationResult result = new AuthenticationResult();
- byte[] secdiscardable = loadSecdiscardable(handle, userId);
- int slotId = loadWeaverSlot(handle, userId);
+ byte[] secdiscardable = loadSecdiscardable(protectorId, userId);
+ int slotId = loadWeaverSlot(protectorId, userId);
if (slotId != INVALID_WEAVER_SLOT) {
if (!isWeaverAvailable()) {
- Slog.e(TAG, "No weaver service to unwrap token based SP");
+ Slog.e(TAG, "Protector uses Weaver, but Weaver is unavailable");
result.gkResponse = VerifyCredentialResponse.ERROR;
return result;
}
VerifyCredentialResponse response = weaverVerify(slotId, null);
if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK ||
response.getGatekeeperHAT() == null) {
- Slog.e(TAG, "Failed to retrieve weaver secret when unwrapping token");
+ Slog.e(TAG,
+ "Failed to retrieve Weaver secret when unlocking token-based protector");
result.gkResponse = VerifyCredentialResponse.ERROR;
return result;
}
secdiscardable = SyntheticPasswordCrypto.decrypt(response.getGatekeeperHAT(),
PERSONALIZATION_WEAVER_TOKEN, secdiscardable);
}
- byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable);
- result.authToken = unwrapSyntheticPasswordBlob(handle, type, applicationId, 0L, userId);
- if (result.authToken != null) {
- result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+ byte[] protectorSecret = transformUnderSecdiscardable(token, secdiscardable);
+ result.syntheticPassword = unwrapSyntheticPasswordBlob(protectorId, expectedProtectorType,
+ protectorSecret, 0L, userId);
+ if (result.syntheticPassword != null) {
+ result.gkResponse = verifyChallenge(gatekeeper, result.syntheticPassword, 0L, userId);
if (result.gkResponse == null) {
// The user currently has no password. return OK with null payload so null
// is propagated to unlockUser()
@@ -1180,9 +1193,9 @@ public class SyntheticPasswordManager {
return result;
}
- private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
- byte[] applicationId, long sid, int userId) {
- byte[] data = loadState(SP_BLOB_NAME, handle, userId);
+ private SyntheticPassword unwrapSyntheticPasswordBlob(long protectorId,
+ byte expectedProtectorType, byte[] protectorSecret, long sid, int userId) {
+ byte[] data = loadState(SP_BLOB_NAME, protectorId, userId);
if (data == null) {
return null;
}
@@ -1190,36 +1203,38 @@ public class SyntheticPasswordManager {
if (blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V3
&& blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V2
&& blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V1) {
- throw new IllegalArgumentException("Unknown blob version");
+ throw new IllegalArgumentException("Unknown blob version: " + blob.mVersion);
}
- if (blob.mType != type) {
- throw new IllegalArgumentException("Invalid blob type");
+ if (blob.mProtectorType != expectedProtectorType) {
+ throw new IllegalArgumentException("Invalid protector type: " + blob.mProtectorType);
}
- final byte[] secret;
+ final byte[] spSecret;
if (blob.mVersion == SYNTHETIC_PASSWORD_VERSION_V1) {
- secret = SyntheticPasswordCrypto.decryptBlobV1(getKeyName(handle), blob.mContent,
- applicationId);
+ spSecret = SyntheticPasswordCrypto.decryptBlobV1(getKeyName(protectorId), blob.mContent,
+ protectorSecret);
} else {
- secret = decryptSPBlob(getKeyName(handle), blob.mContent, applicationId);
+ spSecret = decryptSPBlob(getKeyName(protectorId), blob.mContent, protectorSecret);
}
- if (secret == null) {
+ if (spSecret == null) {
Slog.e(TAG, "Fail to decrypt SP for user " + userId);
return null;
}
- AuthenticationToken result = new AuthenticationToken(blob.mVersion);
- if (type == SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED
- || type == SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED) {
+ SyntheticPassword result = new SyntheticPassword(blob.mVersion);
+ if (blob.mProtectorType == PROTECTOR_TYPE_STRONG_TOKEN_BASED
+ || blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) {
if (!loadEscrowData(result, userId)) {
Slog.e(TAG, "User is not escrowable: " + userId);
return null;
}
- result.recreateFromEscrow(secret);
+ result.recreateFromEscrow(spSecret);
} else {
- result.recreateDirectly(secret);
+ result.recreateDirectly(spSecret);
}
if (blob.mVersion == SYNTHETIC_PASSWORD_VERSION_V1) {
- Slog.i(TAG, "Upgrade v1 SP blob for user " + userId + ", type = " + type);
- createSyntheticPasswordBlob(handle, type, result, applicationId, sid, userId);
+ Slog.i(TAG, "Upgrading v1 SP blob for user " + userId + ", protectorType = "
+ + blob.mProtectorType);
+ createSyntheticPasswordBlob(protectorId, blob.mProtectorType, result, protectorSecret,
+ sid, userId);
}
return result;
}
@@ -1228,13 +1243,12 @@ public class SyntheticPasswordManager {
* performs GK verifyChallenge and returns auth token, re-enrolling SP password handle
* if required.
*
- * Normally performing verifyChallenge with an AuthenticationToken should always return
- * RESPONSE_OK, since user authentication failures are detected earlier when trying to
- * decrypt SP.
+ * Normally performing verifyChallenge with an SP should always return RESPONSE_OK, since user
+ * authentication failures are detected earlier when trying to decrypt the SP.
*/
public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper,
- @NonNull AuthenticationToken auth, long challenge, int userId) {
- return verifyChallengeInternal(gatekeeper, auth.deriveGkPassword(), challenge, userId);
+ @NonNull SyntheticPassword sp, long challenge, int userId) {
+ return verifyChallengeInternal(gatekeeper, sp.deriveGkPassword(), challenge, userId);
}
protected @Nullable VerifyCredentialResponse verifyChallengeInternal(
@@ -1285,46 +1299,49 @@ public class SyntheticPasswordManager {
}
}
- public boolean existsHandle(long handle, int userId) {
- return hasState(SP_BLOB_NAME, handle, userId);
+ public boolean protectorExists(long protectorId, int userId) {
+ return hasState(SP_BLOB_NAME, protectorId, userId);
}
- /** Destroy the escrow token with the given handle for the given user. */
- public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
- SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME, handle,
- userId));
- destroySyntheticPassword(handle, userId);
- destroyState(SECDISCARDABLE_NAME, handle, userId);
- if (blob.mType == SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED) {
- notifyWeakEscrowTokenRemovedListeners(handle, userId);
+ /** Destroy a token-based SP protector. */
+ public void destroyTokenBasedProtector(long protectorId, int userId) {
+ SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME,
+ protectorId, userId));
+ destroyProtectorCommon(protectorId, userId);
+ destroyState(SECDISCARDABLE_NAME, protectorId, userId);
+ if (blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) {
+ notifyWeakEscrowTokenRemovedListeners(protectorId, userId);
}
}
- /** Destroy all weak escrow tokens for the given user. */
- public void destroyAllWeakTokenBasedSyntheticPasswords(int userId) {
- List<Long> handles = mStorage.listSyntheticPasswordHandlesForUser(SECDISCARDABLE_NAME,
- userId);
- for (long handle: handles) {
+ /** Destroy all weak token-based SP protectors for the given user. */
+ public void destroyAllWeakTokenBasedProtectors(int userId) {
+ List<Long> protectorIds =
+ mStorage.listSyntheticPasswordProtectorsForUser(SECDISCARDABLE_NAME, userId);
+ for (long protectorId : protectorIds) {
SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME,
- handle, userId));
- if (blob.mType == SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED) {
- destroyTokenBasedSyntheticPassword(handle, userId);
+ protectorId, userId));
+ if (blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) {
+ destroyTokenBasedProtector(protectorId, userId);
}
}
}
- public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
- destroySyntheticPassword(handle, userId);
- destroyState(SECDISCARDABLE_NAME, handle, userId);
- destroyState(PASSWORD_DATA_NAME, handle, userId);
- destroyState(PASSWORD_METRICS_NAME, handle, userId);
+ /**
+ * Destroy an LSKF-based SP protector. This is used when the user's LSKF is changed.
+ */
+ public void destroyLskfBasedProtector(long protectorId, int userId) {
+ destroyProtectorCommon(protectorId, userId);
+ destroyState(SECDISCARDABLE_NAME, protectorId, userId);
+ destroyState(PASSWORD_DATA_NAME, protectorId, userId);
+ destroyState(PASSWORD_METRICS_NAME, protectorId, userId);
}
- private void destroySyntheticPassword(long handle, int userId) {
- destroyState(SP_BLOB_NAME, handle, userId);
- destroySPBlobKey(getKeyName(handle));
- if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
- destroyWeaverSlot(handle, userId);
+ private void destroyProtectorCommon(long protectorId, int userId) {
+ destroyState(SP_BLOB_NAME, protectorId, userId);
+ destroySPBlobKey(getKeyName(protectorId));
+ if (hasState(WEAVER_SLOT_NAME, protectorId, userId)) {
+ destroyWeaverSlot(protectorId, userId);
}
}
@@ -1346,92 +1363,91 @@ public class SyntheticPasswordManager {
return result;
}
- private byte[] createSecdiscardable(long handle, int userId) {
+ private byte[] createSecdiscardable(long protectorId, int userId) {
byte[] data = secureRandom(SECDISCARDABLE_LENGTH);
- saveSecdiscardable(handle, data, userId);
+ saveSecdiscardable(protectorId, data, userId);
return data;
}
- private void saveSecdiscardable(long handle, byte[] secdiscardable, int userId) {
- saveState(SECDISCARDABLE_NAME, secdiscardable, handle, userId);
+ private void saveSecdiscardable(long protectorId, byte[] secdiscardable, int userId) {
+ saveState(SECDISCARDABLE_NAME, secdiscardable, protectorId, userId);
}
- private byte[] loadSecdiscardable(long handle, int userId) {
- return loadState(SECDISCARDABLE_NAME, handle, userId);
+ private byte[] loadSecdiscardable(long protectorId, int userId) {
+ return loadState(SECDISCARDABLE_NAME, protectorId, userId);
}
- private byte getTokenBasedBlobType(@TokenType int type) {
+ private byte getTokenBasedProtectorType(@TokenType int type) {
switch (type) {
case TOKEN_TYPE_WEAK:
- return SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED;
+ return PROTECTOR_TYPE_WEAK_TOKEN_BASED;
case TOKEN_TYPE_STRONG:
default:
- return SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED;
+ return PROTECTOR_TYPE_STRONG_TOKEN_BASED;
}
}
/**
- * Retrieves the saved password metrics associated with a SP handle. Only meaningful to be
- * called on the handle of a password-based synthetic password. A valid AuthenticationToken for
- * the target user is required in order to be able to decrypt the encrypted password metrics on
- * disk.
+ * Retrieves a user's saved password metrics from their LSKF-based SP protector. The
+ * SyntheticPassword itself is needed to decrypt the file containing the password metrics.
*/
- public @Nullable PasswordMetrics getPasswordMetrics(AuthenticationToken authToken, long handle,
+ public @Nullable PasswordMetrics getPasswordMetrics(SyntheticPassword sp, long protectorId,
int userId) {
- final byte[] encrypted = loadState(PASSWORD_METRICS_NAME, handle, userId);
+ final byte[] encrypted = loadState(PASSWORD_METRICS_NAME, protectorId, userId);
if (encrypted == null) return null;
- final byte[] decrypted = SyntheticPasswordCrypto.decrypt(authToken.deriveMetricsKey(),
+ final byte[] decrypted = SyntheticPasswordCrypto.decrypt(sp.deriveMetricsKey(),
/* personalization= */ new byte[0], encrypted);
if (decrypted == null) return null;
return VersionedPasswordMetrics.deserialize(decrypted).getMetrics();
}
- private void savePasswordMetrics(LockscreenCredential credential, AuthenticationToken authToken,
- long handle, int userId) {
- final byte[] encrypted = SyntheticPasswordCrypto.encrypt(authToken.deriveMetricsKey(),
+ private void savePasswordMetrics(LockscreenCredential credential, SyntheticPassword sp,
+ long protectorId, int userId) {
+ final byte[] encrypted = SyntheticPasswordCrypto.encrypt(sp.deriveMetricsKey(),
/* personalization= */ new byte[0],
new VersionedPasswordMetrics(credential).serialize());
- saveState(PASSWORD_METRICS_NAME, encrypted, handle, userId);
+ saveState(PASSWORD_METRICS_NAME, encrypted, protectorId, userId);
}
- private boolean hasPasswordMetrics(long handle, int userId) {
- return hasState(PASSWORD_METRICS_NAME, handle, userId);
+ private boolean hasPasswordMetrics(long protectorId, int userId) {
+ return hasState(PASSWORD_METRICS_NAME, protectorId, userId);
}
- private boolean hasState(String stateName, long handle, int userId) {
- return !ArrayUtils.isEmpty(loadState(stateName, handle, userId));
+ private boolean hasState(String stateName, long protectorId, int userId) {
+ return !ArrayUtils.isEmpty(loadState(stateName, protectorId, userId));
}
- private byte[] loadState(String stateName, long handle, int userId) {
- return mStorage.readSyntheticPasswordState(userId, handle, stateName);
+ private byte[] loadState(String stateName, long protectorId, int userId) {
+ return mStorage.readSyntheticPasswordState(userId, protectorId, stateName);
}
- private void saveState(String stateName, byte[] data, long handle, int userId) {
- mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
+ private void saveState(String stateName, byte[] data, long protectorId, int userId) {
+ mStorage.writeSyntheticPasswordState(userId, protectorId, stateName, data);
}
- private void destroyState(String stateName, long handle, int userId) {
- mStorage.deleteSyntheticPasswordState(userId, handle, stateName);
+ private void destroyState(String stateName, long protectorId, int userId) {
+ mStorage.deleteSyntheticPasswordState(userId, protectorId, stateName);
}
- protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
- return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, applicationId);
+ protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] protectorSecret) {
+ return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, protectorSecret);
}
- protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
- return SyntheticPasswordCrypto.createBlob(blobKeyName, data, applicationId, sid);
+ protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] protectorSecret,
+ long sid) {
+ return SyntheticPasswordCrypto.createBlob(blobKeyName, data, protectorSecret, sid);
}
protected void destroySPBlobKey(String keyAlias) {
SyntheticPasswordCrypto.destroyBlobKey(keyAlias);
}
- public static long generateHandle() {
+ public static long generateProtectorId() {
SecureRandom rng = new SecureRandom();
long result;
do {
result = rng.nextLong();
- } while (result == DEFAULT_HANDLE);
+ } while (result == NULL_PROTECTOR_ID);
return result;
}
@@ -1448,8 +1464,8 @@ public class SyntheticPasswordManager {
}
}
- private String getKeyName(long handle) {
- return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
+ private String getKeyName(long protectorId) {
+ return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, protectorId);
}
private byte[] computePasswordToken(LockscreenCredential credential, PasswordData data) {
@@ -1506,11 +1522,11 @@ public class SyntheticPasswordManager {
*/
public boolean migrateKeyNamespace() {
boolean success = true;
- final Map<Integer, List<Long>> allHandles =
- mStorage.listSyntheticPasswordHandlesForAllUsers(SP_BLOB_NAME);
- for (List<Long> userHandles : allHandles.values()) {
- for (long handle : userHandles) {
- success &= SyntheticPasswordCrypto.migrateLockSettingsKey(getKeyName(handle));
+ final Map<Integer, List<Long>> allProtectors =
+ mStorage.listSyntheticPasswordProtectorsForAllUsers(SP_BLOB_NAME);
+ for (List<Long> userProtectors : allProtectors.values()) {
+ for (long protectorId : userProtectors) {
+ success &= SyntheticPasswordCrypto.migrateLockSettingsKey(getKeyName(protectorId));
}
}
return success;
@@ -1528,13 +1544,13 @@ public class SyntheticPasswordManager {
return mListeners.unregister(listener);
}
- private void notifyWeakEscrowTokenRemovedListeners(long handle, int userId) {
+ private void notifyWeakEscrowTokenRemovedListeners(long protectorId, int userId) {
int i = mListeners.beginBroadcast();
try {
while (i > 0) {
i--;
try {
- mListeners.getBroadcastItem(i).onWeakEscrowTokenRemoved(handle, userId);
+ mListeners.getBroadcastItem(i).onWeakEscrowTokenRemoved(protectorId, userId);
} catch (RemoteException e) {
Slog.e(TAG, "Exception while notifying WeakEscrowTokenRemovedListener.",
e);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index c9631549cd76..4a0a07b9783c 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -38,6 +38,7 @@ import android.app.ActivityManager;
import android.app.ActivityManager.ProcessCapability;
import android.net.NetworkPolicyManager;
import android.os.UserHandle;
+import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
@@ -79,6 +80,8 @@ public class NetworkPolicyLogger {
private static final int EVENT_APP_IDLE_WL_CHANGED = 14;
private static final int EVENT_METERED_ALLOWLIST_CHANGED = 15;
private static final int EVENT_METERED_DENYLIST_CHANGED = 16;
+ private static final int EVENT_ROAMING_CHANGED = 17;
+ private static final int EVENT_INTERFACES_CHANGED = 18;
private final LogBuffer mNetworkBlockedBuffer = new LogBuffer(MAX_NETWORK_BLOCKED_LOG_SIZE);
private final LogBuffer mUidStateChangeBuffer = new LogBuffer(MAX_LOG_SIZE);
@@ -265,6 +268,24 @@ public class NetworkPolicyLogger {
}
}
+ void roamingChanged(int netId, boolean newRoaming) {
+ synchronized (mLock) {
+ if (LOGD || mDebugUid != INVALID_UID) {
+ Slog.d(TAG, getRoamingChangedLog(netId, newRoaming));
+ }
+ mEventsBuffer.roamingChanged(netId, newRoaming);
+ }
+ }
+
+ void interfacesChanged(int netId, ArraySet<String> newIfaces) {
+ synchronized (mLock) {
+ if (LOGD || mDebugUid != INVALID_UID) {
+ Slog.d(TAG, getInterfacesChangedLog(netId, newIfaces.toString()));
+ }
+ mEventsBuffer.interfacesChanged(netId, newIfaces.toString());
+ }
+ }
+
void setDebugUid(int uid) {
mDebugUid = uid;
}
@@ -348,6 +369,14 @@ public class NetworkPolicyLogger {
return "metered-denylist for " + uid + " changed to " + added;
}
+ private static String getRoamingChangedLog(int netId, boolean newRoaming) {
+ return "Roaming of netId=" + netId + " changed to " + newRoaming;
+ }
+
+ private static String getInterfacesChangedLog(int netId, String newIfaces) {
+ return "Interfaces of netId=" + netId + " changed to " + newIfaces;
+ }
+
private static String getFirewallChainName(int chain) {
switch (chain) {
case FIREWALL_CHAIN_DOZABLE:
@@ -570,6 +599,28 @@ public class NetworkPolicyLogger {
data.timeStamp = System.currentTimeMillis();
}
+ public void roamingChanged(int netId, boolean newRoaming) {
+ final Data data = getNextSlot();
+ if (data == null) return;
+
+ data.reset();
+ data.type = EVENT_ROAMING_CHANGED;
+ data.ifield1 = netId;
+ data.bfield1 = newRoaming;
+ data.timeStamp = System.currentTimeMillis();
+ }
+
+ public void interfacesChanged(int netId, String newIfaces) {
+ final Data data = getNextSlot();
+ if (data == null) return;
+
+ data.reset();
+ data.type = EVENT_INTERFACES_CHANGED;
+ data.ifield1 = netId;
+ data.sfield1 = newIfaces;
+ data.timeStamp = System.currentTimeMillis();
+ }
+
public void reverseDump(IndentingPrintWriter pw) {
final Data[] allData = toArray();
for (int i = allData.length - 1; i >= 0; --i) {
@@ -621,6 +672,10 @@ public class NetworkPolicyLogger {
return getMeteredAllowlistChangedLog(data.ifield1, data.bfield1);
case EVENT_METERED_DENYLIST_CHANGED:
return getMeteredDenylistChangedLog(data.ifield1, data.bfield1);
+ case EVENT_ROAMING_CHANGED:
+ return getRoamingChangedLog(data.ifield1, data.bfield1);
+ case EVENT_INTERFACES_CHANGED:
+ return getInterfacesChangedLog(data.ifield1, data.sfield1);
default:
return String.valueOf(data.type);
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 99a488c27dbb..de83f5ae7545 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1367,8 +1367,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final boolean roamingChanged = updateCapabilityChange(
mNetworkRoaming, newRoaming, network);
- if (meteredChanged || roamingChanged) {
+ final boolean shouldUpdateNetworkRules = meteredChanged || roamingChanged;
+
+ if (meteredChanged) {
mLogger.meterednessChanged(network.getNetId(), newMetered);
+ }
+
+ if (roamingChanged) {
+ mLogger.roamingChanged(network.getNetId(), newRoaming);
+ }
+
+ if (shouldUpdateNetworkRules) {
updateNetworkRulesNL();
}
}
@@ -1381,6 +1390,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final boolean ifacesChanged = updateNetworkToIfacesNL(network.getNetId(),
newIfaces);
if (ifacesChanged) {
+ mLogger.interfacesChanged(network.getNetId(), newIfaces);
updateNetworkRulesNL();
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index e09f7b09b4d1..40c0a535534b 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -16,15 +16,8 @@
package com.android.server.notification;
-import android.app.AlarmManager;
import android.app.NotificationHistory;
import android.app.NotificationHistory.HistoricalNotification;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
import android.os.Handler;
import android.util.AtomicFile;
import android.util.Slog;
@@ -61,18 +54,9 @@ public class NotificationHistoryDatabase {
private static final String TAG = "NotiHistoryDatabase";
private static final boolean DEBUG = NotificationManagerService.DBG;
private static final int HISTORY_RETENTION_DAYS = 1;
- private static final int HISTORY_RETENTION_MS = 24 * 60 * 60 * 1000;
private static final long WRITE_BUFFER_INTERVAL_MS = 1000 * 60 * 20;
private static final long INVALID_FILE_TIME_MS = -1;
- private static final String ACTION_HISTORY_DELETION =
- NotificationHistoryDatabase.class.getSimpleName() + ".CLEANUP";
- private static final int REQUEST_CODE_DELETION = 1;
- private static final String SCHEME_DELETION = "delete";
- private static final String EXTRA_KEY = "key";
-
- private final Context mContext;
- private final AlarmManager mAlarmManager;
private final Object mLock = new Object();
private final Handler mFileWriteHandler;
@VisibleForTesting
@@ -88,9 +72,7 @@ public class NotificationHistoryDatabase {
@VisibleForTesting
NotificationHistory mBuffer;
- public NotificationHistoryDatabase(Context context, Handler fileWriteHandler, File dir) {
- mContext = context;
- mAlarmManager = context.getSystemService(AlarmManager.class);
+ public NotificationHistoryDatabase(Handler fileWriteHandler, File dir) {
mCurrentVersion = DEFAULT_CURRENT_VERSION;
mFileWriteHandler = fileWriteHandler;
mVersionFile = new File(dir, "version");
@@ -98,11 +80,6 @@ public class NotificationHistoryDatabase {
mHistoryFiles = new ArrayList<>();
mBuffer = new NotificationHistory();
mWriteBufferRunnable = new WriteBufferRunnable();
-
- IntentFilter deletionFilter = new IntentFilter(ACTION_HISTORY_DELETION);
- deletionFilter.addDataScheme(SCHEME_DELETION);
- mContext.registerReceiver(mFileCleanupReceiver, deletionFilter,
- Context.RECEIVER_EXPORTED_UNAUDITED);
}
public void init() {
@@ -118,7 +95,7 @@ public class NotificationHistoryDatabase {
checkVersionAndBuildLocked();
indexFilesLocked();
- prune(HISTORY_RETENTION_DAYS, System.currentTimeMillis());
+ prune();
}
}
@@ -247,7 +224,14 @@ public class NotificationHistoryDatabase {
}
/**
- * Remove any files that are too old and schedule jobs to clean up the rest
+ * Remove any files that are too old.
+ */
+ void prune() {
+ prune(HISTORY_RETENTION_DAYS, System.currentTimeMillis());
+ }
+
+ /**
+ * Remove any files that are too old.
*/
void prune(final int retentionDays, final long currentTimeMillis) {
synchronized (mLock) {
@@ -266,10 +250,6 @@ public class NotificationHistoryDatabase {
if (creationTime <= retentionBoundary.getTimeInMillis()) {
deleteFile(currentOldestFile);
- } else {
- // all remaining files are newer than the cut off; schedule jobs to delete
- scheduleDeletion(
- currentOldestFile.getBaseFile(), creationTime, retentionDays);
}
}
}
@@ -307,26 +287,6 @@ public class NotificationHistoryDatabase {
removeFilePathFromHistory(file.getBaseFile().getAbsolutePath());
}
- private void scheduleDeletion(File file, long creationTime, int retentionDays) {
- final long deletionTime = creationTime + (retentionDays * HISTORY_RETENTION_MS);
- scheduleDeletion(file, deletionTime);
- }
-
- private void scheduleDeletion(File file, long deletionTime) {
- if (DEBUG) {
- Slog.d(TAG, "Scheduling deletion for " + file.getName() + " at " + deletionTime);
- }
- final PendingIntent pi = PendingIntent.getBroadcast(mContext,
- REQUEST_CODE_DELETION,
- new Intent(ACTION_HISTORY_DELETION)
- .setData(new Uri.Builder().scheme(SCHEME_DELETION)
- .appendPath(file.getAbsolutePath()).build())
- .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
- .putExtra(EXTRA_KEY, file.getAbsolutePath()),
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, deletionTime, pi);
- }
-
private void writeLocked(AtomicFile file, NotificationHistory notifications)
throws IOException {
FileOutputStream fos = file.startWrite();
@@ -356,12 +316,6 @@ public class NotificationHistoryDatabase {
}
}
- public void unregisterFileCleanupReceiver() {
- if(mContext != null) {
- mContext.unregisterReceiver(mFileCleanupReceiver);
- }
- }
-
private static long safeParseLong(String fileName) {
// AtomicFile will create copies of the numeric files with ".new" and ".bak"
// over the course of its processing. If these files still exist on boot we need to clean
@@ -373,40 +327,15 @@ public class NotificationHistoryDatabase {
}
}
- private final BroadcastReceiver mFileCleanupReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action == null) {
- return;
- }
- if (ACTION_HISTORY_DELETION.equals(action)) {
- try {
- synchronized (mLock) {
- final String filePath = intent.getStringExtra(EXTRA_KEY);
- AtomicFile fileToDelete = new AtomicFile(new File(filePath));
- if (DEBUG) {
- Slog.d(TAG, "Removed " + fileToDelete.getBaseFile().getName());
- }
- fileToDelete.delete();
- removeFilePathFromHistory(filePath);
- }
- } catch (Exception e) {
- Slog.e(TAG, "Failed to delete notification history file", e);
- }
- }
- }
- };
-
final class WriteBufferRunnable implements Runnable {
@Override
public void run() {
long time = System.currentTimeMillis();
- run(time, new AtomicFile(new File(mHistoryDir, String.valueOf(time))));
+ run(new AtomicFile(new File(mHistoryDir, String.valueOf(time))));
}
- void run(long time, AtomicFile file) {
+ void run(AtomicFile file) {
synchronized (mLock) {
if (DEBUG) Slog.d(TAG, "WriteBufferRunnable "
+ file.getBaseFile().getAbsolutePath());
@@ -414,8 +343,6 @@ public class NotificationHistoryDatabase {
writeLocked(file, mBuffer);
mHistoryFiles.add(0, file);
mBuffer = new NotificationHistory();
-
- scheduleDeletion(file.getBaseFile(), time, HISTORY_RETENTION_DAYS);
} catch (IOException e) {
Slog.e(TAG, "Failed to write buffer to disk. not flushing buffer", e);
}
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java
index d9e0d79883c5..0d975cc50d79 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java
@@ -35,6 +35,6 @@ public class NotificationHistoryDatabaseFactory {
if(sTestingNotificationHistoryDb != null) {
return sTestingNotificationHistoryDb;
}
- return new NotificationHistoryDatabase(context, handler, rootDir);
+ return new NotificationHistoryDatabase(handler, rootDir);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryJobService.java b/services/core/java/com/android/server/notification/NotificationHistoryJobService.java
new file mode 100644
index 000000000000..3776ad7a0799
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NotificationHistoryJobService.java
@@ -0,0 +1,81 @@
+/*
+ * 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.notification;
+
+import static android.app.job.JobScheduler.RESULT_SUCCESS;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.CancellationSignal;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This service runs every twenty minutes to ensure the retention policy for notification history
+ * data.
+ */
+public class NotificationHistoryJobService extends JobService {
+ private final static String TAG = "NotificationHistoryJob";
+ private static final long JOB_RUN_INTERVAL = TimeUnit.MINUTES.toMillis(20);
+
+ static final int BASE_JOB_ID = 237039804;
+
+ static void scheduleJob(Context context) {
+ JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+ if (jobScheduler.getPendingJob(BASE_JOB_ID) == null) {
+ ComponentName component =
+ new ComponentName(context, NotificationHistoryJobService.class);
+ JobInfo newJob = new JobInfo.Builder(BASE_JOB_ID, component)
+ .setRequiresDeviceIdle(false)
+ .setPeriodic(JOB_RUN_INTERVAL)
+ .build();
+ if (jobScheduler.schedule(newJob) != RESULT_SUCCESS) {
+ Slog.w(TAG, "Failed to schedule history cleanup job");
+ }
+ }
+ }
+
+ private CancellationSignal mSignal;
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ mSignal = new CancellationSignal();
+ new Thread(() -> {
+ NotificationManagerInternal nmInternal =
+ LocalServices.getService(NotificationManagerInternal.class);
+ nmInternal.cleanupHistoryFiles();
+ jobFinished(params, mSignal.isCanceled());
+ }).start();
+ return true;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ if (mSignal != null) {
+ mSignal.cancel();
+ }
+ return false;
+ }
+}
+
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryManager.java b/services/core/java/com/android/server/notification/NotificationHistoryManager.java
index 0aacd130c837..6a46048e80e1 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryManager.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryManager.java
@@ -84,6 +84,11 @@ public class NotificationHistoryManager {
}
void onBootPhaseAppsCanStart() {
+ try {
+ NotificationHistoryJobService.scheduleJob(mContext);
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failed to schedule cleanup job", e);
+ }
mSettingsObserver.observe();
}
@@ -151,6 +156,24 @@ public class NotificationHistoryManager {
}
}
+ public void cleanupHistoryFiles() {
+ synchronized (mLock) {
+ int n = mUserUnlockedStates.size();
+ for (int i = 0; i < n; i++) {
+ // cleanup old files for currently unlocked users. User are additionally cleaned
+ // on unlock in NotificationHistoryDatabase.init().
+ if (mUserUnlockedStates.valueAt(i)) {
+ final NotificationHistoryDatabase userHistory =
+ mUserState.get(mUserUnlockedStates.keyAt(i));
+ if (userHistory == null) {
+ continue;
+ }
+ userHistory.prune();
+ }
+ }
+ }
+ }
+
public void deleteNotificationHistoryItem(String pkg, int uid, long postedTime) {
synchronized (mLock) {
int userId = UserHandle.getUserId(uid);
@@ -288,7 +311,6 @@ public class NotificationHistoryManager {
private void disableHistory(NotificationHistoryDatabase userHistory, @UserIdInt int userId) {
userHistory.disableHistory();
- userHistory.unregisterFileCleanupReceiver();
mUserPendingHistoryDisables.put(userId, false);
mHistoryEnabled.put(userId, false);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
index 8a627367c1dc..bc3885605a6c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
@@ -45,4 +45,6 @@ public interface NotificationManagerInternal {
/** Send a notification to the user prompting them to review their notification permissions. */
void sendReviewPermissionsNotification();
+
+ void cleanupHistoryFiles();
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 172cf2965070..2070c2b31236 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2734,7 +2734,7 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public void onUserUnlocking(@NonNull TargetUser user) {
+ public void onUserUnlocked(@NonNull TargetUser user) {
mHandler.post(() -> {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryUnlockUser");
try {
@@ -6344,6 +6344,12 @@ public class NotificationManagerService extends SystemService {
Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
NotificationManagerService.REVIEW_NOTIF_STATE_RESHOWN);
}
+
+ @Override
+ public void cleanupHistoryFiles() {
+ checkCallerIsSystem();
+ mHistoryManager.cleanupHistoryFiles();
+ }
};
int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) {
@@ -6757,9 +6763,8 @@ public class NotificationManagerService extends SystemService {
protected void doChannelWarningToast(int forUid, CharSequence toastText) {
Binder.withCleanCallingIdentity(() -> {
- final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0;
final boolean warningEnabled = Settings.Global.getInt(getContext().getContentResolver(),
- Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, defaultWarningEnabled) != 0;
+ Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, 0) != 0;
if (warningEnabled) {
Toast toast = Toast.makeText(getContext(), mHandler.getLooper(), toastText,
Toast.LENGTH_SHORT);
@@ -9918,10 +9923,16 @@ public class NotificationManagerService extends SystemService {
* given NAS is bound in.
*/
private boolean isInteractionVisibleToListener(ManagedServiceInfo info, int userId) {
- boolean isAssistantService = mAssistants.isServiceTokenValidLocked(info.service);
+ boolean isAssistantService = isServiceTokenValid(info.service);
return !isAssistantService || info.isSameUser(userId);
}
+ private boolean isServiceTokenValid(IInterface service) {
+ synchronized (mNotificationLock) {
+ return mAssistants.isServiceTokenValidLocked(service);
+ }
+ }
+
private boolean isPackageSuspendedForUser(String pkg, int uid) {
final long identity = Binder.clearCallingIdentity();
int userId = UserHandle.getUserId(uid);
@@ -11183,7 +11194,7 @@ public class NotificationManagerService extends SystemService {
BackgroundThread.getHandler().post(() -> {
if (info.isSystem
|| hasCompanionDevice(info)
- || mAssistants.isServiceTokenValidLocked(info.service)) {
+ || isServiceTokenValid(info.service)) {
notifyNotificationChannelChanged(
info, pkg, user, channel, modificationType);
}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 066692d374d0..477b8da61e0f 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -86,7 +86,6 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -1328,17 +1327,16 @@ public class PreferencesHelper implements RankingConfig {
return null;
}
NotificationChannelGroup group = r.groups.get(groupId).clone();
- ArrayList channels = new ArrayList();
+ group.setChannels(new ArrayList<>());
int N = r.channels.size();
for (int i = 0; i < N; i++) {
final NotificationChannel nc = r.channels.valueAt(i);
if (includeDeleted || !nc.isDeleted()) {
if (groupId.equals(nc.getGroup())) {
- channels.add(nc);
+ group.addChannel(nc);
}
}
}
- group.setChannels(channels);
return group;
}
}
@@ -1359,48 +1357,44 @@ public class PreferencesHelper implements RankingConfig {
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty) {
Objects.requireNonNull(pkg);
- List<NotificationChannelGroup> groups = new ArrayList<>();
+ Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
synchronized (mPackagePreferences) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return ParceledListSlice.emptyList();
}
- Map<String, ArrayList<NotificationChannel>> groupedChannels = new HashMap();
+ NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null);
int N = r.channels.size();
for (int i = 0; i < N; i++) {
final NotificationChannel nc = r.channels.valueAt(i);
if (includeDeleted || !nc.isDeleted()) {
if (nc.getGroup() != null) {
if (r.groups.get(nc.getGroup()) != null) {
- ArrayList<NotificationChannel> channels = groupedChannels.getOrDefault(
- nc.getGroup(), new ArrayList<>());
- channels.add(nc);
- groupedChannels.put(nc.getGroup(), channels);
+ NotificationChannelGroup ncg = groups.get(nc.getGroup());
+ if (ncg == null) {
+ ncg = r.groups.get(nc.getGroup()).clone();
+ ncg.setChannels(new ArrayList<>());
+ groups.put(nc.getGroup(), ncg);
+
+ }
+ ncg.addChannel(nc);
}
} else {
- ArrayList<NotificationChannel> channels = groupedChannels.getOrDefault(
- null, new ArrayList<>());
- channels.add(nc);
- groupedChannels.put(null, channels);
+ nonGrouped.addChannel(nc);
}
}
}
- for (NotificationChannelGroup group : r.groups.values()) {
- ArrayList<NotificationChannel> channels =
- groupedChannels.getOrDefault(group.getId(), new ArrayList<>());
- if (includeEmpty || !channels.isEmpty()) {
- NotificationChannelGroup clone = group.clone();
- clone.setChannels(channels);
- groups.add(clone);
- }
+ if (includeNonGrouped && nonGrouped.getChannels().size() > 0) {
+ groups.put(null, nonGrouped);
}
-
- if (includeNonGrouped && groupedChannels.containsKey(null)) {
- NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null);
- nonGrouped.setChannels(groupedChannels.get(null));
- groups.add(nonGrouped);
+ if (includeEmpty) {
+ for (NotificationChannelGroup group : r.groups.values()) {
+ if (!groups.containsKey(group.getId())) {
+ groups.put(group.getId(), group);
+ }
+ }
}
- return new ParceledListSlice<>(groups);
+ return new ParceledListSlice<>(new ArrayList<>(groups.values()));
}
}
diff --git a/services/core/java/com/android/server/pm/ApexPackageInfo.java b/services/core/java/com/android/server/pm/ApexPackageInfo.java
index f959a52f0374..73cb0ada6b87 100644
--- a/services/core/java/com/android/server/pm/ApexPackageInfo.java
+++ b/services/core/java/com/android/server/pm/ApexPackageInfo.java
@@ -22,10 +22,9 @@ import static com.android.server.pm.ApexManager.MATCH_FACTORY_PACKAGE;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.apex.ApexInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.ArrayMap;
+import android.util.Pair;
import android.util.PrintWriterPrinter;
import com.android.internal.annotations.GuardedBy;
@@ -33,8 +32,9 @@ import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.parsing.pkg.ParsedPackage;
-import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
+import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import java.io.File;
@@ -59,16 +59,17 @@ class ApexPackageInfo {
private final Object mLock = new Object();
@GuardedBy("mLock")
- private List<PackageInfo> mAllPackagesCache;
+ private List<Pair<ApexInfo, AndroidPackage>> mAllPackagesCache;
- /**
- * Whether an APEX package is active or not.
- *
- * @param packageInfo the package to check
- * @return {@code true} if this package is active, {@code false} otherwise.
- */
- private static boolean isActive(PackageInfo packageInfo) {
- return packageInfo.isActiveApex;
+ @Nullable
+ private final PackageManagerService mPackageManager;
+
+ ApexPackageInfo() {
+ mPackageManager = null;
+ }
+
+ ApexPackageInfo(@NonNull PackageManagerService pms) {
+ mPackageManager = pms;
}
/**
@@ -105,20 +106,23 @@ class ApexPackageInfo {
* is not found.
*/
@Nullable
- PackageInfo getPackageInfo(String packageName, @ApexManager.PackageInfoFlags int flags) {
+ Pair<ApexInfo, AndroidPackage> getPackageInfo(String packageName,
+ @ApexManager.PackageInfoFlags int flags) {
synchronized (mLock) {
Preconditions.checkState(mAllPackagesCache != null,
"APEX packages have not been scanned");
boolean matchActive = (flags & MATCH_ACTIVE_PACKAGE) != 0;
boolean matchFactory = (flags & MATCH_FACTORY_PACKAGE) != 0;
for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
- final PackageInfo packageInfo = mAllPackagesCache.get(i);
- if (!packageInfo.packageName.equals(packageName)) {
+ final Pair<ApexInfo, AndroidPackage> pair = mAllPackagesCache.get(i);
+ var apexInfo = pair.first;
+ var pkg = pair.second;
+ if (!pkg.getPackageName().equals(packageName)) {
continue;
}
- if ((matchActive && isActive(packageInfo))
- || (matchFactory && isFactory(packageInfo))) {
- return packageInfo;
+ if ((matchActive && apexInfo.isActive)
+ || (matchFactory && apexInfo.isFactory)) {
+ return pair;
}
}
return null;
@@ -128,18 +132,18 @@ class ApexPackageInfo {
/**
* Retrieves information about all active APEX packages.
*
- * @return a List of PackageInfo object, each one containing information about a different
- * active package.
+ * @return list containing information about different active packages.
*/
- List<PackageInfo> getActivePackages() {
+ @NonNull
+ List<Pair<ApexInfo, AndroidPackage>> getActivePackages() {
synchronized (mLock) {
Preconditions.checkState(mAllPackagesCache != null,
"APEX packages have not been scanned");
- final List<PackageInfo> activePackages = new ArrayList<>();
+ final List<Pair<ApexInfo, AndroidPackage>> activePackages = new ArrayList<>();
for (int i = 0; i < mAllPackagesCache.size(); i++) {
- final PackageInfo packageInfo = mAllPackagesCache.get(i);
- if (isActive(packageInfo)) {
- activePackages.add(packageInfo);
+ final var pair = mAllPackagesCache.get(i);
+ if (pair.first.isActive) {
+ activePackages.add(pair);
}
}
return activePackages;
@@ -147,20 +151,20 @@ class ApexPackageInfo {
}
/**
- * Retrieves information about all active pre-installed APEX packages.
+ * Retrieves information about all pre-installed APEX packages.
*
- * @return a List of PackageInfo object, each one containing information about a different
- * active pre-installed package.
+ * @return list containing information about different pre-installed packages.
*/
- List<PackageInfo> getFactoryPackages() {
+ @NonNull
+ List<Pair<ApexInfo, AndroidPackage>> getFactoryPackages() {
synchronized (mLock) {
Preconditions.checkState(mAllPackagesCache != null,
"APEX packages have not been scanned");
- final List<PackageInfo> factoryPackages = new ArrayList<>();
+ final List<Pair<ApexInfo, AndroidPackage>> factoryPackages = new ArrayList<>();
for (int i = 0; i < mAllPackagesCache.size(); i++) {
- final PackageInfo packageInfo = mAllPackagesCache.get(i);
- if (isFactory(packageInfo)) {
- factoryPackages.add(packageInfo);
+ final var pair = mAllPackagesCache.get(i);
+ if (pair.first.isFactory) {
+ factoryPackages.add(pair);
}
}
return factoryPackages;
@@ -170,18 +174,18 @@ class ApexPackageInfo {
/**
* Retrieves information about all inactive APEX packages.
*
- * @return a List of PackageInfo object, each one containing information about a different
- * inactive package.
+ * @return list containing information about different inactive packages.
*/
- List<PackageInfo> getInactivePackages() {
+ @NonNull
+ List<Pair<ApexInfo, AndroidPackage>> getInactivePackages() {
synchronized (mLock) {
Preconditions.checkState(mAllPackagesCache != null,
"APEX packages have not been scanned");
- final List<PackageInfo> inactivePackages = new ArrayList<>();
+ final List<Pair<ApexInfo, AndroidPackage>> inactivePackages = new ArrayList<>();
for (int i = 0; i < mAllPackagesCache.size(); i++) {
- final PackageInfo packageInfo = mAllPackagesCache.get(i);
- if (!isActive(packageInfo)) {
- inactivePackages.add(packageInfo);
+ final var pair = mAllPackagesCache.get(i);
+ if (!pair.first.isActive) {
+ inactivePackages.add(pair);
}
}
return inactivePackages;
@@ -199,8 +203,8 @@ class ApexPackageInfo {
Preconditions.checkState(mAllPackagesCache != null,
"APEX packages have not been scanned");
for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
- final PackageInfo packageInfo = mAllPackagesCache.get(i);
- if (packageInfo.packageName.equals(packageName)) {
+ final var pair = mAllPackagesCache.get(i);
+ if (pair.second.getPackageName().equals(packageName)) {
return true;
}
}
@@ -222,21 +226,18 @@ class ApexPackageInfo {
}
void notifyPackageInstalled(ApexInfo apexInfo, AndroidPackage pkg) {
- final int flags = PackageManager.GET_META_DATA
- | PackageManager.GET_SIGNING_CERTIFICATES
- | PackageManager.GET_SIGNATURES;
- final PackageInfo newApexPkg = PackageInfoWithoutStateUtils.generate(
- pkg, apexInfo, flags);
- final String packageName = newApexPkg.packageName;
+ final String packageName = pkg.getPackageName();
synchronized (mLock) {
for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
- PackageInfo oldApexPkg = mAllPackagesCache.get(i);
- if (oldApexPkg.isActiveApex && oldApexPkg.packageName.equals(packageName)) {
- if (isFactory(oldApexPkg)) {
- oldApexPkg.isActiveApex = false;
- mAllPackagesCache.add(newApexPkg);
+ var pair = mAllPackagesCache.get(i);
+ var oldApexInfo = pair.first;
+ var oldApexPkg = pair.second;
+ if (oldApexInfo.isActive && oldApexPkg.getPackageName().equals(packageName)) {
+ if (oldApexInfo.isFactory) {
+ oldApexInfo.isActive = false;
+ mAllPackagesCache.add(Pair.create(apexInfo, pkg));
} else {
- mAllPackagesCache.set(i, newApexPkg);
+ mAllPackagesCache.set(i, Pair.create(apexInfo, pkg));
}
break;
}
@@ -245,16 +246,6 @@ class ApexPackageInfo {
}
/**
- * Whether the APEX package is pre-installed or not.
- *
- * @param packageInfo the package to check
- * @return {@code true} if this package is pre-installed, {@code false} otherwise.
- */
- private static boolean isFactory(@NonNull PackageInfo packageInfo) {
- return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0;
- }
-
- /**
* Dumps various state information to the provided {@link PrintWriter} object.
*
* @param pw the {@link PrintWriter} object to send information to.
@@ -288,33 +279,25 @@ class ApexPackageInfo {
HashSet<String> factoryPackagesSet = new HashSet<>();
for (ApexManager.ScanResult result : scanResults) {
ApexInfo ai = result.apexInfo;
-
- final PackageInfo packageInfo = PackageInfoWithoutStateUtils.generate(
- result.pkg, ai, flags);
- if (packageInfo == null) {
- throw new IllegalStateException("Unable to generate package info: "
- + ai.modulePath);
- }
- if (!packageInfo.packageName.equals(result.packageName)) {
+ String packageName = result.pkg.getPackageName();
+ if (!packageName.equals(result.packageName)) {
throw new IllegalStateException("Unmatched package name: "
- + result.packageName + " != " + packageInfo.packageName
+ + result.packageName + " != " + packageName
+ ", path=" + ai.modulePath);
}
- mAllPackagesCache.add(packageInfo);
+ mAllPackagesCache.add(Pair.create(ai, result.pkg));
if (ai.isActive) {
- if (!activePackagesSet.add(packageInfo.packageName)) {
+ if (!activePackagesSet.add(packageName)) {
throw new IllegalStateException(
- "Two active packages have the same name: "
- + packageInfo.packageName);
+ "Two active packages have the same name: " + packageName);
}
}
if (ai.isFactory) {
// Don't throw when the duplicating APEX is VNDK APEX
- if (!factoryPackagesSet.add(packageInfo.packageName)
+ if (!factoryPackagesSet.add(packageName)
&& !ai.moduleName.startsWith(VNDK_APEX_MODULE_NAME_PREFIX)) {
throw new IllegalStateException(
- "Two factory packages have the same name: "
- + packageInfo.packageName);
+ "Two factory packages have the same name: " + packageName);
}
}
}
@@ -348,6 +331,13 @@ class ApexPackageInfo {
if (throwable == null) {
// Calling hideAsFinal to assign derived fields for the app info flags.
parseResult.parsedPackage.hideAsFinal();
+
+ // TODO: When ENABLE_FEATURE_SCAN_APEX is finalized, remove this and the entire
+ // calling path code
+ ScanPackageUtils.applyPolicy(parseResult.parsedPackage,
+ PackageManagerService.SCAN_AS_SYSTEM,
+ mPackageManager == null ? null : mPackageManager.getPlatformPackage(),
+ false);
results.add(new ApexManager.ScanResult(
ai, parseResult.parsedPackage, parseResult.parsedPackage.getPackageName()));
} else if (throwable instanceof PackageManagerException) {
@@ -363,34 +353,69 @@ class ApexPackageInfo {
}
/**
+ * @see #dumpPackages(List, String, IndentingPrintWriter)
+ */
+ static void dumpPackageStates(List<PackageStateInternal> packageStates, boolean isActive,
+ @Nullable String packageName, IndentingPrintWriter ipw) {
+ ipw.println();
+ ipw.increaseIndent();
+ for (int i = 0, size = packageStates.size(); i < size; i++) {
+ final var packageState = packageStates.get(i);
+ var pkg = packageState.getPkg();
+ if (packageName != null && !packageName.equals(pkg.getPackageName())) {
+ continue;
+ }
+ ipw.println(pkg.getPackageName());
+ ipw.increaseIndent();
+ ipw.println("Version: " + pkg.getLongVersionCode());
+ ipw.println("Path: " + pkg.getBaseApkPath());
+ ipw.println("IsActive: " + isActive);
+ ipw.println("IsFactory: " + !packageState.isUpdatedSystemApp());
+ ipw.println("ApplicationInfo: ");
+ ipw.increaseIndent();
+ // TODO: Dump the package manually
+ AndroidPackageUtils.generateAppInfoWithoutState(pkg)
+ .dump(new PrintWriterPrinter(ipw), "");
+ ipw.decreaseIndent();
+ ipw.decreaseIndent();
+ }
+ ipw.decreaseIndent();
+ ipw.println();
+ }
+
+ /**
* Dump information about the packages contained in a particular cache
* @param packagesCache the cache to print information about.
* @param packageName a {@link String} containing a package name, or {@code null}. If set,
* only information about that specific package will be dumped.
* @param ipw the {@link IndentingPrintWriter} object to send information to.
*/
- static void dumpPackages(List<PackageInfo> packagesCache,
+ static void dumpPackages(List<Pair<ApexInfo, AndroidPackage>> packagesCache,
@Nullable String packageName, IndentingPrintWriter ipw) {
ipw.println();
ipw.increaseIndent();
for (int i = 0, size = packagesCache.size(); i < size; i++) {
- final PackageInfo pi = packagesCache.get(i);
- if (packageName != null && !packageName.equals(pi.packageName)) {
+ final var pair = packagesCache.get(i);
+ var apexInfo = pair.first;
+ var pkg = pair.second;
+ if (packageName != null && !packageName.equals(pkg.getPackageName())) {
continue;
}
- ipw.println(pi.packageName);
+ ipw.println(pkg.getPackageName());
ipw.increaseIndent();
- ipw.println("Version: " + pi.versionCode);
- ipw.println("Path: " + pi.applicationInfo.sourceDir);
- ipw.println("IsActive: " + isActive(pi));
- ipw.println("IsFactory: " + isFactory(pi));
+ ipw.println("Version: " + pkg.getLongVersionCode());
+ ipw.println("Path: " + pkg.getBaseApkPath());
+ ipw.println("IsActive: " + apexInfo.isActive);
+ ipw.println("IsFactory: " + apexInfo.isFactory);
ipw.println("ApplicationInfo: ");
ipw.increaseIndent();
- pi.applicationInfo.dump(new PrintWriterPrinter(ipw), "");
+ // TODO: Dump the package manually
+ AndroidPackageUtils.generateAppInfoWithoutState(pkg)
+ .dump(new PrintWriterPrinter(ipw), "");
ipw.decreaseIndent();
ipw.decreaseIndent();
}
ipw.decreaseIndent();
ipw.println();
}
-}
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 63c25ea520f7..8ec3d2bc74ca 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -65,6 +65,7 @@ import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.apex.ApexInfo;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
@@ -1018,11 +1019,12 @@ public class ComputerEngine implements Computer {
if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
apexFlags = ApexManager.MATCH_FACTORY_PACKAGE;
}
- final PackageInfo pi = mApexPackageInfo.getPackageInfo(packageName, apexFlags);
- if (pi == null) {
+ final var pair = mApexPackageInfo.getPackageInfo(packageName, apexFlags);
+ if (pair == null) {
return null;
}
- return pi.applicationInfo;
+ return PackageInfoUtils.generateApplicationInfo(pair.second, flags,
+ PackageUserStateInternal.DEFAULT, userId, null);
}
}
if ("android".equals(packageName) || "system".equals(packageName)) {
@@ -1718,8 +1720,12 @@ public class ComputerEngine implements Computer {
// Instant app filtering for APEX modules is ignored
if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
if (matchApex) {
- return mApexPackageInfo.getPackageInfo(packageName,
+ final var pair = mApexPackageInfo.getPackageInfo(packageName,
ApexManager.MATCH_FACTORY_PACKAGE);
+ if (pair == null) {
+ return null;
+ }
+ return PackageInfoUtils.generate(pair.second, pair.first, flags, null, userId);
}
}
final PackageStateInternal ps = mSettings.getDisabledSystemPkg(packageName);
@@ -1775,8 +1781,12 @@ public class ComputerEngine implements Computer {
}
if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
if (matchApex) {
- return mApexPackageInfo.getPackageInfo(packageName,
+ final var pair = mApexPackageInfo.getPackageInfo(packageName,
ApexManager.MATCH_ACTIVE_PACKAGE);
+ if (pair == null) {
+ return null;
+ }
+ return PackageInfoUtils.generate(pair.second, pair.first, flags, null, userId);
}
}
return null;
@@ -1883,10 +1893,17 @@ public class ComputerEngine implements Computer {
}
if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
if (listApex) {
+ List<Pair<ApexInfo, AndroidPackage>> pairs;
if (listFactory) {
- list.addAll(mApexPackageInfo.getFactoryPackages());
+ pairs = mApexPackageInfo.getFactoryPackages();
} else {
- list.addAll(mApexPackageInfo.getActivePackages());
+ pairs = mApexPackageInfo.getActivePackages();
+ }
+
+ for (int index = 0; index < pairs.size(); index++) {
+ var pair = pairs.get(index);
+ list.add(PackageInfoUtils.generate(pair.second, pair.first, flags, null,
+ userId));
}
}
}
@@ -3404,29 +3421,23 @@ public class ComputerEngine implements Computer {
} // switch
}
- private void generateApexPackageInfo(List<PackageInfo> activePackages,
- List<PackageInfo> inactivePackages, List<PackageInfo> factoryPackages) {
+ private void generateApexPackageInfo(@NonNull List<PackageStateInternal> activePackages,
+ @NonNull List<PackageStateInternal> inactivePackages,
+ @NonNull List<PackageStateInternal> factoryActivePackages,
+ @NonNull List<PackageStateInternal> factoryInactivePackages) {
for (AndroidPackage p : mPackages.values()) {
final String packageName = p.getPackageName();
PackageStateInternal ps = mSettings.getPackage(packageName);
if (!p.isApex() || ps == null) {
continue;
}
- PackageInfo pi = generatePackageInfo(ps, 0, 0);
- if (pi == null) {
- continue;
- }
- pi.isActiveApex = true;
- activePackages.add(pi);
+ activePackages.add(ps);
if (!ps.isUpdatedSystemApp()) {
- factoryPackages.add(pi);
+ factoryActivePackages.add(ps);
} else {
PackageStateInternal psDisabled = mSettings.getDisabledSystemPkg(packageName);
- pi = generatePackageInfo(psDisabled, 0, 0);
- if (pi != null) {
- factoryPackages.add(pi);
- inactivePackages.add(pi);
- }
+ factoryInactivePackages.add(psDisabled);
+ inactivePackages.add(psDisabled);
}
}
}
@@ -3434,16 +3445,19 @@ public class ComputerEngine implements Computer {
private void dumpApex(PrintWriter pw, String packageName) {
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
- List<PackageInfo> activePackages = new ArrayList<>();
- List<PackageInfo> inactivePackages = new ArrayList<>();
- List<PackageInfo> factoryPackages = new ArrayList<>();
- generateApexPackageInfo(activePackages, inactivePackages, factoryPackages);
+ List<PackageStateInternal> activePackages = new ArrayList<>();
+ List<PackageStateInternal> inactivePackages = new ArrayList<>();
+ List<PackageStateInternal> factoryActivePackages = new ArrayList<>();
+ List<PackageStateInternal> factoryInactivePackages = new ArrayList<>();
+ generateApexPackageInfo(activePackages, inactivePackages, factoryActivePackages,
+ factoryInactivePackages);
ipw.println("Active APEX packages:");
- ApexPackageInfo.dumpPackages(activePackages, packageName, ipw);
+ ApexPackageInfo.dumpPackageStates(activePackages, true, packageName, ipw);
ipw.println("Inactive APEX packages:");
- ApexPackageInfo.dumpPackages(inactivePackages, packageName, ipw);
+ ApexPackageInfo.dumpPackageStates(inactivePackages, false, packageName, ipw);
ipw.println("Factory APEX packages:");
- ApexPackageInfo.dumpPackages(factoryPackages, packageName, ipw);
+ ApexPackageInfo.dumpPackageStates(factoryActivePackages, true, packageName, ipw);
+ ApexPackageInfo.dumpPackageStates(factoryInactivePackages, false, packageName, ipw);
} else {
mApexPackageInfo.dump(pw, packageName);
}
diff --git a/services/core/java/com/android/server/pm/InitAppsHelper.java b/services/core/java/com/android/server/pm/InitAppsHelper.java
index b142ba6822d9..122ab10f43d9 100644
--- a/services/core/java/com/android/server/pm/InitAppsHelper.java
+++ b/services/core/java/com/android/server/pm/InitAppsHelper.java
@@ -116,7 +116,7 @@ final class InitAppsHelper {
mScanFlags = scanFlags;
}
mSystemParseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
- mSystemScanFlags = scanFlags | SCAN_AS_SYSTEM;
+ mSystemScanFlags = mScanFlags | SCAN_AS_SYSTEM;
mExecutorService = ParallelPackageParser.makeExecutorService();
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 6ee43a0268b6..66a97b3b9a89 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -912,8 +912,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
if (session == null || !isCallingUidOwner(session)) {
throw new SecurityException("Caller has no access to session " + sessionId);
}
- session.params.appLabel = appLabel;
- mInternalCallback.onSessionBadgingChanged(session);
+ if (!appLabel.equals(session.params.appLabel)) {
+ session.params.appLabel = appLabel;
+ mInternalCallback.onSessionBadgingChanged(session);
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3f052c039f9c..32b3e6a4ab76 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1611,7 +1611,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mSharedLibraries = injector.getSharedLibrariesImpl();
mApexManager = testParams.apexManager;
- mApexPackageInfo = new ApexPackageInfo();
+ mApexPackageInfo = new ApexPackageInfo(this);
mArtManagerService = testParams.artManagerService;
mAvailableFeatures = testParams.availableFeatures;
mBackgroundDexOptService = testParams.backgroundDexOptService;
@@ -1811,7 +1811,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mProtectedPackages = new ProtectedPackages(mContext);
mApexManager = injector.getApexManager();
- mApexPackageInfo = new ApexPackageInfo();
+ mApexPackageInfo = new ApexPackageInfo(this);
mAppsFilter = mInjector.getAppsFilter();
mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,
@@ -1829,8 +1829,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mAppDataHelper = new AppDataHelper(this);
mInstallPackageHelper = new InstallPackageHelper(this, mAppDataHelper);
mRemovePackageHelper = new RemovePackageHelper(this, mAppDataHelper);
- mInitAppsHelper = new InitAppsHelper(this, mApexManager, mApexPackageInfo,
- mInstallPackageHelper, mInjector.getSystemPartitions());
mDeletePackageHelper = new DeletePackageHelper(this, mRemovePackageHelper,
mAppDataHelper);
mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper);
@@ -1951,6 +1949,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
+ ver.fingerprint + " to " + PackagePartitions.FINGERPRINT);
}
+ mInitAppsHelper = new InitAppsHelper(this, mApexManager, mApexPackageInfo,
+ mInstallPackageHelper, mInjector.getSystemPartitions());
+
// when upgrading from pre-M, promote system app permissions from install to runtime
mPromoteSystemApps =
mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index 0e57c917a72b..86affdd75481 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -823,8 +823,8 @@ final class ScanPackageUtils {
* ideally be static, but, it requires locks to read system state.
*/
public static void applyPolicy(ParsedPackage parsedPackage,
- final @PackageManagerService.ScanFlags int scanFlags, AndroidPackage platformPkg,
- boolean isUpdatedSystemApp) {
+ final @PackageManagerService.ScanFlags int scanFlags,
+ @Nullable AndroidPackage platformPkg, boolean isUpdatedSystemApp) {
if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
parsedPackage.setSystem(true);
// TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index c064324279c1..e55424a5709e 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4789,6 +4789,9 @@ public final class Settings implements Watchable, Snappable {
pw.println();
pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.getFlags(), FLAG_DUMP_SPEC);
pw.println();
+ pw.print(prefix); pw.print(" privatePkgFlags="); printFlags(pw, ps.getPrivateFlags(),
+ PRIVATE_FLAG_DUMP_SPEC);
+ pw.println();
if (pkg != null && pkg.getOverlayTarget() != null) {
pw.print(prefix); pw.print(" overlayTarget="); pw.println(pkg.getOverlayTarget());
diff --git a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
index 937b2cf047a4..b57d4d55b6eb 100644
--- a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
+++ b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
@@ -219,38 +219,21 @@ class UserSystemPackageInstaller {
// Install/uninstall system packages per user.
for (int userId : mUm.getUserIds()) {
- final Set<String> userWhitelist = getInstallablePackagesForUserId(userId);
-
- // If null, run for all packages
- if (userWhitelist == null) {
- pmInt.forEachPackageState(packageState -> {
- if (packageState.getPkg() == null) {
- return;
- }
- final boolean install = !packageState.getTransientState()
- .isHiddenUntilInstalled();
- if (packageState.getUserStateOrDefault(userId).isInstalled() != install
- && shouldChangeInstallationState(packageState, install, userId,
- isFirstBoot, isConsideredUpgrade, preExistingPackages)) {
- changesToCommit.add(userId, packageState.getPackageName(), install);
- }
- });
- } else {
- for (String packageName : userWhitelist) {
- PackageStateInternal packageState = pmInt.getPackageStateInternal(packageName);
- if (packageState.getPkg() == null) {
- continue;
- }
-
- final boolean install = !packageState.getTransientState()
- .isHiddenUntilInstalled();
- if (packageState.getUserStateOrDefault(userId).isInstalled() != install
- && shouldChangeInstallationState(packageState, install, userId,
- isFirstBoot, isConsideredUpgrade, preExistingPackages)) {
- changesToCommit.add(userId, packageState.getPackageName(), install);
- }
+ final Set<String> userAllowlist = getInstallablePackagesForUserId(userId);
+
+ pmInt.forEachPackageState(packageState -> {
+ if (packageState.getPkg() == null) {
+ return;
}
- }
+ boolean install = (userAllowlist == null
+ || userAllowlist.contains(packageState.getPackageName()))
+ && !packageState.getTransientState().isHiddenUntilInstalled();
+ if (packageState.getUserStateOrDefault(userId).isInstalled() != install
+ && shouldChangeInstallationState(packageState, install, userId,
+ isFirstBoot, isConsideredUpgrade, preExistingPackages)) {
+ changesToCommit.add(userId, packageState.getPackageName(), install);
+ }
+ });
}
pmInt.commitPackageStateMutation(null, packageStateMutator -> {
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 9c620c4ff3ab..a44def8f772a 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -93,12 +93,14 @@ public class PackageInfoUtils {
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
+ * @deprecated Once ENABLE_FEATURE_SCAN_APEX is removed, this should also be removed.
*/
+ @Deprecated
@Nullable
- public static PackageInfo generate(AndroidPackage pkg, ApexInfo apexInfo, int flags,
- @Nullable PackageStateInternal pkgSetting) {
+ public static PackageInfo generate(AndroidPackage pkg, ApexInfo apexInfo, long flags,
+ @Nullable PackageStateInternal pkgSetting, @UserIdInt int userId) {
return generateWithComponents(pkg, EmptyArray.INT, flags, 0, 0, Collections.emptySet(),
- PackageUserStateInternal.DEFAULT, UserHandle.getCallingUserId(), apexInfo, pkgSetting);
+ PackageUserStateInternal.DEFAULT, userId, apexInfo, pkgSetting);
}
/**
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
index b91f15a4d037..748d32894d8a 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
@@ -22,7 +22,6 @@ import android.annotation.Nullable;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
-import com.android.server.pm.pkg.SELinuxUtil;
import android.content.pm.SigningDetails;
import android.content.res.TypedArray;
import android.os.Environment;
@@ -35,6 +34,7 @@ import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DataClass;
import com.android.internal.util.Parcelling.BuiltIn.ForInternedString;
import com.android.server.pm.parsing.PackageInfoUtils;
+import com.android.server.pm.pkg.SELinuxUtil;
import com.android.server.pm.pkg.component.ComponentMutateUtils;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedProvider;
@@ -255,7 +255,7 @@ public class PackageImpl extends ParsingPackageImpl implements ParsedPackage, An
}
@Override
- public PackageImpl setSigningDetails(@Nullable SigningDetails value) {
+ public PackageImpl setSigningDetails(@NonNull SigningDetails value) {
super.setSigningDetails(value);
return this;
}
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
index 40f859c5e82e..b7b37b2630f7 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
@@ -334,7 +334,7 @@ public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage setSharedUserLabel(int sharedUserLabel);
- ParsingPackage setSigningDetails(SigningDetails signingDetails);
+ ParsingPackage setSigningDetails(@NonNull SigningDetails signingDetails);
ParsingPackage setSplitClassLoaderName(int splitIndex, String classLoaderName);
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
index 6a4513d45d8f..803780fe2a9b 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
@@ -317,8 +317,8 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden,
@Nullable
@DataClass.ParcelWith(ForInternedString.class)
protected String volumeUuid;
- @Nullable
- private SigningDetails signingDetails;
+ @NonNull
+ private SigningDetails signingDetails = SigningDetails.UNKNOWN;
@NonNull
@DataClass.ParcelWith(ForInternedString.class)
@@ -1873,7 +1873,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden,
return volumeUuid;
}
- @Nullable
+ @NonNull
@Override
public SigningDetails getSigningDetails() {
return signingDetails;
@@ -2474,7 +2474,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden,
}
@Override
- public ParsingPackageImpl setSigningDetails(@Nullable SigningDetails value) {
+ public ParsingPackageImpl setSigningDetails(@NonNull SigningDetails value) {
signingDetails = value;
return this;
}
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java
index 20b1ed8d0c3e..22729993af64 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java
@@ -188,6 +188,7 @@ public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutSt
* The signature data of all APKs in this package, which must be exactly the same across the
* base and splits.
*/
+ @NonNull
SigningDetails getSigningDetails();
/**
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 71b1bc2e24bc..bec3754536e2 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -1207,7 +1207,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
private int mImeBackDisposition = 0;
private boolean mShowImeSwitcher = false;
private IBinder mImeToken = null;
- private LetterboxDetails[] mLetterboxDetails;
+ private LetterboxDetails[] mLetterboxDetails = new LetterboxDetails[0];
private void setBarAttributes(@Appearance int appearance,
AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
index 1f8b0de8d903..59c118d2f8ef 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
@@ -51,6 +51,7 @@ import com.android.server.LocalServices;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.time.Duration;
+import java.util.Objects;
/**
* Monitors the network time. If looking up the network time fails for some reason, it tries a few
@@ -74,8 +75,6 @@ public class NetworkTimeUpdateService extends Binder {
private static final int POLL_REQUEST = 0;
- private Network mDefaultNetwork = null;
-
private final Context mContext;
private final NtpTrustedTime mTime;
private final AlarmManager mAlarmManager;
@@ -84,21 +83,12 @@ public class NetworkTimeUpdateService extends Binder {
private final PendingIntent mPendingPollIntent;
private final PowerManager.WakeLock mWakeLock;
- // NTP lookup is done on this thread and handler
- private Handler mHandler;
- private AutoTimeSettingObserver mAutoTimeSettingObserver;
- private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
-
// Normal polling frequency
private final long mPollingIntervalMs;
// Try-again polling interval, in case the network request failed
private final long mPollingIntervalShorterMs;
// Number of times to try again
private final int mTryAgainTimesMax;
- // Keeps track of how many quick attempts were made to fetch NTP time.
- // During bootup, the network may not have been up yet, or it's taking time for the
- // connection to happen.
- private int mTryAgainCounter;
/**
* A log that records the decisions to fetch a network time update.
@@ -107,8 +97,26 @@ public class NetworkTimeUpdateService extends Binder {
@NonNull
private final LocalLog mLocalLog = new LocalLog(30, false /* useLocalTimestamps */);
- public NetworkTimeUpdateService(Context context) {
- mContext = context;
+ // NTP lookup is done on this thread and handler
+ // @NonNull after systemRunning()
+ private Handler mHandler;
+ // @NonNull after systemRunning()
+ private AutoTimeSettingObserver mAutoTimeSettingObserver;
+ // @NonNull after systemRunning()
+ private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
+
+ // This field is only updated and accessed by the mHandler thread (except dump()).
+ @Nullable
+ private Network mDefaultNetwork = null;
+
+ // Keeps track of how many quick attempts were made to fetch NTP time.
+ // During bootup, the network may not have been up yet, or it's taking time for the
+ // connection to happen.
+ // This field is only updated and accessed by the mHandler thread (except dump()).
+ private int mTryAgainCounter;
+
+ public NetworkTimeUpdateService(@NonNull Context context) {
+ mContext = Objects.requireNonNull(context);
mTime = NtpTrustedTime.getInstance(context);
mAlarmManager = mContext.getSystemService(AlarmManager.class);
mTimeDetectorInternal = LocalServices.getService(TimeDetectorInternal.class);
@@ -205,23 +213,26 @@ public class NetworkTimeUpdateService extends Binder {
private void onPollNetworkTime(int event) {
// If we don't have any default network, don't bother.
- if (mDefaultNetwork == null) return;
+ Network network = mDefaultNetwork;
+ if (network == null) return;
+
mWakeLock.acquire();
try {
- onPollNetworkTimeUnderWakeLock(event);
+ onPollNetworkTimeUnderWakeLock(network, event);
} finally {
mWakeLock.release();
}
}
- private void onPollNetworkTimeUnderWakeLock(int event) {
+ private void onPollNetworkTimeUnderWakeLock(@NonNull Network network, int event) {
long currentElapsedRealtimeMillis = SystemClock.elapsedRealtime();
+
// Force an NTP fix when outdated
NtpTrustedTime.TimeResult cachedNtpResult = mTime.getCachedTimeResult();
if (cachedNtpResult == null || cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)
>= mPollingIntervalMs) {
- if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
- boolean isSuccessful = mTime.forceRefresh();
+ if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh using network=" + network);
+ boolean isSuccessful = mTime.forceRefresh(network);
if (isSuccessful) {
mTryAgainCounter = 0;
} else {
@@ -265,7 +276,8 @@ public class NetworkTimeUpdateService extends Binder {
}
/** Suggests the time to the time detector. It may choose use it to set the system clock. */
- private void makeNetworkTimeSuggestion(TimeResult ntpResult, String debugInfo) {
+ private void makeNetworkTimeSuggestion(
+ @NonNull TimeResult ntpResult, @NonNull String debugInfo) {
TimestampedValue<Long> timeSignal = new TimestampedValue<>(
ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
NetworkTimeSuggestion timeSuggestion =
@@ -295,7 +307,7 @@ public class NetworkTimeUpdateService extends Binder {
}
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case EVENT_AUTO_TIME_ENABLED:
case EVENT_POLL_NETWORK_TIME:
@@ -308,7 +320,7 @@ public class NetworkTimeUpdateService extends Binder {
private class NetworkTimeUpdateCallback extends NetworkCallback {
@Override
- public void onAvailable(Network network) {
+ public void onAvailable(@NonNull Network network) {
Log.d(TAG, String.format("New default network %s; checking time.", network));
mDefaultNetwork = network;
// Running on mHandler so invoke directly.
@@ -316,7 +328,7 @@ public class NetworkTimeUpdateService extends Binder {
}
@Override
- public void onLost(Network network) {
+ public void onLost(@NonNull Network network) {
if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
}
}
@@ -331,10 +343,10 @@ public class NetworkTimeUpdateService extends Binder {
private final int mMsg;
private final Handler mHandler;
- AutoTimeSettingObserver(Context context, Handler handler, int msg) {
+ AutoTimeSettingObserver(@NonNull Context context, @NonNull Handler handler, int msg) {
super(handler);
- mContext = context;
- mHandler = handler;
+ mContext = Objects.requireNonNull(context);
+ mHandler = Objects.requireNonNull(handler);
mMsg = msg;
}
@@ -366,6 +378,7 @@ public class NetworkTimeUpdateService extends Binder {
pw.println("mPollingIntervalMs=" + Duration.ofMillis(mPollingIntervalMs));
pw.println("mPollingIntervalShorterMs=" + Duration.ofMillis(mPollingIntervalShorterMs));
pw.println("mTryAgainTimesMax=" + mTryAgainTimesMax);
+ pw.println("mDefaultNetwork=" + mDefaultNetwork);
pw.println("mTryAgainCounter=" + mTryAgainCounter);
pw.println();
pw.println("NtpTrustedTime:");
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 6c1f3bbef9e3..42e0533f178f 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -272,7 +272,6 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConstrainDisplayApisConfig;
import android.content.pm.PackageManager;
-import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -478,7 +477,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
private int mLastReportedDisplayId;
boolean mLastReportedMultiWindowMode;
boolean mLastReportedPictureInPictureMode;
- CompatibilityInfo compat;// last used compatibility mode
ActivityRecord resultTo; // who started this entry, so will get our reply
final String resultWho; // additional identifier for use by resultTo.
final int requestCode; // code given by requester (resultTo)
@@ -1022,7 +1020,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (rootVoiceInteraction) {
pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
}
- pw.print(prefix); pw.print("compat="); pw.print(compat);
+ pw.print(prefix); pw.print("compat=");
+ pw.print(mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo));
pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
@@ -2728,8 +2727,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
final StartingSurfaceController.StartingSurface surface;
- final StartingData startingData = mStartingData;
+ final boolean animate;
if (mStartingData != null) {
+ animate = prepareAnimation && mStartingData.needRevealAnimation()
+ && mStartingWindow.isVisibleByPolicy();
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Schedule remove starting %s startingWindow=%s"
+ + " animate=%b Callers=%s", this, mStartingWindow, animate,
+ Debug.getCallers(5));
surface = mStartingSurface;
mStartingData = null;
mStartingSurface = null;
@@ -2747,21 +2751,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return;
}
-
- ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Schedule remove starting %s startingWindow=%s"
- + " startingView=%s Callers=%s", this, mStartingWindow, mStartingSurface,
- Debug.getCallers(5));
-
- final Runnable removeSurface = () -> {
- ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing startingView=%s", surface);
- try {
- surface.remove(prepareAnimation && startingData.needRevealAnimation());
- } catch (Exception e) {
- Slog.w(TAG_WM, "Exception when removing starting window", e);
- }
- };
-
- removeSurface.run();
+ surface.remove(animate);
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index f5c5a134402f..4066fe15d39b 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -56,6 +56,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.INVALID_UID;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
@@ -2934,6 +2935,10 @@ class ActivityStarter {
newParent = candidateTf;
}
}
+ if (newParent.canHaveEmbeddingActivityTransition(mStartActivity)) {
+ // Make sure the embedded TaskFragment is included in the start activity transition.
+ newParent.collectEmbeddedTaskFragmentIfNeeded();
+ }
if (mStartActivity.getTaskFragment() == null
|| mStartActivity.getTaskFragment() == newParent) {
newParent.addChild(mStartActivity, POSITION_TOP);
@@ -2972,6 +2977,7 @@ class ActivityStarter {
if (taskFragment.isOrganized()) {
mService.mWindowOrganizerController.sendTaskFragmentOperationFailure(
taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken,
+ taskFragment, HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT,
new SecurityException(errMsg));
} else {
// If the taskFragment is not organized, just dump error message as warning logs.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 84740683f6aa..345ec117b03a 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -875,7 +875,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY);
r.forceNewConfig = false;
mService.getAppWarningsLocked().onStartActivity(r);
- r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
// Because we could be starting an Activity in the system process this may not go
// across a Binder interface which would create a new Configuration. Consequently
@@ -905,7 +904,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
- mergedConfiguration.getOverrideConfiguration(), r.compat,
+ mergedConfiguration.getOverrideConfiguration(),
r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
results, newIntents, r.takeOptions(), isTransitionForward,
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index b23f50154257..1ed5a851549c 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -135,8 +135,10 @@ class AnrController {
* Notify a window owned by the provided pid was unresponsive.
*/
private void notifyWindowUnresponsive(int pid, String reason) {
- Slog.i(TAG_WM, "ANR in input window owned by pid=" + pid + ". Reason: " + reason);
- dumpAnrStateLocked(null /* activity */, null /* windowState */, reason);
+ synchronized (mService.mGlobalLock) {
+ Slog.i(TAG_WM, "ANR in input window owned by pid=" + pid + ". Reason: " + reason);
+ dumpAnrStateLocked(null /* activity */, null /* windowState */, reason);
+ }
// We cannot determine the z-order of the window, so place the anr dialog as high
// as possible.
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 0af046281cc5..1898cc65b107 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -204,8 +204,11 @@ class AsyncRotationController extends FadeAnimationController implements Consume
for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
final WindowToken token = mTargetWindowTokens.keyAt(i);
for (int j = token.getChildCount() - 1; j >= 0; j--) {
- // TODO(b/234585256): The consumer should be handleFinishDrawing().
- token.getChildAt(j).applyWithNextDraw(t -> {});
+ // TODO(b/234585256): The consumer should be handleFinishDrawing(). And check why
+ // the local window might easily time out.
+ final WindowState w = token.getChildAt(j);
+ if (w.isClientLocal()) continue;
+ w.applyWithNextDraw(t -> {});
}
}
mIsSyncDrawRequested = true;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 518d4bf54ccd..b54cd415d8df 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -230,6 +230,7 @@ import android.window.DisplayWindowPolicyController;
import android.window.IDisplayAreaOrganizer;
import android.window.TransitionRequestInfo;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -1078,7 +1079,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mDisplayPolicy = new DisplayPolicy(mWmService, this);
mDisplayRotation = new DisplayRotation(mWmService, this);
mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat(
- com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio);
+ R.dimen.config_closeToSquareDisplayMaxAspectRatio);
if (isDefaultDisplay) {
// The policy may be invoked right after here, so it requires the necessary default
// fields of this display content.
@@ -1570,7 +1571,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mAtmService.mContext.createConfigurationContext(getConfiguration());
final float minimalSize =
displayConfigurationContext.getResources().getDimension(
- com.android.internal.R.dimen.default_minimal_size_resizable_task);
+ R.dimen.default_minimal_size_resizable_task);
if (Double.compare(mDisplayMetrics.density, 0.0) == 0) {
throw new IllegalArgumentException("Display with ID=" + getDisplayId() + "has invalid "
+ "DisplayMetrics.density= 0.0");
@@ -3271,10 +3272,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) {
- if (mScreenRotationAnimation != null) {
- mScreenRotationAnimation.kill();
- }
+ final ScreenRotationAnimation prev = mScreenRotationAnimation;
mScreenRotationAnimation = screenRotationAnimation;
+ if (prev != null) {
+ prev.kill();
+ }
// Hide the windows which are not significant in rotation animation. So that the windows
// don't need to block the unfreeze time.
@@ -4263,6 +4265,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void detach(Transaction t) {
removeImeSurface(t);
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(64);
+ sb.append("ImeScreenshot{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" imeTarget=" + mImeTarget);
+ sb.append(" surface=" + mImeSurface);
+ sb.append('}');
+ return sb.toString();
+ }
}
private void attachAndShowImeScreenshotOnTarget() {
@@ -4295,15 +4308,23 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
/**
- * Removes the IME screenshot when necessary.
- *
- * Used when app transition animation finished or obsoleted screenshot surface like size
- * changed by rotation.
+ * Removes the IME screenshot when the caller is a part of the attached target window.
*/
- void removeImeScreenshotIfPossible() {
- if (mImeLayeringTarget == null
- || mImeLayeringTarget.mAttrs.type != TYPE_APPLICATION_STARTING
- && !mImeLayeringTarget.inTransitionSelfOrParent()) {
+ void removeImeSurfaceByTarget(WindowContainer win) {
+ if (mImeScreenshot == null || win == null) {
+ return;
+ }
+ // The starting window shouldn't be the input target to attach the IME screenshot during
+ // transitioning.
+ if (win.asWindowState() != null
+ && win.asWindowState().mAttrs.type == TYPE_APPLICATION_STARTING) {
+ return;
+ }
+
+ final WindowState screenshotTarget = mImeScreenshot.getImeTarget();
+ final boolean winIsOrContainsScreenshotTarget = (win == screenshotTarget
+ || win.getWindow(w -> w == screenshotTarget) != null);
+ if (winIsOrContainsScreenshotTarget) {
removeImeSurfaceImmediately();
}
}
@@ -4563,9 +4584,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// if the wallpaper service is disabled on the device, we're never going to have
// wallpaper, don't bother waiting for it
boolean wallpaperEnabled = mWmService.mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_enableWallpaperService)
+ R.bool.config_enableWallpaperService)
&& mWmService.mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_checkWallpaperAtBoot);
+ R.bool.config_checkWallpaperAtBoot);
final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS);
final boolean haveApp = drawnWindowTypes.get(TYPE_BASE_APPLICATION);
@@ -4650,10 +4671,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
wc, SurfaceAnimator.animationTypeToString(type), mImeScreenshot,
mImeScreenshot.getImeTarget());
}
- if (mImeScreenshot != null && (wc == mImeScreenshot.getImeTarget()
- || wc.getWindow(w -> w == mImeScreenshot.getImeTarget()) != null)
- && (type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
- removeImeSurfaceImmediately();
+ if ((type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
+ removeImeSurfaceByTarget(wc);
}
}
@@ -6520,9 +6539,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
class RemoteInsetsControlTarget implements InsetsControlTarget {
private final IDisplayWindowInsetsController mRemoteInsetsController;
private final InsetsVisibilities mRequestedVisibilities = new InsetsVisibilities();
+ private final boolean mCanShowTransient;
RemoteInsetsControlTarget(IDisplayWindowInsetsController controller) {
mRemoteInsetsController = controller;
+ mCanShowTransient = mWmService.mContext.getResources().getBoolean(
+ R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction);
}
/**
@@ -6579,6 +6601,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
@Override
+ public boolean canShowTransient() {
+ return mCanShowTransient;
+ }
+
+ @Override
public boolean getRequestedVisibility(@InternalInsetsType int type) {
if (type == ITYPE_IME) {
return getInsetsStateController().getImeSourceProvider().isImeShowing();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 4a7a8bd99419..14e224111286 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -220,6 +220,7 @@ public class DisplayPolicy {
@Px
private int mRightGestureInset;
+ private boolean mCanSystemBarsBeShownByUser;
private boolean mNavButtonForcedVisible;
StatusBarManagerInternal getStatusBarManagerInternal() {
@@ -425,6 +426,9 @@ public class DisplayPolicy {
final Resources r = mContext.getResources();
mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer);
mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer);
+ mCanSystemBarsBeShownByUser = !r.getBoolean(
+ R.bool.config_remoteInsetsControllerControlsSystemBars) || r.getBoolean(
+ R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction);
mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
Context.ACCESSIBILITY_SERVICE);
@@ -617,7 +621,7 @@ public class DisplayPolicy {
displayContent.mAppTransition.registerListenerLocked(mAppTransitionListener);
displayContent.mTransitionController.registerLegacyListener(mAppTransitionListener);
mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper,
- mService.mVrModeEnabled);
+ mService.mVrModeEnabled, mCanSystemBarsBeShownByUser);
// TODO: Make it can take screenshot on external display
mScreenshotHelper = displayContent.isDefaultDisplay
@@ -2024,6 +2028,11 @@ public class DisplayPolicy {
return lp.width;
}
+ @VisibleForTesting
+ void setCanSystemBarsBeShownByUser(boolean canBeShown) {
+ mCanSystemBarsBeShownByUser = canBeShown;
+ }
+
void notifyDisplayReady() {
mHandler.post(() -> {
final int displayId = getDisplayId();
@@ -2261,11 +2270,17 @@ public class DisplayPolicy {
updateSystemBarAttributes();
}
- private void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
+ @VisibleForTesting
+ void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
if (swipeTarget == null || !mService.mPolicy.isUserSetupComplete()) {
// Swipe-up for navigation bar is disabled during setup
return;
}
+ if (!mCanSystemBarsBeShownByUser) {
+ Slog.d(TAG, "Remote insets controller disallows showing system bars - ignoring "
+ + "request");
+ return;
+ }
final InsetsSourceProvider provider = swipeTarget.getControllableInsetProvider();
final InsetsControlTarget controlTarget = provider != null
? provider.getControlTarget() : null;
diff --git a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
index 93bdf16a99ea..4c18d0b8a0dc 100644
--- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
@@ -99,9 +99,11 @@ public class ImmersiveModeConfirmation {
// Local copy of vr mode enabled state, to avoid calling into VrManager with
// the lock held.
private boolean mVrModeEnabled;
+ private boolean mCanSystemBarsBeShownByUser;
private int mLockTaskState = LOCK_TASK_MODE_NONE;
- ImmersiveModeConfirmation(Context context, Looper looper, boolean vrModeEnabled) {
+ ImmersiveModeConfirmation(Context context, Looper looper, boolean vrModeEnabled,
+ boolean canSystemBarsBeShownByUser) {
final Display display = context.getDisplay();
final Context uiContext = ActivityThread.currentActivityThread().getSystemUiContext();
mContext = display.getDisplayId() == DEFAULT_DISPLAY
@@ -111,6 +113,7 @@ public class ImmersiveModeConfirmation {
mPanicThresholdMs = context.getResources()
.getInteger(R.integer.config_immersive_mode_confirmation_panic);
mVrModeEnabled = vrModeEnabled;
+ mCanSystemBarsBeShownByUser = canSystemBarsBeShownByUser;
}
private long getNavBarExitDuration() {
@@ -171,6 +174,7 @@ public class ImmersiveModeConfirmation {
if ((DEBUG_SHOW_EVERY_TIME || !sConfirmed)
&& userSetupComplete
&& !mVrModeEnabled
+ && mCanSystemBarsBeShownByUser
&& !navBarEmpty
&& !UserManager.isDeviceInDemoMode(mContext)
&& (mLockTaskState != LOCK_TASK_MODE_LOCKED)) {
diff --git a/services/core/java/com/android/server/wm/LaunchParamsUtil.java b/services/core/java/com/android/server/wm/LaunchParamsUtil.java
new file mode 100644
index 000000000000..a618f7c79238
--- /dev/null
+++ b/services/core/java/com/android/server/wm/LaunchParamsUtil.java
@@ -0,0 +1,129 @@
+/*
+ * 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.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.util.DisplayMetrics.DENSITY_DEFAULT;
+
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.NonNull;
+import android.content.pm.ActivityInfo;
+import android.graphics.Rect;
+import android.util.Size;
+
+/**
+ * The static class that defines some utility constants and functions that are shared among launch
+ * params modifiers.
+ */
+class LaunchParamsUtil {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "LaunchParamsUtil" : TAG_ATM;
+ private static final boolean DEBUG = false;
+
+ // Screen size of Nexus 5x
+ static final int DEFAULT_PORTRAIT_FREEFORM_WIDTH_DP = 412;
+ static final int DEFAULT_PORTRAIT_FREEFORM_HEIGHT_DP = 732;
+
+ // One of the most common tablet sizes that are small enough to fit in most large screens.
+ private static final int DEFAULT_LANDSCAPE_FREEFORM_WIDTH_DP = 1064;
+ private static final int DEFAULT_LANDSCAPE_FREEFORM_HEIGHT_DP = 600;
+
+ private LaunchParamsUtil() {}
+
+ /**
+ * Gets centered bounds of width x height. If inOutBounds is not empty, the result bounds
+ * centers at its center or displayArea's app bounds center if inOutBounds is empty.
+ */
+ static void centerBounds(@NonNull TaskDisplayArea displayArea, int width, int height,
+ @NonNull Rect inOutBounds) {
+ if (inOutBounds.isEmpty()) {
+ displayArea.getStableRect(inOutBounds);
+ }
+ final int left = inOutBounds.centerX() - width / 2;
+ final int top = inOutBounds.centerY() - height / 2;
+ inOutBounds.set(left, top, left + width, top + height);
+ }
+
+ /**
+ * Calculate the default size for a freeform environment. |defaultSize| is used as the default
+ * DP size, but if this is null, the portrait phone size is used.
+ */
+ static Size getDefaultFreeformSize(@NonNull ActivityInfo info,
+ @NonNull TaskDisplayArea displayArea,
+ @NonNull ActivityInfo.WindowLayout layout, int orientation,
+ @NonNull Rect stableBounds) {
+ // Get window size based on Nexus 5x screen, we assume that this is enough to show content
+ // of activities.
+ final float density = (float) displayArea.getConfiguration().densityDpi / DENSITY_DEFAULT;
+ final int freeformWidthInDp = (orientation == SCREEN_ORIENTATION_LANDSCAPE)
+ ? DEFAULT_LANDSCAPE_FREEFORM_WIDTH_DP : DEFAULT_PORTRAIT_FREEFORM_WIDTH_DP;
+ final int freeformHeightInDp = (orientation == SCREEN_ORIENTATION_LANDSCAPE)
+ ? DEFAULT_LANDSCAPE_FREEFORM_HEIGHT_DP : DEFAULT_PORTRAIT_FREEFORM_HEIGHT_DP;
+ final int freeformWidth = (int) (freeformWidthInDp * density + 0.5f);
+ final int freeformHeight = (int) (freeformHeightInDp * density + 0.5f);
+
+ // Minimum layout requirements.
+ final int layoutMinWidth = (layout == null) ? -1 : layout.minWidth;
+ final int layoutMinHeight = (layout == null) ? -1 : layout.minHeight;
+
+ // Max size, which is letterboxing/pillarboxing in displayArea. That's to say the large
+ // dimension of default size is the small dimension of displayArea size, and the small
+ // dimension of default size is calculated to keep the same aspect ratio as the
+ // displayArea's. Here we use stable bounds of displayArea because that indicates the area
+ // that isn't occupied by system widgets (e.g. sysbar and navbar).
+ final int portraitHeight = Math.min(stableBounds.width(), stableBounds.height());
+ final int otherDimension = Math.max(stableBounds.width(), stableBounds.height());
+ final int portraitWidth = (portraitHeight * portraitHeight) / otherDimension;
+ final int maxWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitHeight
+ : portraitWidth;
+ final int maxHeight = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitWidth
+ : portraitHeight;
+ final int width = Math.min(maxWidth, Math.max(freeformWidth, layoutMinWidth));
+ final int height = Math.min(maxHeight, Math.max(freeformHeight, layoutMinHeight));
+ final float aspectRatio = (float) Math.max(width, height) / (float) Math.min(width, height);
+
+ // Aspect ratio requirements.
+ final float minAspectRatio = info.getMinAspectRatio(orientation);
+ final float maxAspectRatio = info.getMaxAspectRatio();
+
+ // Adjust the width and height to the aspect ratio requirements.
+ int adjWidth = width;
+ int adjHeight = height;
+ if (minAspectRatio >= 1 && aspectRatio < minAspectRatio) {
+ // The aspect ratio is below the minimum, adjust it to the minimum.
+ if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
+ // Fix the width, scale the height.
+ adjHeight = (int) (adjWidth / minAspectRatio + 0.5f);
+ } else {
+ // Fix the height, scale the width.
+ adjWidth = (int) (adjHeight / minAspectRatio + 0.5f);
+ }
+ } else if (maxAspectRatio >= 1 && aspectRatio > maxAspectRatio) {
+ // The aspect ratio exceeds the maximum, adjust it to the maximum.
+ if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
+ // Fix the width, scale the height.
+ adjHeight = (int) (adjWidth / maxAspectRatio + 0.5f);
+ } else {
+ // Fix the height, scale the width.
+ adjWidth = (int) (adjHeight / maxAspectRatio + 0.5f);
+ }
+ }
+
+ return new Size(adjWidth, adjHeight);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 8cad16509c4c..fd8b614de9b7 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -40,9 +40,11 @@ import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
+import android.os.IBinder;
import android.os.Trace;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import android.view.DisplayAddress;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
@@ -165,18 +167,43 @@ class ScreenRotationAnimation {
final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
try {
- SurfaceControl.LayerCaptureArgs.Builder builder =
- new SurfaceControl.LayerCaptureArgs.Builder(displayContent.getSurfaceControl())
- .setCaptureSecureLayers(true)
- .setAllowProtected(true)
- .setSourceCrop(new Rect(0, 0, width, height));
-
+ final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer;
if (isSizeChanged) {
+ final DisplayAddress address = displayInfo.address;
+ if (!(address instanceof DisplayAddress.Physical)) {
+ Slog.e(TAG, "Display does not have a physical address: " + displayId);
+ return;
+ }
+ final DisplayAddress.Physical physicalAddress =
+ (DisplayAddress.Physical) address;
+ final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(
+ physicalAddress.getPhysicalDisplayId());
+ if (displayToken == null) {
+ Slog.e(TAG, "Display token is null.");
+ return;
+ }
+ // Temporarily not skip screenshot for the rounded corner overlays and screenshot
+ // the whole display to include the rounded corner overlays.
+ setSkipScreenshotForRoundedCornerOverlays(false, t);
mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays();
+ final SurfaceControl.DisplayCaptureArgs captureArgs =
+ new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
+ .setSourceCrop(new Rect(0, 0, width, height))
+ .setAllowProtected(true)
+ .setCaptureSecureLayers(true)
+ .build();
+ screenshotBuffer = SurfaceControl.captureDisplay(captureArgs);
+ } else {
+ SurfaceControl.LayerCaptureArgs captureArgs =
+ new SurfaceControl.LayerCaptureArgs.Builder(
+ displayContent.getSurfaceControl())
+ .setCaptureSecureLayers(true)
+ .setAllowProtected(true)
+ .setSourceCrop(new Rect(0, 0, width, height))
+ .build();
+ screenshotBuffer = SurfaceControl.captureLayers(captureArgs);
}
- SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
- SurfaceControl.captureLayers(builder.build());
if (screenshotBuffer == null) {
Slog.w(TAG, "Unable to take screenshot of display " + displayId);
return;
@@ -275,6 +302,21 @@ class ScreenRotationAnimation {
t.apply();
}
+ void setSkipScreenshotForRoundedCornerOverlays(
+ boolean skipScreenshot, SurfaceControl.Transaction t) {
+ mDisplayContent.forAllWindows(w -> {
+ if (!w.mToken.mRoundedCornerOverlay || !w.isVisible() || !w.mWinAnimator.hasSurface()) {
+ return;
+ }
+ t.setSkipScreenshot(w.mWinAnimator.mSurfaceController.mSurfaceControl, skipScreenshot);
+ }, false);
+ if (!skipScreenshot) {
+ // Use sync apply to apply the change immediately, so that the next
+ // SC.captureDisplay can capture the screen decor layers.
+ t.apply(true /* sync */);
+ }
+ }
+
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(STARTED, mStarted);
@@ -483,10 +525,15 @@ class ScreenRotationAnimation {
}
mBackColorSurface = null;
}
+
if (mRoundedCornerOverlay != null) {
- for (SurfaceControl sc : mRoundedCornerOverlay) {
- if (sc.isValid()) {
- t.show(sc);
+ if (mDisplayContent.getRotationAnimation() == null
+ || mDisplayContent.getRotationAnimation() == this) {
+ setSkipScreenshotForRoundedCornerOverlays(true, t);
+ for (SurfaceControl sc : mRoundedCornerOverlay) {
+ if (sc.isValid()) {
+ t.show(sc);
+ }
}
}
mRoundedCornerOverlay = null;
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 3e6546ebb647..1c20fb3188b1 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2316,6 +2316,26 @@ class TaskFragment extends WindowContainer<WindowContainer> {
return !startBounds.equals(getBounds());
}
+ boolean canHaveEmbeddingActivityTransition(@NonNull ActivityRecord child) {
+ if (!isOrganizedTaskFragment() || !mTransitionController.isShellTransitionsEnabled()) {
+ return false;
+ }
+ // The activity should request open transition when it is becoming visible.
+ return child.isVisibleRequested();
+ }
+
+ void collectEmbeddedTaskFragmentIfNeeded() {
+ if (!isOrganizedTaskFragment() || mTransitionController.isCollecting(this)) {
+ return;
+ }
+ if (getChildCount() == 0) {
+ // The TaskFragment is new created, and just becoming non-empty.
+ mTransitionController.collectExistenceChange(this);
+ } else {
+ mTransitionController.collect(this);
+ }
+ }
+
@Override
void setSurfaceControl(SurfaceControl sc) {
super.setSurfaceControl(sc);
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 392d4c2f772b..d4551becbaaf 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -16,7 +16,7 @@
package com.android.server.wm;
-import static android.window.TaskFragmentOrganizer.putExceptionInBundle;
+import static android.window.TaskFragmentOrganizer.putErrorInfoInBundle;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
@@ -214,12 +214,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
}
- void onTaskFragmentError(IBinder errorCallbackToken, Throwable exception) {
+ void onTaskFragmentError(IBinder errorCallbackToken, @Nullable TaskFragment taskFragment,
+ int opType, Throwable exception) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
"Sending TaskFragment error exception=%s", exception.toString());
- final Bundle exceptionBundle = putExceptionInBundle(exception);
+ final TaskFragmentInfo info =
+ taskFragment != null ? taskFragment.getTaskFragmentInfo() : null;
+ final Bundle errorBundle = putErrorInfoInBundle(exception, info, opType);
try {
- mOrganizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
+ mOrganizer.onTaskFragmentError(errorCallbackToken, errorBundle);
} catch (RemoteException e) {
Slog.d(TAG, "Exception sending onTaskFragmentError callback", e);
}
@@ -462,13 +465,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
- Throwable exception) {
+ TaskFragment taskFragment, int opType, Throwable exception) {
validateAndGetState(organizer);
Slog.w(TAG, "onTaskFragmentError ", exception);
final PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent.Builder(
PendingTaskFragmentEvent.EVENT_ERROR, organizer)
.setErrorCallbackToken(errorCallbackToken)
+ .setTaskFragment(taskFragment)
.setException(exception)
+ .setOpType(opType)
.build();
mPendingTaskFragmentEvents.add(pendingEvent);
// Make sure the error event will be dispatched if there are no other changes.
@@ -567,19 +572,22 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
// Set when the event is deferred due to the host task is invisible. The defer time will
// be the last active time of the host task.
private long mDeferTime;
+ private int mOpType;
private PendingTaskFragmentEvent(@EventType int eventType,
ITaskFragmentOrganizer taskFragmentOrg,
@Nullable TaskFragment taskFragment,
@Nullable IBinder errorCallbackToken,
@Nullable Throwable exception,
- @Nullable ActivityRecord activity) {
+ @Nullable ActivityRecord activity,
+ int opType) {
mEventType = eventType;
mTaskFragmentOrg = taskFragmentOrg;
mTaskFragment = taskFragment;
mErrorCallbackToken = errorCallbackToken;
mException = exception;
mActivity = activity;
+ mOpType = opType;
}
/**
@@ -610,6 +618,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
private Throwable mException;
@Nullable
private ActivityRecord mActivity;
+ private int mOpType;
Builder(@EventType int eventType, ITaskFragmentOrganizer taskFragmentOrg) {
mEventType = eventType;
@@ -636,9 +645,14 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
return this;
}
+ Builder setOpType(int opType) {
+ mOpType = opType;
+ return this;
+ }
+
PendingTaskFragmentEvent build() {
return new PendingTaskFragmentEvent(mEventType, mTaskFragmentOrg, mTaskFragment,
- mErrorCallbackToken, mException, mActivity);
+ mErrorCallbackToken, mException, mActivity, mOpType);
}
}
}
@@ -667,6 +681,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
private boolean shouldSendEventWhenTaskInvisible(@NonNull PendingTaskFragmentEvent event) {
+ if (event.mEventType == PendingTaskFragmentEvent.EVENT_ERROR) {
+ return true;
+ }
+
final TaskFragmentOrganizerState state =
mTaskFragmentOrganizerState.get(event.mTaskFragmentOrg.asBinder());
final TaskFragmentInfo lastInfo = state.mLastSentTaskFragmentInfos.get(event.mTaskFragment);
@@ -757,7 +775,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
state.onTaskFragmentParentInfoChanged(taskFragment);
break;
case PendingTaskFragmentEvent.EVENT_ERROR:
- state.onTaskFragmentError(event.mErrorCallbackToken, event.mException);
+ state.onTaskFragmentError(event.mErrorCallbackToken, taskFragment, event.mOpType,
+ event.mException);
break;
case PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENT_TO_TASK:
state.onActivityReparentToTask(event.mActivity);
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 4141156f9caf..7b0337d52da2 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -48,6 +48,7 @@ import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
+import android.util.Size;
import android.util.Slog;
import android.view.Gravity;
import android.view.View;
@@ -67,10 +68,6 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskLaunchParamsModifier" : TAG_ATM;
private static final boolean DEBUG = false;
- // Screen size of Nexus 5x
- private static final int DEFAULT_PORTRAIT_PHONE_WIDTH_DP = 412;
- private static final int DEFAULT_PORTRAIT_PHONE_HEIGHT_DP = 732;
-
// Allowance of size matching.
private static final int EPSILON = 2;
@@ -748,7 +745,10 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
// First we get the default size we want.
- getDefaultFreeformSize(root.info, displayArea, layout, orientation, mTmpBounds);
+ displayArea.getStableRect(mTmpStableBounds);
+ final Size defaultSize = LaunchParamsUtil.getDefaultFreeformSize(root.info, displayArea,
+ layout, orientation, mTmpStableBounds);
+ mTmpBounds.set(0, 0, defaultSize.getWidth(), defaultSize.getHeight());
if (hasInitialBounds || sizeMatches(inOutBounds, mTmpBounds)) {
// We're here because either input parameters specified initial bounds, or the suggested
// bounds have the same size of the default freeform size. We should use the suggested
@@ -758,8 +758,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
if (DEBUG) appendLog("freeform-size-orientation-match=" + inOutBounds);
} else {
// Meh, orientation doesn't match. Let's rotate inOutBounds in-place.
- centerBounds(displayArea, inOutBounds.height(), inOutBounds.width(),
- inOutBounds);
+ LaunchParamsUtil.centerBounds(displayArea, inOutBounds.height(),
+ inOutBounds.width(), inOutBounds);
if (DEBUG) appendLog("freeform-orientation-mismatch=" + inOutBounds);
}
} else {
@@ -768,7 +768,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
// to the center of suggested bounds (or the displayArea if no suggested bounds). The
// default size might be too big to center to source activity bounds in displayArea, so
// we may need to move it back to the displayArea.
- centerBounds(displayArea, mTmpBounds.width(), mTmpBounds.height(),
+ LaunchParamsUtil.centerBounds(displayArea, mTmpBounds.width(), mTmpBounds.height(),
inOutBounds);
adjustBoundsToFitInDisplayArea(displayArea, inOutBounds);
if (DEBUG) appendLog("freeform-size-mismatch=" + inOutBounds);
@@ -816,87 +816,6 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
return orientation;
}
- private void getDefaultFreeformSize(@NonNull ActivityInfo info,
- @NonNull TaskDisplayArea displayArea,
- @NonNull ActivityInfo.WindowLayout layout, int orientation, @NonNull Rect bounds) {
- // Default size, which is letterboxing/pillarboxing in displayArea. That's to say the large
- // dimension of default size is the small dimension of displayArea size, and the small
- // dimension of default size is calculated to keep the same aspect ratio as the
- // displayArea's. Here we use stable bounds of displayArea because that indicates the area
- // that isn't occupied by system widgets (e.g. sysbar and navbar).
- final Rect stableBounds = mTmpStableBounds;
- displayArea.getStableRect(stableBounds);
- final int portraitHeight = Math.min(stableBounds.width(), stableBounds.height());
- final int otherDimension = Math.max(stableBounds.width(), stableBounds.height());
- final int portraitWidth = (portraitHeight * portraitHeight) / otherDimension;
- final int defaultWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitHeight
- : portraitWidth;
- final int defaultHeight = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitWidth
- : portraitHeight;
-
- // Get window size based on Nexus 5x screen, we assume that this is enough to show content
- // of activities.
- final float density = (float) displayArea.getConfiguration().densityDpi / DENSITY_DEFAULT;
- final int phonePortraitWidth = (int) (DEFAULT_PORTRAIT_PHONE_WIDTH_DP * density + 0.5f);
- final int phonePortraitHeight = (int) (DEFAULT_PORTRAIT_PHONE_HEIGHT_DP * density + 0.5f);
- final int phoneWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? phonePortraitHeight
- : phonePortraitWidth;
- final int phoneHeight = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? phonePortraitWidth
- : phonePortraitHeight;
-
- // Minimum layout requirements.
- final int layoutMinWidth = (layout == null) ? -1 : layout.minWidth;
- final int layoutMinHeight = (layout == null) ? -1 : layout.minHeight;
-
- // Aspect ratio requirements.
- final float minAspectRatio = info.getMinAspectRatio(orientation);
- final float maxAspectRatio = info.getMaxAspectRatio();
-
- final int width = Math.min(defaultWidth, Math.max(phoneWidth, layoutMinWidth));
- final int height = Math.min(defaultHeight, Math.max(phoneHeight, layoutMinHeight));
- final float aspectRatio = (float) Math.max(width, height) / (float) Math.min(width, height);
-
- // Adjust the width and height to the aspect ratio requirements.
- int adjWidth = width;
- int adjHeight = height;
- if (minAspectRatio >= 1 && aspectRatio < minAspectRatio) {
- // The aspect ratio is below the minimum, adjust it to the minimum.
- if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
- // Fix the width, scale the height.
- adjHeight = (int) (adjWidth / minAspectRatio + 0.5f);
- } else {
- // Fix the height, scale the width.
- adjWidth = (int) (adjHeight / minAspectRatio + 0.5f);
- }
- } else if (maxAspectRatio >= 1 && aspectRatio > maxAspectRatio) {
- // The aspect ratio exceeds the maximum, adjust it to the maximum.
- if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
- // Fix the width, scale the height.
- adjHeight = (int) (adjWidth / maxAspectRatio + 0.5f);
- } else {
- // Fix the height, scale the width.
- adjWidth = (int) (adjHeight / maxAspectRatio + 0.5f);
- }
- }
-
- bounds.set(0, 0, adjWidth, adjHeight);
- bounds.offset(stableBounds.left, stableBounds.top);
- }
-
- /**
- * Gets centered bounds of width x height. If inOutBounds is not empty, the result bounds
- * centers at its center or displayArea's app bounds center if inOutBounds is empty.
- */
- private void centerBounds(@NonNull TaskDisplayArea displayArea, int width, int height,
- @NonNull Rect inOutBounds) {
- if (inOutBounds.isEmpty()) {
- displayArea.getStableRect(inOutBounds);
- }
- final int left = inOutBounds.centerX() - width / 2;
- final int top = inOutBounds.centerY() - height / 2;
- inOutBounds.set(left, top, left + width, top + height);
- }
-
private void adjustBoundsToFitInDisplayArea(@NonNull TaskDisplayArea displayArea,
@NonNull Rect inOutBounds) {
final Rect stableBounds = mTmpStableBounds;
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 91f69a55d400..31d8eb8eea17 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1149,6 +1149,26 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
return false;
}
+ private static boolean isTranslucent(@NonNull WindowContainer wc) {
+ final TaskFragment taskFragment = wc.asTaskFragment();
+ if (taskFragment != null) {
+ if (taskFragment.isTranslucent(null /* starting */)) {
+ return true;
+ }
+ final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
+ if (adjacentTaskFragment != null) {
+ // Treat the TaskFragment as translucent if its adjacent TF is, otherwise everything
+ // behind two adjacent TaskFragments are occluded.
+ return adjacentTaskFragment.isTranslucent(null /* starting */);
+ }
+ }
+ // TODO(b/172695805): hierarchical check. This is non-trivial because for containers
+ // it is effected by child visibility but needs to work even
+ // before visibility is committed. This means refactoring some
+ // checks to use requested visibility.
+ return !wc.fillsParent();
+ }
+
/**
* Under some conditions (eg. all visible targets within a parent container are transitioning
* the same way) the transition can be "promoted" to the parent container. This means an
@@ -1701,20 +1721,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
if (mShowWallpaper || wc.showWallpaper()) {
flags |= FLAG_SHOW_WALLPAPER;
}
- if (!wc.fillsParent()) {
- // TODO(b/172695805): hierarchical check. This is non-trivial because for containers
- // it is effected by child visibility but needs to work even
- // before visibility is committed. This means refactoring some
- // checks to use requested visibility.
+ if (isTranslucent(wc)) {
flags |= FLAG_TRANSLUCENT;
}
final Task task = wc.asTask();
if (task != null && task.voiceSession != null) {
flags |= FLAG_IS_VOICE_INTERACTION;
}
- if (task != null && task.isTranslucent(null)) {
- flags |= FLAG_TRANSLUCENT;
- }
final ActivityRecord record = wc.asActivityRecord();
if (record != null) {
if (record.mUseTransferredAnimation) {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index ee6435493699..0f5655c74f31 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -21,6 +21,7 @@ import static android.app.ActivityManager.isStartResultSuccessful;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
@@ -764,7 +765,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
bottomActivity)) {
Slog.w(TAG, "Skip removing TaskFragment due in lock task mode.");
sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
- new IllegalStateException(
+ taskFragment, type, new IllegalStateException(
"Not allow to delete task fragment in lock task mode."));
break;
}
@@ -778,13 +779,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (tf == null) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to operate with invalid fragment token");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
+ exception);
break;
}
if (tf.isEmbeddedTaskFragmentInPip()) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to start activity in PIP TaskFragment");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
+ exception);
break;
}
final Intent activityIntent = hop.getActivityIntent();
@@ -794,7 +797,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
hop.getCallingActivity(), caller.mUid, caller.mPid,
errorCallbackToken);
if (!isStartResultSuccessful(result)) {
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
convertStartFailureToThrowable(result, activityIntent));
} else {
effects |= TRANSACT_EFFECTS_LIFECYCLE;
@@ -815,28 +818,34 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (parent == null || activity == null) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to operate with invalid fragment token or activity.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
+ exception);
break;
}
if (parent.isEmbeddedTaskFragmentInPip()) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to reparent activity to PIP TaskFragment");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
+ exception);
break;
}
if (parent.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) {
final Throwable exception = new SecurityException(
"The task fragment is not allowed to embed the given activity.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
+ exception);
break;
}
if (parent.getTask() != activity.getTask()) {
final Throwable exception = new SecurityException("The reparented activity is"
+ " not in the same Task as the target TaskFragment.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
+ exception);
break;
}
+ prepareActivityEmbeddingTransitionForReparentActivityToTaskFragment(parent,
+ activity);
activity.reparent(parent, POSITION_TOP);
effects |= TRANSACT_EFFECTS_LIFECYCLE;
break;
@@ -851,14 +860,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (tf1 == null || (adjacentFragmentToken != null && tf2 == null)) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to set adjacent on invalid fragment tokens");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf1, type,
+ exception);
break;
}
if (tf1.isEmbeddedTaskFragmentInPip()
|| (tf2 != null && tf2.isEmbeddedTaskFragmentInPip())) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to set adjacent on TaskFragment in PIP Task");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf1, type,
+ exception);
break;
}
tf1.setAdjacentTaskFragment(tf2);
@@ -1061,6 +1072,41 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
return effects;
}
+ private void prepareActivityEmbeddingTransitionForReparentActivityToTaskFragment(
+ @NonNull TaskFragment taskFragment, @NonNull ActivityRecord activity) {
+ if (!taskFragment.canHaveEmbeddingActivityTransition(activity)) {
+ return;
+ }
+
+ // The reparent can happen in the following cases:
+ // 1. Reparent an existing activity to split when app launches new intent.
+ // - This happens after app calls to start activity, but before the activity is actually
+ // started, so we don't expect any collecting transition, but if it does, we can't
+ // queue the WCT because the start activity won't wait.
+ // 2. Reparent an existing activity to split to launch placeholder when Task size changed.
+ // - We expect to have a collecting transition for the Task resize, so just collect.
+ // 3. Reparent a new launching activity to an always-expand container.
+ // 4. Reparent a new launching activity to split to launch placeholder together.
+ // 5. Reparent a new launching activity to an existing split.
+ // - The new launching activity should have start an OPEN transition, so just collect.
+ // 6. Reparent PiP activity back to the original Task.
+ // - This should be part of the exiting PiP transition, so just collect.
+
+ if (!taskFragment.getBounds().equals(activity.getBounds()) && activity.isVisible()
+ && !mTransitionController.isCollecting()) {
+ // 1. Reparent an existing activity to split when app launches new intent.
+ mTransitionController.requestTransitionIfNeeded(TRANSIT_CHANGE, activity);
+ }
+
+ // We expect the activity to be in the transition already, so just collect the TaskFragment.
+ if (mTransitionController.isCollecting(activity)) {
+ taskFragment.collectEmbeddedTaskFragmentIfNeeded();
+ } else {
+ ProtoLog.w(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Reparenting Activity"
+ + " to embedded TaskFragment, but the Activity is not collected");
+ }
+ }
+
/** A helper method to send minimum dimension violation error to the client. */
private void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions,
IBinder errorCallbackToken, String reason) {
@@ -1071,7 +1117,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
+ taskFragment.getBounds() + " does not satisfy minimum dimensions:"
+ minDimensions + " " + reason);
sendTaskFragmentOperationFailure(taskFragment.getTaskFragmentOrganizer(),
- errorCallbackToken, exception);
+ errorCallbackToken, taskFragment, -1 /* opType */, exception);
}
/**
@@ -1624,13 +1670,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (ownerActivity == null || ownerActivity.getTask() == null) {
final Throwable exception =
new IllegalArgumentException("Not allowed to operate with invalid ownerToken");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
+ HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
if (!ownerActivity.isResizeable()) {
final IllegalArgumentException exception = new IllegalArgumentException("Not allowed"
+ " to operate with non-resizable owner Activity");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
+ HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
// The ownerActivity has to belong to the same app as the target Task.
@@ -1640,13 +1688,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
final Throwable exception =
new SecurityException("Not allowed to operate with the ownerToken while "
+ "the root activity of the target task belong to the different app");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
+ HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
if (ownerTask.inPinnedWindowingMode()) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to create TaskFragment in PIP Task");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
+ HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
final TaskFragment taskFragment = new TaskFragment(mService,
@@ -1674,7 +1724,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (newParentTF == null) {
final Throwable exception =
new IllegalArgumentException("Not allowed to operate with invalid container");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
+ HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
return;
}
if (newParentTF.getTaskFragmentOrganizer() != null) {
@@ -1685,20 +1736,23 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (isEmbeddingDisallowed) {
final Throwable exception = new SecurityException(
"The new parent is not allowed to embed the activities.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
+ HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
return;
}
}
if (newParentTF.isEmbeddedTaskFragmentInPip() || oldParent.isEmbeddedTaskFragmentInPip()) {
final Throwable exception = new SecurityException(
"Not allow to reparent in TaskFragment in PIP Task.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
+ HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
return;
}
if (newParentTF.getTask() != oldParent.getTask()) {
final Throwable exception = new SecurityException(
"The new parent is not in the same Task as the old parent.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
+ HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
return;
}
while (oldParent.hasChild()) {
@@ -1713,7 +1767,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
final Throwable exception =
new IllegalArgumentException("Not allowed to operate with invalid "
+ "taskFragment");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
return 0;
}
if (taskFragment.isEmbeddedTaskFragmentInPip()
@@ -1722,7 +1777,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
&& taskFragment.getTopNonFinishingActivity() != null) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to delete TaskFragment in PIP Task");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
return 0;
}
mLaunchTaskFragments.removeAt(index);
@@ -1750,12 +1806,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
}
void sendTaskFragmentOperationFailure(@NonNull ITaskFragmentOrganizer organizer,
- @Nullable IBinder errorCallbackToken, @NonNull Throwable exception) {
+ @Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment, int opType,
+ @NonNull Throwable exception) {
if (organizer == null) {
throw new IllegalArgumentException("Not allowed to operate with invalid organizer");
}
mService.mTaskFragmentOrganizerController
- .onTaskFragmentError(organizer, errorCallbackToken, exception);
+ .onTaskFragmentError(organizer, errorCallbackToken, taskFragment, opType,
+ exception);
}
private Throwable convertStartFailureToThrowable(int result, Intent intent) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 658b6acbc16d..366ca3b25130 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -137,7 +137,6 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITIO
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
-import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainerChildProto.WINDOW;
@@ -2448,8 +2447,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
final DisplayContent dc = getDisplayContent();
if (isImeLayeringTarget()) {
- // Remove the IME screenshot surface if the layering target is not animating.
- dc.removeImeScreenshotIfPossible();
+ // Remove the attached IME screenshot surface.
+ dc.removeImeSurfaceByTarget(this);
// Make sure to set mImeLayeringTarget as null when the removed window is the
// IME target, in case computeImeTarget may use the outdated target.
dc.setImeLayeringTarget(null);
@@ -3583,6 +3582,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
} else {
logExclusionRestrictions(EXCLUSION_LEFT);
logExclusionRestrictions(EXCLUSION_RIGHT);
+ getDisplayContent().removeImeSurfaceByTarget(this);
}
// Exclude toast because legacy apps may show toast window by themselves, so the misused
// apps won't always be considered as foreground state.
@@ -4956,10 +4956,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|| isAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION);
}
- boolean isExitAnimationRunningSelfOrChild() {
- return isAnimating(CHILDREN, ANIMATION_TYPE_WINDOW_ANIMATION);
- }
-
private boolean shouldFinishAnimatingExit() {
// Exit animation might be applied soon.
if (inTransition()) {
@@ -5915,6 +5911,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (!super.prepareSync()) {
return false;
}
+ if (mIsWallpaper) {
+ // TODO(b/233286785): Add sync support to wallpaper.
+ return false;
+ }
// In the WindowContainer implementation we immediately mark ready
// since a generic WindowContainer only needs to wait for its
// children to finish and is immediately ready from its own
diff --git a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
index cdb6324988be..e44ce3c43370 100644
--- a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
+++ b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
@@ -34,4 +34,5 @@ android_test {
],
platform_apis: true,
test_suites: ["device-tests"],
+ data: [":AppEnumerationSyncProviderTestApp"],
}
diff --git a/services/tests/PackageManagerServiceTests/appenumeration/AndroidTest.xml b/services/tests/PackageManagerServiceTests/appenumeration/AndroidTest.xml
index f48974a3b8e0..cca8ec7c374f 100644
--- a/services/tests/PackageManagerServiceTests/appenumeration/AndroidTest.xml
+++ b/services/tests/PackageManagerServiceTests/appenumeration/AndroidTest.xml
@@ -30,7 +30,7 @@
</target_preparer>
<!-- Load additional APKs onto device -->
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="push" value="AppEnumerationSyncProviderTestApp.apk->/data/local/tmp/appenumerationtests/AppEnumerationSyncProviderTestApp.apk" />
<option name="push" value="AppEnumerationHasAppOpPermissionTestApp.apk->/data/local/tmp/appenumerationtests/AppEnumerationHasAppOpPermissionTestApp.apk" />
<option name="push" value="AppEnumerationSharedUserTestApp.apk->/data/local/tmp/appenumerationtests/AppEnumerationSharedUserTestApp.apk" />
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
index 721777ca6b38..13510adbb960 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
@@ -30,6 +30,7 @@ import android.content.pm.PackageInfo;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArrayMap;
+import android.util.SparseLongArray;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -174,10 +175,13 @@ public class ScribeTest {
when(mIrs.getConsumptionLimitLocked()).thenReturn(consumptionLimit);
Ledger ledger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
- ledger.recordTransaction(new Ledger.Transaction(0, 1000L, 1, null, 2000, 0));
+ ledger.recordTransaction(
+ new Ledger.Transaction(0, 1000L, EconomicPolicy.TYPE_REWARD | 1, null, 2000, 0));
// Negative ledger balance shouldn't affect the total circulation value.
ledger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID + 1, TEST_PACKAGE);
- ledger.recordTransaction(new Ledger.Transaction(0, 1000L, 1, null, -5000, 3000));
+ ledger.recordTransaction(
+ new Ledger.Transaction(0, 1000L,
+ EconomicPolicy.TYPE_ACTION | 1, null, -5000, 3000));
mScribeUnderTest.setLastReclamationTimeLocked(lastReclamationTime);
mScribeUnderTest.setConsumptionLimitLocked(consumptionLimit);
mScribeUnderTest.adjustRemainingConsumableCakesLocked(
@@ -209,9 +213,13 @@ public class ScribeTest {
@Test
public void testWritingPopulatedLedgerToDisk() {
final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
- ogLedger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 51, 0));
- ogLedger.recordTransaction(new Ledger.Transaction(1500, 2000, 2, "green", 52, -1));
- ogLedger.recordTransaction(new Ledger.Transaction(2500, 3000, 3, "blue", 3, 12));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REWARD | 1, null, 51, 0));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(1500, 2000,
+ EconomicPolicy.TYPE_REWARD | 2, "green", 52, -1));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(2500, 3000, EconomicPolicy.TYPE_REWARD | 3, "blue", 3, 12));
mScribeUnderTest.writeImmediatelyForTesting();
mScribeUnderTest.loadFromDiskLocked();
@@ -230,11 +238,13 @@ public class ScribeTest {
addInstalledPackage(userId, pkgName);
final Ledger ledger = mScribeUnderTest.getLedgerLocked(userId, pkgName);
ledger.recordTransaction(new Ledger.Transaction(
- 0, 1000L * u + l, 1, null, -51L * u + l, 50));
+ 0, 1000L * u + l, EconomicPolicy.TYPE_ACTION | 1, null, -51L * u + l, 50));
ledger.recordTransaction(new Ledger.Transaction(
- 1500L * u + l, 2000L * u + l, 2 * u + l, "green" + u + l, 52L * u + l, 0));
+ 1500L * u + l, 2000L * u + l,
+ EconomicPolicy.TYPE_REWARD | 2 * u + l, "green" + u + l, 52L * u + l, 0));
ledger.recordTransaction(new Ledger.Transaction(
- 2500L * u + l, 3000L * u + l, 3 * u + l, "blue" + u + l, 3L * u + l, 0));
+ 2500L * u + l, 3000L * u + l,
+ EconomicPolicy.TYPE_REWARD | 3 * u + l, "blue" + u + l, 3L * u + l, 0));
ledgers.add(userId, pkgName, ledger);
}
}
@@ -248,9 +258,12 @@ public class ScribeTest {
@Test
public void testDiscardLedgerFromDisk() {
final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
- ogLedger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 51, 1));
- ogLedger.recordTransaction(new Ledger.Transaction(1500, 2000, 2, "green", 52, 0));
- ogLedger.recordTransaction(new Ledger.Transaction(2500, 3000, 3, "blue", 3, 1));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REWARD | 1, null, 51, 1));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(1500, 2000, EconomicPolicy.TYPE_REWARD | 2, "green", 52, 0));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(2500, 3000, EconomicPolicy.TYPE_REWARD | 3, "blue", 3, 1));
mScribeUnderTest.writeImmediatelyForTesting();
mScribeUnderTest.loadFromDiskLocked();
@@ -269,9 +282,12 @@ public class ScribeTest {
public void testLoadingMissingPackageFromDisk() {
final String pkgName = TEST_PACKAGE + ".uninstalled";
final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, pkgName);
- ogLedger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 51, 1));
- ogLedger.recordTransaction(new Ledger.Transaction(1500, 2000, 2, "green", 52, 2));
- ogLedger.recordTransaction(new Ledger.Transaction(2500, 3000, 3, "blue", 3, 3));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REGULATION | 1, null, 51, 1));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(1500, 2000, EconomicPolicy.TYPE_REWARD | 2, "green", 52, 2));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(2500, 3000, EconomicPolicy.TYPE_ACTION | 3, "blue", -3, 3));
mScribeUnderTest.writeImmediatelyForTesting();
// Package isn't installed, so make sure it's not saved to memory after loading.
@@ -283,9 +299,13 @@ public class ScribeTest {
public void testLoadingMissingUserFromDisk() {
final int userId = TEST_USER_ID + 1;
final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(userId, TEST_PACKAGE);
- ogLedger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 51, 0));
- ogLedger.recordTransaction(new Ledger.Transaction(1500, 2000, 2, "green", 52, 1));
- ogLedger.recordTransaction(new Ledger.Transaction(2500, 3000, 3, "blue", 3, 3));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REWARD | 1, null, 51, 0));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(1500, 2000, EconomicPolicy.TYPE_REWARD | 2, "green", 52, 1));
+ ogLedger.recordTransaction(
+ new Ledger.Transaction(2500, 3000,
+ EconomicPolicy.TYPE_REGULATION | 3, "blue", 3, 3));
mScribeUnderTest.writeImmediatelyForTesting();
// User doesn't show up with any packages, so make sure nothing is saved after loading.
@@ -331,12 +351,34 @@ public class ScribeTest {
}
assertNotNull(actual);
assertEquals(expected.getCurrentBalance(), actual.getCurrentBalance());
+
List<Ledger.Transaction> expectedTransactions = expected.getTransactions();
List<Ledger.Transaction> actualTransactions = actual.getTransactions();
assertEquals(expectedTransactions.size(), actualTransactions.size());
for (int i = 0; i < expectedTransactions.size(); ++i) {
assertTransactionsEqual(expectedTransactions.get(i), actualTransactions.get(i));
}
+
+ List<Ledger.RewardBucket> expectedRewardBuckets = expected.getRewardBuckets();
+ List<Ledger.RewardBucket> actualRewardBuckets = actual.getRewardBuckets();
+ assertEquals(expectedRewardBuckets.size(), actualRewardBuckets.size());
+ for (int i = 0; i < expectedRewardBuckets.size(); ++i) {
+ assertRewardBucketsEqual(expectedRewardBuckets.get(i), actualRewardBuckets.get(i));
+ }
+ }
+
+ private void assertSparseLongArraysEqual(SparseLongArray expected, SparseLongArray actual) {
+ if (expected == null) {
+ assertNull(actual);
+ return;
+ }
+ assertNotNull(actual);
+ final int size = expected.size();
+ assertEquals(size, actual.size());
+ for (int i = 0; i < size; ++i) {
+ assertEquals(expected.keyAt(i), actual.keyAt(i));
+ assertEquals(expected.valueAt(i), actual.valueAt(i));
+ }
}
private void assertReportListsEqual(List<Analyst.Report> expected,
@@ -382,6 +424,17 @@ public class ScribeTest {
}
}
+ private void assertRewardBucketsEqual(Ledger.RewardBucket expected,
+ Ledger.RewardBucket actual) {
+ if (expected == null) {
+ assertNull(actual);
+ return;
+ }
+ assertNotNull(actual);
+ assertEquals(expected.startTimeMs, actual.startTimeMs);
+ assertSparseLongArraysEqual(expected.cumulativeDelta, actual.cumulativeDelta);
+ }
+
private void assertTransactionsEqual(Ledger.Transaction expected, Ledger.Transaction actual) {
if (expected == null) {
assertNull(actual);
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java
new file mode 100644
index 000000000000..e305957c6290
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.display.brightness;
+
+import static org.junit.Assert.assertEquals;
+
+import android.hardware.display.BrightnessInfo;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public final class BrightnessEventTest {
+ private BrightnessEvent mBrightnessEvent;
+
+ @Before
+ public void setUp() {
+ mBrightnessEvent = new BrightnessEvent(1);
+ mBrightnessEvent.setReason(
+ getReason(BrightnessReason.REASON_DOZE, BrightnessReason.MODIFIER_LOW_POWER));
+ mBrightnessEvent.setLux(100.0f);
+ mBrightnessEvent.setPreThresholdLux(150.0f);
+ mBrightnessEvent.setTime(System.currentTimeMillis());
+ mBrightnessEvent.setBrightness(0.6f);
+ mBrightnessEvent.setRecommendedBrightness(0.6f);
+ mBrightnessEvent.setHbmMax(0.62f);
+ mBrightnessEvent.setThermalMax(0.65f);
+ mBrightnessEvent.setHbmMode(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
+ mBrightnessEvent.setFlags(0);
+ mBrightnessEvent.setAdjustmentFlags(0);
+ }
+
+ @Test
+ public void testEqualsMainDataComparesAllFieldsExceptTime() {
+ BrightnessEvent secondBrightnessEvent = new BrightnessEvent(1);
+ secondBrightnessEvent.copyFrom(mBrightnessEvent);
+ secondBrightnessEvent.setTime(0);
+ assertEquals(secondBrightnessEvent.equalsMainData(mBrightnessEvent), true);
+ }
+
+ @Test
+ public void testToStringWorksAsExpected() {
+ String actualString = mBrightnessEvent.toString(false);
+ String expectedString =
+ "BrightnessEvent: disp=1, brt=0.6, rcmdBrt=0.6, preBrt=NaN, lux=100.0, preLux=150"
+ + ".0, hbmMax=0.62, hbmMode=off, thrmMax=0.65, flags=, reason=doze [ "
+ + "low_pwr ]";
+ assertEquals(actualString, expectedString);
+ }
+
+ private BrightnessReason getReason(int reason, int modifier) {
+ BrightnessReason brightnessReason = new BrightnessReason();
+ brightnessReason.setReason(reason);
+ brightnessReason.setModifier(modifier);
+ return brightnessReason;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java
new file mode 100644
index 000000000000..ffc2e0dfe26c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.display.brightness;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public final class BrightnessReasonTest {
+ private BrightnessReason mBrightnessReason;
+
+ @Before
+ public void setUp() {
+ mBrightnessReason = getReason(BrightnessReason.REASON_DOZE,
+ BrightnessReason.MODIFIER_LOW_POWER);
+ }
+
+ @Test
+ public void setSetsAppropriateValues() {
+ mBrightnessReason.set(null);
+ assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_UNKNOWN);
+ assertEquals(mBrightnessReason.getModifier(), 0);
+
+ mBrightnessReason.set(
+ getReason(BrightnessReason.REASON_BOOST, BrightnessReason.MODIFIER_THROTTLED));
+ assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_BOOST);
+ assertEquals(mBrightnessReason.getModifier(), BrightnessReason.MODIFIER_THROTTLED);
+ }
+
+ @Test
+ public void toStringGeneratesExpectedString() {
+ String actualString = mBrightnessReason.toString();
+ String expectedString = "doze [ low_pwr ]";
+ assertEquals(actualString, expectedString);
+ }
+
+ @Test
+ public void setModifierDoesntSetIfModifierIsBeyondExtremes() {
+ int extremeModifier = 0x16;
+ mBrightnessReason.setModifier(extremeModifier);
+ assertEquals(mBrightnessReason.getModifier(), BrightnessReason.MODIFIER_LOW_POWER);
+ }
+
+ @Test
+ public void setReasonDoesntSetIfModifierIsBeyondExtremes() {
+ int extremeReason = 10;
+ mBrightnessReason.setReason(extremeReason);
+ assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_DOZE);
+
+ extremeReason = -1;
+ mBrightnessReason.setReason(extremeReason);
+ assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_DOZE);
+ }
+
+ @Test
+ public void addModifierWorksAsExpected() {
+ mBrightnessReason.addModifier(BrightnessReason.REASON_BOOST);
+ assertEquals(mBrightnessReason.getModifier(),
+ BrightnessReason.REASON_DOZE | BrightnessReason.REASON_BOOST);
+ }
+
+ private BrightnessReason getReason(int reason, int modifier) {
+ BrightnessReason brightnessReason = new BrightnessReason();
+ brightnessReason.setReason(reason);
+ brightnessReason.setModifier(modifier);
+ return brightnessReason;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
index 5a3f12c5b4ed..0bb20215111b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
@@ -47,7 +47,7 @@ public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>();
@Override
- protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
+ protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] protectorSecret) {
if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) {
throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName);
}
@@ -59,11 +59,11 @@ public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
byte[] data = new byte[len];
buffer.get(data);
len = buffer.getInt();
- byte[] appId = new byte[len];
- buffer.get(appId);
+ byte[] storedProtectorSecret = new byte[len];
+ buffer.get(storedProtectorSecret);
long sid = buffer.getLong();
- if (!Arrays.equals(appId, applicationId)) {
- throw new AssertionFailedError("Invalid application id");
+ if (!Arrays.equals(storedProtectorSecret, protectorSecret)) {
+ throw new AssertionFailedError("Invalid protector secret");
}
if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) {
throw new AssertionFailedError("No valid auth token");
@@ -72,13 +72,14 @@ public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
}
@Override
- protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
+ protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] protectorSecret,
+ long sid) {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES
- + applicationId.length + Long.BYTES);
+ + protectorSecret.length + Long.BYTES);
buffer.putInt(data.length);
buffer.put(data);
- buffer.putInt(applicationId.length);
- buffer.put(applicationId);
+ buffer.putInt(protectorSecret.length);
+ buffer.put(protectorSecret);
buffer.putLong(sid);
byte[] result = buffer.array();
mBlobs.put(blobKeyName, result);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 6d1df2c2f2bf..87beece5b414 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -19,7 +19,7 @@ package com.android.server.locksettings;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
+import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -45,8 +45,8 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
import com.android.server.locksettings.SyntheticPasswordManager.PasswordData;
+import com.android.server.locksettings.SyntheticPasswordManager.SyntheticPassword;
import org.junit.Before;
import org.junit.Test;
@@ -74,28 +74,28 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
}
@Test
- public void testPasswordBasedSyntheticPassword() throws RemoteException {
+ public void testLskfBasedProtector() throws RemoteException {
final int USER_ID = 10;
final LockscreenCredential password = newPassword("user-password");
final LockscreenCredential badPassword = newPassword("bad-password");
MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mContext, mStorage,
mGateKeeperService, mUserManager, mPasswordSlotManager);
- AuthenticationToken authToken = manager.newSyntheticPassword(USER_ID);
- long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService,
- password, authToken, USER_ID);
+ SyntheticPassword sp = manager.newSyntheticPassword(USER_ID);
+ long protectorId = manager.createLskfBasedProtector(mGateKeeperService, password, sp,
+ USER_ID);
- AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(
- mGateKeeperService, handle, password, USER_ID, null);
- assertArrayEquals(result.authToken.deriveKeyStorePassword(),
- authToken.deriveKeyStorePassword());
+ AuthenticationResult result = manager.unlockLskfBasedProtector(mGateKeeperService,
+ protectorId, password, USER_ID, null);
+ assertArrayEquals(result.syntheticPassword.deriveKeyStorePassword(),
+ sp.deriveKeyStorePassword());
- result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle,
- badPassword, USER_ID, null);
- assertNull(result.authToken);
+ result = manager.unlockLskfBasedProtector(mGateKeeperService, protectorId, badPassword,
+ USER_ID, null);
+ assertNull(result.syntheticPassword);
}
private boolean hasSyntheticPassword(int userId) throws RemoteException {
- return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
+ return mService.getLong(CURRENT_LSKF_BASED_PROTECTOR_ID_KEY, 0, userId) != 0;
}
private void initializeCredential(LockscreenCredential password, int userId)
@@ -544,12 +544,12 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
}
private void assertNoOrphanedFilesLeft(int userId) {
- String handleString = String.format("%016x",
- mService.getSyntheticPasswordHandleLocked(userId));
+ String lskfProtectorPrefix = String.format("%016x",
+ mService.getCurrentLskfBasedProtectorId(userId));
File directory = mStorage.getSyntheticPasswordDirectoryForUser(userId);
for (File file : directory.listFiles()) {
String[] parts = file.getName().split("\\.");
- if (!parts[0].equals(handleString) && !parts[0].equals("0000000000000000")) {
+ if (!parts[0].equals(lskfProtectorPrefix) && !parts[0].equals("0000000000000000")) {
fail("Orphaned state left: " + file.getName());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index 20482afd53ac..503ca69a627f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -36,8 +36,6 @@ import android.apex.ApexSessionInfo;
import android.apex.ApexSessionParams;
import android.apex.IApexService;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.os.Environment;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -93,16 +91,16 @@ public class ApexManagerTest {
ApexPackageInfo apexPackageInfo = new ApexPackageInfo();
apexPackageInfo.scanApexPackages(
apexInfo, mPackageParser2, ParallelPackageParser.makeExecutorService());
- final PackageInfo activePkgPi = apexPackageInfo.getPackageInfo(TEST_APEX_PKG,
+ final var activePair = apexPackageInfo.getPackageInfo(TEST_APEX_PKG,
ApexManager.MATCH_ACTIVE_PACKAGE);
- assertThat(activePkgPi).isNotNull();
- assertThat(activePkgPi.packageName).contains(TEST_APEX_PKG);
+ assertThat(activePair).isNotNull();
+ assertThat(activePair.second.getPackageName()).contains(TEST_APEX_PKG);
- final PackageInfo factoryPkgPi = apexPackageInfo.getPackageInfo(TEST_APEX_PKG,
+ final var factoryPair = apexPackageInfo.getPackageInfo(TEST_APEX_PKG,
ApexManager.MATCH_FACTORY_PACKAGE);
- assertThat(factoryPkgPi).isNull();
+ assertThat(factoryPair).isNull();
}
@Test
@@ -111,16 +109,16 @@ public class ApexManagerTest {
ApexPackageInfo apexPackageInfo = new ApexPackageInfo();
apexPackageInfo.scanApexPackages(
apexInfo, mPackageParser2, ParallelPackageParser.makeExecutorService());
- PackageInfo factoryPkgPi = apexPackageInfo.getPackageInfo(TEST_APEX_PKG,
+ var factoryPair = apexPackageInfo.getPackageInfo(TEST_APEX_PKG,
ApexManager.MATCH_FACTORY_PACKAGE);
- assertThat(factoryPkgPi).isNotNull();
- assertThat(factoryPkgPi.packageName).contains(TEST_APEX_PKG);
+ assertThat(factoryPair).isNotNull();
+ assertThat(factoryPair.second.getPackageName()).contains(TEST_APEX_PKG);
- final PackageInfo activePkgPi = apexPackageInfo.getPackageInfo(TEST_APEX_PKG,
+ final var activePair = apexPackageInfo.getPackageInfo(TEST_APEX_PKG,
ApexManager.MATCH_ACTIVE_PACKAGE);
- assertThat(activePkgPi).isNull();
+ assertThat(activePair).isNull();
}
@Test
@@ -388,23 +386,16 @@ public class ApexManagerTest {
newApexInfo = mApexManager.installPackage(installedApex);
apexPackageInfo.notifyPackageInstalled(newApexInfo, mPackageParser2);
- PackageInfo newInfo = apexPackageInfo.getPackageInfo("test.apex.rebootless",
+ var newInfo = apexPackageInfo.getPackageInfo("test.apex.rebootless",
ApexManager.MATCH_ACTIVE_PACKAGE);
- assertThat(newInfo.applicationInfo.sourceDir).isEqualTo(finalApex.getAbsolutePath());
- assertThat(newInfo.applicationInfo.longVersionCode).isEqualTo(2);
- assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)
- .isEqualTo(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
- assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
- .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
-
- PackageInfo factoryInfo = apexPackageInfo.getPackageInfo("test.apex.rebootless",
+ assertThat(newInfo.second.getBaseApkPath()).isEqualTo(finalApex.getAbsolutePath());
+ assertThat(newInfo.second.getLongVersionCode()).isEqualTo(2);
+
+ var factoryInfo = apexPackageInfo.getPackageInfo("test.apex.rebootless",
ApexManager.MATCH_FACTORY_PACKAGE);
- assertThat(factoryInfo.applicationInfo.sourceDir).isEqualTo(activeApexInfo.modulePath);
- assertThat(factoryInfo.applicationInfo.longVersionCode).isEqualTo(1);
- assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
- .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
- assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
- .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(factoryInfo.second.getBaseApkPath()).isEqualTo(activeApexInfo.modulePath);
+ assertThat(factoryInfo.second.getLongVersionCode()).isEqualTo(1);
+ assertThat(factoryInfo.second.isSystem()).isTrue();
}
@Test
@@ -429,23 +420,16 @@ public class ApexManagerTest {
newApexInfo = mApexManager.installPackage(installedApex);
apexPackageInfo.notifyPackageInstalled(newApexInfo, mPackageParser2);
- PackageInfo newInfo = apexPackageInfo.getPackageInfo("test.apex.rebootless",
+ var newInfo = apexPackageInfo.getPackageInfo("test.apex.rebootless",
ApexManager.MATCH_ACTIVE_PACKAGE);
- assertThat(newInfo.applicationInfo.sourceDir).isEqualTo(finalApex.getAbsolutePath());
- assertThat(newInfo.applicationInfo.longVersionCode).isEqualTo(2);
- assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)
- .isEqualTo(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
- assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
- .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
-
- PackageInfo factoryInfo = apexPackageInfo.getPackageInfo("test.apex.rebootless",
+ assertThat(newInfo.second.getBaseApkPath()).isEqualTo(finalApex.getAbsolutePath());
+ assertThat(newInfo.second.getLongVersionCode()).isEqualTo(2);
+
+ var factoryInfo = apexPackageInfo.getPackageInfo("test.apex.rebootless",
ApexManager.MATCH_FACTORY_PACKAGE);
- assertThat(factoryInfo.applicationInfo.sourceDir).isEqualTo(factoryApexInfo.modulePath);
- assertThat(factoryInfo.applicationInfo.longVersionCode).isEqualTo(1);
- assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
- .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
- assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
- .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(factoryInfo.second.getBaseApkPath()).isEqualTo(factoryApexInfo.modulePath);
+ assertThat(factoryInfo.second.getLongVersionCode()).isEqualTo(1);
+ assertThat(factoryInfo.second.isSystem()).isTrue();
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java b/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java
index 22dcf842906c..54566c39a8d2 100644
--- a/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java
+++ b/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java
@@ -22,7 +22,12 @@ import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.util.SparseLongArray;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -32,7 +37,10 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.Clock;
+import java.time.Duration;
import java.time.ZoneOffset;
+import java.util.ArrayList;
+import java.util.List;
/** Test that the ledger records transactions correctly. */
@RunWith(AndroidJUnit4.class)
@@ -44,6 +52,11 @@ public class LedgerTest {
TareUtils.sSystemClock = Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
}
+ private void shiftSystemTime(long incrementMs) {
+ TareUtils.sSystemClock =
+ Clock.offset(TareUtils.sSystemClock, Duration.ofMillis(incrementMs));
+ }
+
@Test
public void testInitialState() {
final Ledger ledger = new Ledger();
@@ -52,37 +65,149 @@ public class LedgerTest {
}
@Test
+ public void testInitialization_FullLists() {
+ final long balance = 1234567890L;
+ List<Ledger.Transaction> transactions = new ArrayList<>();
+ List<Ledger.RewardBucket> rewardBuckets = new ArrayList<>();
+
+ final long now = getCurrentTimeMillis();
+ Ledger.Transaction secondTxn = null;
+ Ledger.RewardBucket remainingBucket = null;
+ for (int i = 0; i < Ledger.MAX_TRANSACTION_COUNT; ++i) {
+ final long start = now - 10 * HOUR_IN_MILLIS + i * MINUTE_IN_MILLIS;
+ Ledger.Transaction transaction = new Ledger.Transaction(
+ start, start + MINUTE_IN_MILLIS, 1, null, 400, 0);
+ if (i == 1) {
+ secondTxn = transaction;
+ }
+ transactions.add(transaction);
+ }
+ for (int b = 0; b < Ledger.NUM_REWARD_BUCKET_WINDOWS; ++b) {
+ final long start = now - (Ledger.NUM_REWARD_BUCKET_WINDOWS - b) * 24 * HOUR_IN_MILLIS;
+ Ledger.RewardBucket rewardBucket = new Ledger.RewardBucket();
+ rewardBucket.startTimeMs = start;
+ for (int r = 0; r < 5; ++r) {
+ rewardBucket.cumulativeDelta.put(EconomicPolicy.TYPE_REWARD | r, b * start + r);
+ }
+ if (b == Ledger.NUM_REWARD_BUCKET_WINDOWS - 1) {
+ remainingBucket = rewardBucket;
+ }
+ rewardBuckets.add(rewardBucket);
+ }
+ final Ledger ledger = new Ledger(balance, transactions, rewardBuckets);
+ assertEquals(balance, ledger.getCurrentBalance());
+ assertEquals(transactions, ledger.getTransactions());
+ // Everything but the last bucket is old, so the returned list should only contain that
+ // bucket.
+ rewardBuckets.clear();
+ rewardBuckets.add(remainingBucket);
+ assertEquals(rewardBuckets, ledger.getRewardBuckets());
+
+ // Make sure the ledger can properly record new transactions.
+ final long start = now - MINUTE_IN_MILLIS;
+ final long delta = 400;
+ final Ledger.Transaction transaction = new Ledger.Transaction(
+ start, start + MINUTE_IN_MILLIS, EconomicPolicy.TYPE_REWARD | 1, null, delta, 0);
+ ledger.recordTransaction(transaction);
+ assertEquals(balance + delta, ledger.getCurrentBalance());
+ transactions = ledger.getTransactions();
+ assertEquals(secondTxn, transactions.get(0));
+ assertEquals(transaction, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 1));
+ final Ledger.RewardBucket rewardBucket = new Ledger.RewardBucket();
+ rewardBucket.startTimeMs = now;
+ rewardBucket.cumulativeDelta.put(EconomicPolicy.TYPE_REWARD | 1, delta);
+ rewardBuckets = ledger.getRewardBuckets();
+ assertRewardBucketsEqual(remainingBucket, rewardBuckets.get(0));
+ assertRewardBucketsEqual(rewardBucket, rewardBuckets.get(1));
+ }
+
+ @Test
+ public void testInitialization_OverflowingLists() {
+ final long balance = 1234567890L;
+ final List<Ledger.Transaction> transactions = new ArrayList<>();
+ final List<Ledger.RewardBucket> rewardBuckets = new ArrayList<>();
+
+ final long now = getCurrentTimeMillis();
+ for (int i = 0; i < 2 * Ledger.MAX_TRANSACTION_COUNT; ++i) {
+ final long start = now - 20 * HOUR_IN_MILLIS + i * MINUTE_IN_MILLIS;
+ Ledger.Transaction transaction = new Ledger.Transaction(
+ start, start + MINUTE_IN_MILLIS, 1, null, 400, 0);
+ transactions.add(transaction);
+ }
+ for (int b = 0; b < 2 * Ledger.NUM_REWARD_BUCKET_WINDOWS; ++b) {
+ final long start = now
+ - (2 * Ledger.NUM_REWARD_BUCKET_WINDOWS - b) * 6 * HOUR_IN_MILLIS;
+ Ledger.RewardBucket rewardBucket = new Ledger.RewardBucket();
+ rewardBucket.startTimeMs = start;
+ for (int r = 0; r < 5; ++r) {
+ rewardBucket.cumulativeDelta.put(EconomicPolicy.TYPE_REWARD | r, b * start + r);
+ }
+ rewardBuckets.add(rewardBucket);
+ }
+ final Ledger ledger = new Ledger(balance, transactions, rewardBuckets);
+ assertEquals(balance, ledger.getCurrentBalance());
+ assertEquals(transactions.subList(Ledger.MAX_TRANSACTION_COUNT,
+ 2 * Ledger.MAX_TRANSACTION_COUNT),
+ ledger.getTransactions());
+ assertEquals(rewardBuckets.subList(Ledger.NUM_REWARD_BUCKET_WINDOWS,
+ 2 * Ledger.NUM_REWARD_BUCKET_WINDOWS),
+ ledger.getRewardBuckets());
+ }
+
+ @Test
public void testMultipleTransactions() {
final Ledger ledger = new Ledger();
ledger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 5, 0));
assertEquals(5, ledger.getCurrentBalance());
- assertEquals(5, ledger.get24HourSum(1, 60_000));
ledger.recordTransaction(new Ledger.Transaction(2000, 2000, 1, null, 25, 0));
assertEquals(30, ledger.getCurrentBalance());
- assertEquals(30, ledger.get24HourSum(1, 60_000));
ledger.recordTransaction(new Ledger.Transaction(5000, 5500, 1, null, -10, 5));
assertEquals(20, ledger.getCurrentBalance());
- assertEquals(20, ledger.get24HourSum(1, 60_000));
}
@Test
public void test24HourSum() {
+ final long now = getCurrentTimeMillis();
+ final long end = now + 24 * HOUR_IN_MILLIS;
+ final int reward1 = EconomicPolicy.TYPE_REWARD | 1;
+ final int reward2 = EconomicPolicy.TYPE_REWARD | 2;
final Ledger ledger = new Ledger();
- ledger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 500, 0));
- assertEquals(500, ledger.get24HourSum(1, 24 * HOUR_IN_MILLIS));
+
+ // First bucket
+ assertEquals(0, ledger.get24HourSum(reward1, end));
+ ledger.recordTransaction(new Ledger.Transaction(now, now + 1000, reward1, null, 500, 0));
+ assertEquals(500, ledger.get24HourSum(reward1, end));
+ assertEquals(0, ledger.get24HourSum(reward2, end));
+ ledger.recordTransaction(
+ new Ledger.Transaction(now + 2 * HOUR_IN_MILLIS, now + 3 * HOUR_IN_MILLIS,
+ reward1, null, 2500, 0));
+ assertEquals(3000, ledger.get24HourSum(reward1, end));
+ // Second bucket
+ shiftSystemTime(7 * HOUR_IN_MILLIS); // now + 7
+ ledger.recordTransaction(
+ new Ledger.Transaction(now + 7 * HOUR_IN_MILLIS, now + 7 * HOUR_IN_MILLIS,
+ reward1, null, 1, 0));
ledger.recordTransaction(
- new Ledger.Transaction(2 * HOUR_IN_MILLIS, 3 * HOUR_IN_MILLIS, 1, null, 2500, 0));
- assertEquals(3000, ledger.get24HourSum(1, 24 * HOUR_IN_MILLIS));
+ new Ledger.Transaction(now + 7 * HOUR_IN_MILLIS, now + 7 * HOUR_IN_MILLIS,
+ reward2, null, 42, 0));
+ assertEquals(3001, ledger.get24HourSum(reward1, end));
+ assertEquals(42, ledger.get24HourSum(reward2, end));
+ // Third bucket
+ shiftSystemTime(12 * HOUR_IN_MILLIS); // now + 19
ledger.recordTransaction(
- new Ledger.Transaction(4 * HOUR_IN_MILLIS, 4 * HOUR_IN_MILLIS, 1, null, 1, 0));
- assertEquals(3001, ledger.get24HourSum(1, 24 * HOUR_IN_MILLIS));
- assertEquals(2501, ledger.get24HourSum(1, 25 * HOUR_IN_MILLIS));
- assertEquals(2501, ledger.get24HourSum(1, 26 * HOUR_IN_MILLIS));
- // Pro-rated as the second transaction phases out
- assertEquals(1251,
- ledger.get24HourSum(1, 26 * HOUR_IN_MILLIS + 30 * MINUTE_IN_MILLIS));
- assertEquals(1, ledger.get24HourSum(1, 27 * HOUR_IN_MILLIS));
- assertEquals(0, ledger.get24HourSum(1, 28 * HOUR_IN_MILLIS));
+ new Ledger.Transaction(now + 12 * HOUR_IN_MILLIS, now + 13 * HOUR_IN_MILLIS,
+ reward1, null, 300, 0));
+ assertEquals(3301, ledger.get24HourSum(reward1, end));
+ assertRewardBucketsInOrder(ledger.getRewardBuckets());
+ // Older buckets should be excluded
+ assertEquals(301, ledger.get24HourSum(reward1, end + HOUR_IN_MILLIS));
+ assertEquals(301, ledger.get24HourSum(reward1, end + 2 * HOUR_IN_MILLIS));
+ // 2nd bucket should still be included since it started at the 7 hour mark
+ assertEquals(301, ledger.get24HourSum(reward1, end + 6 * HOUR_IN_MILLIS));
+ assertEquals(42, ledger.get24HourSum(reward2, end + 6 * HOUR_IN_MILLIS));
+ assertEquals(300, ledger.get24HourSum(reward1, end + 7 * HOUR_IN_MILLIS + 1));
+ assertEquals(0, ledger.get24HourSum(reward2, end + 8 * HOUR_IN_MILLIS));
+ assertEquals(0, ledger.get24HourSum(reward1, end + 19 * HOUR_IN_MILLIS + 1));
}
@Test
@@ -125,4 +250,127 @@ public class LedgerTest {
ledger.removeOldTransactions(0);
assertNull(ledger.getEarliestTransaction());
}
+
+ @Test
+ public void testTransactionsAlwaysInOrder() {
+ final Ledger ledger = new Ledger();
+ List<Ledger.Transaction> transactions = ledger.getTransactions();
+ assertTrue(transactions.isEmpty());
+
+ final long now = getCurrentTimeMillis();
+ Ledger.Transaction transaction1 = new Ledger.Transaction(
+ now - 48 * HOUR_IN_MILLIS, now - 40 * HOUR_IN_MILLIS, 1, null, 4800, 0);
+ Ledger.Transaction transaction2 = new Ledger.Transaction(
+ now - 24 * HOUR_IN_MILLIS, now - 23 * HOUR_IN_MILLIS, 1, null, 600, 0);
+ Ledger.Transaction transaction3 = new Ledger.Transaction(
+ now - 22 * HOUR_IN_MILLIS, now - 21 * HOUR_IN_MILLIS, 1, null, 600, 0);
+ // Instant event
+ Ledger.Transaction transaction4 = new Ledger.Transaction(
+ now - 20 * HOUR_IN_MILLIS, now - 20 * HOUR_IN_MILLIS, 1, null, 500, 0);
+
+ Ledger.Transaction transaction5 = new Ledger.Transaction(
+ now - 15 * HOUR_IN_MILLIS, now - 15 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS,
+ 1, null, 400, 0);
+ ledger.recordTransaction(transaction1);
+ ledger.recordTransaction(transaction2);
+ ledger.recordTransaction(transaction3);
+ ledger.recordTransaction(transaction4);
+ ledger.recordTransaction(transaction5);
+
+ transactions = ledger.getTransactions();
+ assertEquals(5, transactions.size());
+ assertTransactionsInOrder(transactions);
+
+ for (int i = 0; i < Ledger.MAX_TRANSACTION_COUNT - 5; ++i) {
+ final long start = now - 10 * HOUR_IN_MILLIS + i * MINUTE_IN_MILLIS;
+ Ledger.Transaction transaction = new Ledger.Transaction(
+ start, start + MINUTE_IN_MILLIS, 1, null, 400, 0);
+ ledger.recordTransaction(transaction);
+ }
+ transactions = ledger.getTransactions();
+ assertEquals(Ledger.MAX_TRANSACTION_COUNT, transactions.size());
+ assertTransactionsInOrder(transactions);
+
+ long start = now - 5 * HOUR_IN_MILLIS;
+ Ledger.Transaction transactionLast5 = new Ledger.Transaction(
+ start, start + MINUTE_IN_MILLIS, 1, null, 4800, 0);
+ start = now - 4 * HOUR_IN_MILLIS;
+ Ledger.Transaction transactionLast4 = new Ledger.Transaction(
+ start, start + MINUTE_IN_MILLIS, 1, null, 600, 0);
+ start = now - 3 * HOUR_IN_MILLIS;
+ Ledger.Transaction transactionLast3 = new Ledger.Transaction(
+ start, start + MINUTE_IN_MILLIS, 1, null, 600, 0);
+ // Instant event
+ start = now - 2 * HOUR_IN_MILLIS;
+ Ledger.Transaction transactionLast2 = new Ledger.Transaction(
+ start, start, 1, null, 500, 0);
+ Ledger.Transaction transactionLast1 = new Ledger.Transaction(
+ start, start + MINUTE_IN_MILLIS, 1, null, 400, 0);
+ ledger.recordTransaction(transactionLast5);
+ ledger.recordTransaction(transactionLast4);
+ ledger.recordTransaction(transactionLast3);
+ ledger.recordTransaction(transactionLast2);
+ ledger.recordTransaction(transactionLast1);
+
+ transactions = ledger.getTransactions();
+ assertEquals(Ledger.MAX_TRANSACTION_COUNT, transactions.size());
+ assertTransactionsInOrder(transactions);
+ assertEquals(transactionLast1, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 1));
+ assertEquals(transactionLast2, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 2));
+ assertEquals(transactionLast3, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 3));
+ assertEquals(transactionLast4, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 4));
+ assertEquals(transactionLast5, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 5));
+ assertFalse(transactions.contains(transaction1));
+ assertFalse(transactions.contains(transaction2));
+ assertFalse(transactions.contains(transaction3));
+ assertFalse(transactions.contains(transaction4));
+ assertFalse(transactions.contains(transaction5));
+ }
+
+ private void assertSparseLongArraysEqual(SparseLongArray expected, SparseLongArray actual) {
+ if (expected == null) {
+ assertNull(actual);
+ return;
+ }
+ assertNotNull(actual);
+ final int size = expected.size();
+ assertEquals(size, actual.size());
+ for (int i = 0; i < size; ++i) {
+ assertEquals(expected.keyAt(i), actual.keyAt(i));
+ assertEquals(expected.valueAt(i), actual.valueAt(i));
+ }
+ }
+
+ private void assertRewardBucketsEqual(Ledger.RewardBucket expected,
+ Ledger.RewardBucket actual) {
+ if (expected == null) {
+ assertNull(actual);
+ return;
+ }
+ assertNotNull(actual);
+ assertEquals(expected.startTimeMs, actual.startTimeMs);
+ assertSparseLongArraysEqual(expected.cumulativeDelta, actual.cumulativeDelta);
+ }
+
+ private void assertRewardBucketsInOrder(List<Ledger.RewardBucket> rewardBuckets) {
+ assertNotNull(rewardBuckets);
+ for (int i = 1; i < rewardBuckets.size(); ++i) {
+ final Ledger.RewardBucket prev = rewardBuckets.get(i - 1);
+ final Ledger.RewardBucket cur = rewardBuckets.get(i);
+ assertTrue("Newer bucket stored before older bucket @ index " + i
+ + ": " + prev.startTimeMs + " vs " + cur.startTimeMs,
+ prev.startTimeMs <= cur.startTimeMs);
+ }
+ }
+
+ private void assertTransactionsInOrder(List<Ledger.Transaction> transactions) {
+ assertNotNull(transactions);
+ for (int i = 1; i < transactions.size(); ++i) {
+ final Ledger.Transaction prev = transactions.get(i - 1);
+ final Ledger.Transaction cur = transactions.get(i);
+ assertTrue("Newer transaction stored before older transaction @ index " + i
+ + ": " + prev.endTimeMs + " vs " + cur.endTimeMs,
+ prev.endTimeMs <= cur.endTimeMs);
+ }
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
index a7d18eeba058..1b42fd3bb241 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -18,7 +18,6 @@ package com.android.server.notification;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -26,7 +25,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.AlarmManager;
import android.app.NotificationHistory;
import android.app.NotificationHistory.HistoricalNotification;
import android.content.Context;
@@ -60,8 +58,6 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
Handler mFileWriteHandler;
@Mock
Context mContext;
- @Mock
- AlarmManager mAlarmManager;
NotificationHistoryDatabase mDataBase;
@@ -96,22 +92,16 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager);
when(mContext.getUser()).thenReturn(getContext().getUser());
when(mContext.getPackageName()).thenReturn(getContext().getPackageName());
mRootDir = new File(mContext.getFilesDir(), "NotificationHistoryDatabaseTest");
- mDataBase = new NotificationHistoryDatabase(mContext, mFileWriteHandler, mRootDir);
+ mDataBase = new NotificationHistoryDatabase(mFileWriteHandler, mRootDir);
mDataBase.init();
}
@Test
- public void testDeletionReceiver() {
- verify(mContext, times(1)).registerReceiver(any(), any(), anyInt());
- }
-
- @Test
public void testPrune() throws Exception {
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeInMillis(10);
@@ -144,8 +134,6 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
mDataBase.prune(retainDays, cal.getTimeInMillis());
assertThat(mDataBase.mHistoryFiles).containsExactlyElementsIn(expectedFiles);
-
- verify(mAlarmManager, times(6)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
}
@Test
@@ -412,15 +400,14 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
when(file.getName()).thenReturn("5");
when(af.getBaseFile()).thenReturn(file);
- wbr.run(5, af);
+ wbr.run(af);
assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(1);
assertThat(mDataBase.mBuffer).isNotEqualTo(nh);
- verify(mAlarmManager, times(1)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
}
@Test
- public void testRemoveFilePathFromHistory_hasMatch() throws Exception {
+ public void testRemoveFilePathFromHistory_hasMatch() {
for (int i = 0; i < 5; i++) {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
@@ -436,7 +423,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
}
@Test
- public void testRemoveFilePathFromHistory_noMatch() throws Exception {
+ public void testRemoveFilePathFromHistory_noMatch() {
for (int i = 0; i < 5; i++) {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java
new file mode 100644
index 000000000000..af10b9dba63f
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.notification;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertFalse;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.app.job.JobServiceEngine;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.rule.ServiceTestRule;
+
+import com.android.server.LocalServices;
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidTestingRunner.class)
+public class NotificationHistoryJobServiceTest extends UiServiceTestCase {
+ private NotificationHistoryJobService mJobService;
+ private JobParameters mJobParams = new JobParameters(null,
+ NotificationHistoryJobService.BASE_JOB_ID, null, null, null,
+ 0, false, false, null, null, null);
+
+ @Captor
+ ArgumentCaptor<JobInfo> mJobInfoCaptor;
+
+ @Mock
+ private JobScheduler mMockJobScheduler;
+
+ @Mock
+ private NotificationManagerInternal mMockNotificationManagerInternal;
+
+ @Rule
+ public final ServiceTestRule mServiceRule = new ServiceTestRule();
+
+ @Before
+ public void setUp() throws Exception {
+ mJobService = new NotificationHistoryJobService();
+
+ final Field field = JobService.class.getDeclaredField("mEngine");
+ field.setAccessible(true);
+ field.set(mJobService, mock(JobServiceEngine.class));
+ mContext.addMockSystemService(JobScheduler.class, mMockJobScheduler);
+
+ // add NotificationManagerInternal to LocalServices
+ LocalServices.removeServiceForTest(NotificationManagerInternal.class);
+ LocalServices.addService(NotificationManagerInternal.class,
+ mMockNotificationManagerInternal);
+ }
+
+ @Test
+ public void testScheduleJob() {
+ // if asked, the job doesn't currently exist yet
+ when(mMockJobScheduler.getPendingJob(anyInt())).thenReturn(null);
+
+ // attempt to schedule the job
+ NotificationHistoryJobService.scheduleJob(mContext);
+ verify(mMockJobScheduler, times(1)).schedule(mJobInfoCaptor.capture());
+
+ // verify various properties of the job that is passed in to the job scheduler
+ JobInfo jobInfo = mJobInfoCaptor.getValue();
+ assertEquals(NotificationHistoryJobService.BASE_JOB_ID, jobInfo.getId());
+ assertFalse(jobInfo.isPersisted());
+ assertTrue(jobInfo.isPeriodic());
+ }
+
+ @Test
+ public void testOnStartJob() {
+ assertTrue(mJobService.onStartJob(mJobParams));
+
+ verify(mMockNotificationManagerInternal, timeout(500).atLeastOnce()).cleanupHistoryFiles();
+ }
+} \ No newline at end of file
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 830237a35b07..44ca9f432a46 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -8369,7 +8369,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testOnUnlockUser() {
UserInfo ui = new UserInfo();
ui.id = 10;
- mService.onUserUnlocking(new TargetUser(ui));
+ mService.onUserUnlocked(new TargetUser(ui));
waitForIdle();
verify(mHistoryManager, timeout(MAX_POST_DELAY).times(1)).onUserUnlocked(ui.id);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 1f07b20acc13..d6b807fc223e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2207,6 +2207,52 @@ public class DisplayContentTests extends WindowTestsBase {
assertNotEquals(curSnapshot, mDisplayContent.mImeScreenshot);
}
+ @UseTestDisplay(addWindows = {W_INPUT_METHOD})
+ @Test
+ public void testRemoveImeScreenshot_whenTargetSurfaceWasInvisible() {
+ final Task rootTask = createTask(mDisplayContent);
+ final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+ final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
+ win.onSurfaceShownChanged(true);
+ makeWindowVisible(win, mDisplayContent.mInputMethodWindow);
+ task.getDisplayContent().prepareAppTransition(TRANSIT_CLOSE);
+ doReturn(true).when(task).okToAnimate();
+ ArrayList<WindowContainer> sources = new ArrayList<>();
+ sources.add(activity);
+
+ mDisplayContent.setImeLayeringTarget(win);
+ mDisplayContent.setImeInputTarget(win);
+ mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);
+ task.applyAnimation(null, TRANSIT_OLD_TASK_CLOSE, false /* enter */,
+ false /* isVoiceInteraction */, sources);
+ assertNotNull(mDisplayContent.mImeScreenshot);
+
+ win.onSurfaceShownChanged(false);
+ assertNull(mDisplayContent.mImeScreenshot);
+ }
+
+ @UseTestDisplay(addWindows = {W_INPUT_METHOD})
+ @Test
+ public void testRemoveImeScreenshot_whenWindowRemoveImmediately() {
+ final Task rootTask = createTask(mDisplayContent);
+ final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+ final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
+ makeWindowVisible(mDisplayContent.mInputMethodWindow);
+
+ mDisplayContent.setImeLayeringTarget(win);
+ mDisplayContent.setImeInputTarget(win);
+ mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);
+ mDisplayContent.showImeScreenshot();
+ assertNotNull(mDisplayContent.mImeScreenshot);
+
+ // Expect IME snapshot will be removed when the win is IME layering target and invoked
+ // removeImeSurfaceByTarget.
+ win.removeImmediately();
+ assertNull(mDisplayContent.mImeScreenshot);
+ }
+
@Test
public void testRotateBounds_keepSamePhysicalPosition() {
final DisplayContent dc =
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 2b131e1fb7c5..8f2e9b4c6ff6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -45,7 +45,12 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.graphics.PixelFormat;
@@ -344,4 +349,24 @@ public class DisplayPolicyTests extends WindowTestsBase {
final InsetsSource navBarSource = state.peekSource(ITYPE_NAVIGATION_BAR);
assertEquals(attrs.height - 10, navBarSource.getFrame().height());
}
+
+ @Test
+ public void testCanSystemBarsBeShownByUser() {
+ ((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true;
+ final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
+ final WindowState windowState = mock(WindowState.class);
+ final InsetsSourceProvider provider = mock(InsetsSourceProvider.class);
+ final InsetsControlTarget controlTarget = mock(InsetsControlTarget.class);
+ when(provider.getControlTarget()).thenReturn(controlTarget);
+ when(windowState.getControllableInsetProvider()).thenReturn(provider);
+ when(controlTarget.getRequestedVisibility(anyInt())).thenReturn(true);
+
+ displayPolicy.setCanSystemBarsBeShownByUser(false);
+ displayPolicy.requestTransientBars(windowState, true);
+ verify(controlTarget, never()).showInsets(anyInt(), anyBoolean());
+
+ displayPolicy.setCanSystemBarsBeShownByUser(true);
+ displayPolicy.requestTransientBars(windowState, true);
+ verify(controlTarget).showInsets(anyInt(), anyBoolean());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerContinuousTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java
index 1e3250080514..8c49c26f3802 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerContinuousTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java
@@ -24,7 +24,7 @@ import android.app.KeyguardManager;
import android.os.PowerManager;
import android.view.SurfaceControl;
import android.view.cts.surfacevalidator.CapturedActivity;
-import android.window.SurfaceSyncer;
+import android.window.SurfaceSyncGroup;
import androidx.test.rule.ActivityTestRule;
@@ -35,7 +35,7 @@ import org.junit.rules.TestName;
import java.util.Objects;
-public class SurfaceSyncerContinuousTest {
+public class SurfaceSyncGroupContinuousTest {
@Rule
public TestName mName = new TestName();
@@ -60,7 +60,7 @@ public class SurfaceSyncerContinuousTest {
@Test
public void testSurfaceViewSyncDuringResize() throws Throwable {
- SurfaceSyncer.setTransactionFactory(SurfaceControl.Transaction::new);
- mCapturedActivity.verifyTest(new SurfaceSyncerValidatorTestCase(), mName);
+ SurfaceSyncGroup.setTransactionFactory(SurfaceControl.Transaction::new);
+ mCapturedActivity.verifyTest(new SurfaceSyncGroupValidatorTestCase(), mName);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java
index 87382952314b..846a5066e036 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java
@@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl;
-import android.window.SurfaceSyncer;
+import android.window.SurfaceSyncGroup;
import androidx.test.filters.SmallTest;
@@ -35,22 +35,20 @@ import java.util.concurrent.TimeUnit;
@SmallTest
@Presubmit
-public class SurfaceSyncerTest {
- private SurfaceSyncer mSurfaceSyncer;
+public class SurfaceSyncGroupTest {
@Before
public void setup() {
- mSurfaceSyncer = new SurfaceSyncer();
- SurfaceSyncer.setTransactionFactory(StubTransaction::new);
+ SurfaceSyncGroup.setTransactionFactory(StubTransaction::new);
}
@Test
public void testSyncOne() throws InterruptedException {
final CountDownLatch finishedLatch = new CountDownLatch(1);
- int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown());
+ SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(transaction -> finishedLatch.countDown());
SyncTarget syncTarget = new SyncTarget();
- mSurfaceSyncer.addToSync(startSyncId, syncTarget);
- mSurfaceSyncer.markSyncReady(startSyncId);
+ syncGroup.addToSync(syncTarget);
+ syncGroup.markSyncReady();
syncTarget.onBufferReady();
@@ -61,15 +59,15 @@ public class SurfaceSyncerTest {
@Test
public void testSyncMultiple() throws InterruptedException {
final CountDownLatch finishedLatch = new CountDownLatch(1);
- int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown());
+ SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(transaction -> finishedLatch.countDown());
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
SyncTarget syncTarget3 = new SyncTarget();
- mSurfaceSyncer.addToSync(startSyncId, syncTarget1);
- mSurfaceSyncer.addToSync(startSyncId, syncTarget2);
- mSurfaceSyncer.addToSync(startSyncId, syncTarget3);
- mSurfaceSyncer.markSyncReady(startSyncId);
+ syncGroup.addToSync(syncTarget1);
+ syncGroup.addToSync(syncTarget2);
+ syncGroup.addToSync(syncTarget3);
+ syncGroup.markSyncReady();
syncTarget1.onBufferReady();
assertNotEquals(0, finishedLatch.getCount());
@@ -84,39 +82,36 @@ public class SurfaceSyncerTest {
}
@Test
- public void testInvalidSyncId() {
- assertFalse(mSurfaceSyncer.addToSync(0, new SyncTarget()));
- }
-
- @Test
- public void testAddSyncWhenSyncComplete() throws InterruptedException {
+ public void testAddSyncWhenSyncComplete() {
final CountDownLatch finishedLatch = new CountDownLatch(1);
- int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown());
+ SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(transaction -> finishedLatch.countDown());
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
- assertTrue(mSurfaceSyncer.addToSync(startSyncId, syncTarget1));
- mSurfaceSyncer.markSyncReady(startSyncId);
+ assertTrue(syncGroup.addToSync(syncTarget1));
+ syncGroup.markSyncReady();
// Adding to a sync that has been completed is also invalid since the sync id has been
// cleared.
- assertFalse(mSurfaceSyncer.addToSync(startSyncId, syncTarget2));
+ assertFalse(syncGroup.addToSync(syncTarget2));
}
@Test
- public void testMultipleSyncSets() throws InterruptedException {
+ public void testMultiplesyncGroups() throws InterruptedException {
final CountDownLatch finishedLatch1 = new CountDownLatch(1);
final CountDownLatch finishedLatch2 = new CountDownLatch(1);
- int startSyncId1 = mSurfaceSyncer.setupSync(transaction -> finishedLatch1.countDown());
- int startSyncId2 = mSurfaceSyncer.setupSync(transaction -> finishedLatch2.countDown());
+ SurfaceSyncGroup syncGroup1 = new SurfaceSyncGroup(
+ transaction -> finishedLatch1.countDown());
+ SurfaceSyncGroup syncGroup2 = new SurfaceSyncGroup(
+ transaction -> finishedLatch2.countDown());
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
- assertTrue(mSurfaceSyncer.addToSync(startSyncId1, syncTarget1));
- assertTrue(mSurfaceSyncer.addToSync(startSyncId2, syncTarget2));
- mSurfaceSyncer.markSyncReady(startSyncId1);
- mSurfaceSyncer.markSyncReady(startSyncId2);
+ assertTrue(syncGroup1.addToSync(syncTarget1));
+ assertTrue(syncGroup2.addToSync(syncTarget2));
+ syncGroup1.markSyncReady();
+ syncGroup2.markSyncReady();
syncTarget1.onBufferReady();
@@ -134,19 +129,21 @@ public class SurfaceSyncerTest {
public void testMergeSync() throws InterruptedException {
final CountDownLatch finishedLatch1 = new CountDownLatch(1);
final CountDownLatch finishedLatch2 = new CountDownLatch(1);
- int startSyncId1 = mSurfaceSyncer.setupSync(transaction -> finishedLatch1.countDown());
- int startSyncId2 = mSurfaceSyncer.setupSync(transaction -> finishedLatch2.countDown());
+ SurfaceSyncGroup syncGroup1 = new SurfaceSyncGroup(
+ transaction -> finishedLatch1.countDown());
+ SurfaceSyncGroup syncGroup2 = new SurfaceSyncGroup(
+ transaction -> finishedLatch2.countDown());
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
- assertTrue(mSurfaceSyncer.addToSync(startSyncId1, syncTarget1));
- assertTrue(mSurfaceSyncer.addToSync(startSyncId2, syncTarget2));
- mSurfaceSyncer.markSyncReady(startSyncId1);
- mSurfaceSyncer.merge(startSyncId2, startSyncId1, mSurfaceSyncer);
- mSurfaceSyncer.markSyncReady(startSyncId2);
+ assertTrue(syncGroup1.addToSync(syncTarget1));
+ assertTrue(syncGroup2.addToSync(syncTarget2));
+ syncGroup1.markSyncReady();
+ syncGroup2.merge(syncGroup1);
+ syncGroup2.markSyncReady();
- // Finish syncTarget2 first to test that the syncSet is not complete until the merged sync
+ // Finish syncTarget2 first to test that the syncGroup is not complete until the merged sync
// is also done.
syncTarget2.onBufferReady();
finishedLatch2.await(1, TimeUnit.SECONDS);
@@ -167,23 +164,25 @@ public class SurfaceSyncerTest {
public void testMergeSyncAlreadyComplete() throws InterruptedException {
final CountDownLatch finishedLatch1 = new CountDownLatch(1);
final CountDownLatch finishedLatch2 = new CountDownLatch(1);
- int startSyncId1 = mSurfaceSyncer.setupSync(transaction -> finishedLatch1.countDown());
- int startSyncId2 = mSurfaceSyncer.setupSync(transaction -> finishedLatch2.countDown());
+ SurfaceSyncGroup syncGroup1 = new SurfaceSyncGroup(
+ transaction -> finishedLatch1.countDown());
+ SurfaceSyncGroup syncGroup2 = new SurfaceSyncGroup(
+ transaction -> finishedLatch2.countDown());
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
- assertTrue(mSurfaceSyncer.addToSync(startSyncId1, syncTarget1));
- assertTrue(mSurfaceSyncer.addToSync(startSyncId2, syncTarget2));
- mSurfaceSyncer.markSyncReady(startSyncId1);
+ assertTrue(syncGroup1.addToSync(syncTarget1));
+ assertTrue(syncGroup2.addToSync(syncTarget2));
+ syncGroup1.markSyncReady();
syncTarget1.onBufferReady();
// The first sync will still get a callback when it's sync requirements are done.
finishedLatch1.await(5, TimeUnit.SECONDS);
assertEquals(0, finishedLatch1.getCount());
- mSurfaceSyncer.merge(startSyncId2, startSyncId1, mSurfaceSyncer);
- mSurfaceSyncer.markSyncReady(startSyncId2);
+ syncGroup2.merge(syncGroup1);
+ syncGroup2.markSyncReady();
syncTarget2.onBufferReady();
// Verify that the second sync will receive complete since the merged sync was already
@@ -192,11 +191,11 @@ public class SurfaceSyncerTest {
assertEquals(0, finishedLatch2.getCount());
}
- private static class SyncTarget implements SurfaceSyncer.SyncTarget {
- private SurfaceSyncer.SyncBufferCallback mSyncBufferCallback;
+ private static class SyncTarget implements SurfaceSyncGroup.SyncTarget {
+ private SurfaceSyncGroup.SyncBufferCallback mSyncBufferCallback;
@Override
- public void onReadyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
+ public void onReadyToSync(SurfaceSyncGroup.SyncBufferCallback syncBufferCallback) {
mSyncBufferCallback = syncBufferCallback;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java
index d65b80ae0700..2df3085c8751 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java
@@ -31,18 +31,18 @@ import android.view.ViewGroup;
import android.view.cts.surfacevalidator.ISurfaceValidatorTestCase;
import android.view.cts.surfacevalidator.PixelChecker;
import android.widget.FrameLayout;
-import android.window.SurfaceSyncer;
+import android.window.SurfaceSyncGroup;
import androidx.annotation.NonNull;
/**
* A validator class that will create a SurfaceView and then update its size over and over. The code
* will request to sync the SurfaceView content with the main window and validate that there was
- * never an empty area (black color). The test uses {@link SurfaceSyncer} class to gather the
+ * never an empty area (black color). The test uses {@link SurfaceSyncGroup} class to gather the
* content it wants to synchronize.
*/
-public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase {
- private static final String TAG = "SurfaceSyncerValidatorTestCase";
+public class SurfaceSyncGroupValidatorTestCase implements ISurfaceValidatorTestCase {
+ private static final String TAG = "SurfaceSyncGroupValidatorTestCase";
private final Runnable mRunnable = new Runnable() {
@Override
@@ -55,12 +55,11 @@ public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase
private Handler mHandler;
private SurfaceView mSurfaceView;
private boolean mLastExpanded = true;
- private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
private RenderingThread mRenderingThread;
private FrameLayout mParent;
- private int mLastSyncId = -1;
+ private SurfaceSyncGroup mSyncGroup;
final SurfaceHolder.Callback mCallback = new SurfaceHolder.Callback() {
@Override
@@ -76,11 +75,11 @@ public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
int height) {
- if (mLastSyncId >= 0) {
- mSurfaceSyncer.addToSync(mLastSyncId, mSurfaceView, frameCallback ->
+ if (mSyncGroup != null) {
+ mSyncGroup.addToSync(mSurfaceView, frameCallback ->
mRenderingThread.setFrameCallback(frameCallback));
- mSurfaceSyncer.markSyncReady(mLastSyncId);
- mLastSyncId = -1;
+ mSyncGroup.markSyncReady();
+ mSyncGroup = null;
}
}
@@ -118,7 +117,7 @@ public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase
}
public void updateSurfaceViewSize() {
- if (mRenderingThread == null || mLastSyncId >= 0 || !mRenderingThread.isReadyToSync()) {
+ if (mRenderingThread == null || mSyncGroup != null || !mRenderingThread.isReadyToSync()) {
return;
}
@@ -133,8 +132,8 @@ public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase
mLastExpanded = !mLastExpanded;
mRenderingThread.pauseRendering();
- mLastSyncId = mSurfaceSyncer.setupSync(() -> { });
- mSurfaceSyncer.addToSync(mLastSyncId, mParent);
+ mSyncGroup = new SurfaceSyncGroup();
+ mSyncGroup.addToSync(mParent.getRootSurfaceControl());
ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
svParams.height = height;
@@ -143,7 +142,7 @@ public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase
private static class RenderingThread extends HandlerThread {
private final SurfaceHolder mSurfaceHolder;
- private SurfaceSyncer.SurfaceViewFrameCallback mFrameCallback;
+ private SurfaceSyncGroup.SurfaceViewFrameCallback mFrameCallback;
private boolean mPauseRendering;
private boolean mComplete;
@@ -202,7 +201,7 @@ public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase
return mFrameCallback == null;
}
}
- public void setFrameCallback(SurfaceSyncer.SurfaceViewFrameCallback frameCallback) {
+ public void setFrameCallback(SurfaceSyncGroup.SurfaceViewFrameCallback frameCallback) {
synchronized (this) {
mFrameCallback = frameCallback;
mPauseRendering = false;
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 e47bcc98b908..97f0918e8136 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -18,6 +18,12 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -237,10 +243,10 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.registerOrganizer(mIOrganizer);
mController.onTaskFragmentError(mTaskFragment.getTaskFragmentOrganizer(),
- mErrorToken, exception);
+ mErrorToken, null /* taskFragment */, -1 /* opType */, exception);
mController.dispatchPendingEvents();
- verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), eq(exception));
+ verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), eq(null), eq(-1), eq(exception));
}
@Test
@@ -604,7 +610,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
verify(mAtm.getActivityStartController(), never()).startActivityInTaskFragment(any(), any(),
any(), any(), anyInt(), anyInt(), any());
verify(mAtm.mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
- eq(mErrorToken), any(IllegalArgumentException.class));
+ eq(mErrorToken), eq(mTaskFragment),
+ eq(HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT),
+ any(IllegalArgumentException.class));
}
@Test
@@ -619,7 +627,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mWindowOrganizerController.applyTransaction(mTransaction);
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
- eq(mErrorToken), any(IllegalArgumentException.class));
+ eq(mErrorToken), eq(mTaskFragment),
+ eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
+ any(IllegalArgumentException.class));
assertNull(activity.getOrganizedTaskFragment());
}
@@ -635,7 +645,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mWindowOrganizerController.applyTransaction(mTransaction);
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
- eq(mErrorToken), any(IllegalArgumentException.class));
+ eq(mErrorToken), eq(mTaskFragment),
+ eq(HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS),
+ any(IllegalArgumentException.class));
verify(mTaskFragment, never()).setAdjacentTaskFragment(any());
}
@@ -654,7 +666,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mWindowOrganizerController.applyTransaction(mTransaction);
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
- eq(mErrorToken), any(IllegalArgumentException.class));
+ eq(mErrorToken), eq(null), eq(HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT),
+ any(IllegalArgumentException.class));
assertNull(mWindowOrganizerController.getTaskFragment(fragmentToken));
}
@@ -669,7 +682,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mWindowOrganizerController.applyTransaction(mTransaction);
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
- eq(mErrorToken), any(IllegalArgumentException.class));
+ eq(mErrorToken), eq(mTaskFragment), eq(HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT),
+ any(IllegalArgumentException.class));
assertNotNull(mWindowOrganizerController.getTaskFragment(mFragmentToken));
// Allow organizer to delete empty TaskFragment for cleanup.
@@ -931,7 +945,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
// The pending event will be dispatched on the handler (from requestTraversal).
waitHandlerIdle(mWm.mAnimationHandler);
- verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(SecurityException.class));
+ verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(),
+ eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
+ any(SecurityException.class));
}
@Test
@@ -968,7 +984,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
// The pending event will be dispatched on the handler (from requestTraversal).
waitHandlerIdle(mWm.mAnimationHandler);
- verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(SecurityException.class));
+ verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(),
+ eq(HIERARCHY_OP_TYPE_REPARENT_CHILDREN), any(SecurityException.class));
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 92457c73b315..851be9d77348 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -40,6 +40,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
boolean mKeyguardShowingAndNotOccluded = false;
boolean mOkToAnimate = true;
+ boolean mIsUserSetupComplete = false;
TestWindowManagerPolicy() {
}
@@ -284,7 +285,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public boolean isUserSetupComplete() {
- return false;
+ return mIsUserSetupComplete;
}
@Override
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index a0b01a7fc27d..959429e255dd 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -639,6 +639,11 @@ public class UsageStatsService extends SystemService implements
mAppStandby.initializeDefaultsForSystemApps(userId);
}
+ private boolean sameApp(int callingUid, @UserIdInt int userId, String packageName) {
+ return mPackageManagerInternal.getPackageUid(packageName, 0 /* flags */, userId)
+ == callingUid;
+ }
+
private boolean isInstantApp(String packageName, int userId) {
return mPackageManagerInternal.isPackageEphemeral(userId, packageName);
}
@@ -2354,17 +2359,15 @@ public class UsageStatsService extends SystemService implements
}
final int packageUid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
// If the calling app is asking about itself, continue, else check for permission.
- if (packageUid != callingUid) {
- if (!hasPermission(callingPackage)) {
- throw new SecurityException(
- "Don't have permission to query app standby bucket");
- }
+ final boolean sameApp = packageUid == callingUid;
+ if (!sameApp && !hasPermission(callingPackage)) {
+ throw new SecurityException("Don't have permission to query app standby bucket");
}
final boolean isInstantApp = isInstantApp(packageName, userId);
final boolean cannotAccessInstantApps = shouldObfuscateInstantAppsForCaller(callingUid,
userId);
- if (packageUid < 0 || (isInstantApp && cannotAccessInstantApps)) {
+ if (packageUid < 0 || (!sameApp && isInstantApp && cannotAccessInstantApps)) {
throw new IllegalArgumentException(
"Cannot get standby bucket for non existent package (" + packageName + ")");
}
@@ -2418,7 +2421,9 @@ public class UsageStatsService extends SystemService implements
}
final int targetUserId = userId;
standbyBucketList.removeIf(
- i -> cannotAccessInstantApps && isInstantApp(i.mPackageName, targetUserId));
+ i -> !sameApp(callingUid, targetUserId, i.mPackageName)
+ && isInstantApp(i.mPackageName, targetUserId)
+ && cannotAccessInstantApps);
return new ParceledListSlice<>(standbyBucketList);
} finally {
Binder.restoreCallingIdentity(token);
diff --git a/tests/Camera2Tests/CameraToo/Android.bp b/tests/Camera2Tests/CameraToo/Android.bp
new file mode 100644
index 000000000000..ebc6fed9fefd
--- /dev/null
+++ b/tests/Camera2Tests/CameraToo/Android.bp
@@ -0,0 +1,28 @@
+// 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 {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: [
+ "frameworks_base_license",
+ ],
+}
+
+android_test {
+ name: "CameraToo",
+
+ sdk_version: "current",
+ srcs: ["src/**/*.java"],
+
+}
diff --git a/tests/Camera2Tests/CameraToo/Android.mk b/tests/Camera2Tests/CameraToo/Android.mk
deleted file mode 100644
index 33473143c8cb..000000000000
--- a/tests/Camera2Tests/CameraToo/Android.mk
+++ /dev/null
@@ -1,26 +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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_PACKAGE_NAME := CameraToo
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-include $(BUILD_PACKAGE)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
index 79656a0bef9e..149576e4ec1d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
@@ -47,7 +47,7 @@ class NewTasksAppHelper @JvmOverloads constructor(
}
button.click()
wmHelper.StateSyncBuilder()
- .withFullScreenApp(this)
+ .withAppTransitionIdle()
.waitForAndVerify()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
index 53f43184dde6..6ceb9ea7e3d7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
@@ -71,49 +71,11 @@ class CloseImeEditorPopupDialogTest(testSpec: FlickerTestParameter) : BaseTest(t
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun entireScreenCovered() =
- super.entireScreenCovered()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerIsVisibleAtStartAndEnd() =
- super.statusBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() =
- super.statusBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
override fun taskBarLayerIsVisibleAtStartAndEnd() =
super.taskBarLayerIsVisibleAtStartAndEnd()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index 113fddff87b5..452aa63e2bf9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -96,12 +96,6 @@ class CloseImeWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest(testSpe
testSpec.navBarLayerPositionAtStartAndEnd()
}
- /** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() =
- super.statusBarLayerPositionAtStartAndEnd()
-
@Presubmit
@Test
fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
index 95c73df257c7..4569a5b4910e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
@@ -80,62 +80,13 @@ class LaunchAppShowImeAndDialogThemeAppTest(
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerIsVisibleAtStartAndEnd() =
- super.statusBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() =
- super.statusBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun entireScreenCovered() = super.entireScreenCovered()
-
/**
* Checks that [ComponentMatcher.IME] layer becomes visible during the transition
*/
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
index 442ff1a36eba..977719c5f670 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.ime
-import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
@@ -94,65 +93,6 @@ class LaunchAppShowImeOnStartTest(testSpec: FlickerTestParameter) : BaseTest(tes
}
}
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerIsVisibleAtStartAndEnd() =
- super.statusBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() =
- super.statusBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun entireScreenCovered() = super.entireScreenCovered()
-
/**
* Checks that [ComponentMatcher.IME] window becomes visible during the transition
*/
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
index 5296e3060a8d..b10aed30e39e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.ime
-import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
@@ -69,18 +68,6 @@ class OpenImeWindowAndCloseTest(testSpec: FlickerTestParameter) : BaseTest(testS
}
}
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerPositionAtStartAndEnd() =
- super.navBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() =
- super.statusBarLayerPositionAtStartAndEnd()
-
@Presubmit
@Test
fun imeWindowBecomesInvisible() = testSpec.imeWindowBecomesInvisible()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
index b8686bc8e7ef..e85b9c0e992f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
@@ -88,12 +88,6 @@ class OpenImeWindowFromFixedOrientationAppTest(
@Test
override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
@Presubmit
@Test
fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
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 470fa58b0ff2..16cf22abecc2 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
@@ -100,22 +100,6 @@ class OpenImeWindowToOverViewTest(testSpec: FlickerTestParameter) : BaseTest(tes
stateSync.withNavOrTaskBarVisible().withStatusBarVisible()
}
}
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun entireScreenCovered() = super.entireScreenCovered()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- super.visibleWindowsShownMoreThanOneConsecutiveEntry()
@Presubmit
@Test
@@ -147,7 +131,7 @@ class OpenImeWindowToOverViewTest(testSpec: FlickerTestParameter) : BaseTest(tes
* In the legacy transitions, the nav bar is not marked as invisible.
* In the new transitions this is fixed and the nav bar shows as invisible
*/
- @Postsubmit
+ @Presubmit
@Test
fun navBarLayerIsInvisibleInLandscapeGestural() {
Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
@@ -217,7 +201,7 @@ class OpenImeWindowToOverViewTest(testSpec: FlickerTestParameter) : BaseTest(tes
override fun taskBarLayerIsVisibleAtStartAndEnd() =
super.taskBarLayerIsVisibleAtStartAndEnd()
- @Postsubmit
+ @Presubmit
@Test
fun statusBarLayerIsVisibleInPortrait() {
Assume.assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index e91126096b82..4954adb079e9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.ime
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
@@ -80,12 +79,6 @@ open class ReOpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSp
}
/** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() =
- super.statusBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
@Presubmit
@Test
override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
@@ -146,9 +139,9 @@ open class ReOpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSp
}
}
- @FlakyTest(bugId = 204570898)
+ @Presubmit
@Test
- fun imeAppWindowVisibility() {
+ fun imeAppWindowIsAlwaysVisibleShellTransit() {
Assume.assumeTrue(isShellTransitionsEnabled)
// the app starts visible in live tile, and stays visible for the duration of entering
// and exiting overview. Since we log 1x per frame, sometimes the activity visibility
@@ -172,9 +165,9 @@ open class ReOpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSp
}
}
- @FlakyTest(bugId = 204570898)
+ @Presubmit
@Test
- fun imeLayerIsBecomesVisible() {
+ fun imeLayerBecomesVisibleShellTransit() {
Assume.assumeTrue(isShellTransitionsEnabled)
testSpec.assertLayers {
this.isVisible(ComponentMatcher.IME)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index 60a1591542ce..4640d36b55e4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -88,6 +88,12 @@ open class OpenAppColdTest(
@Test
override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 240238245)
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index 4beb5d019957..b482e5f3c3fb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -78,7 +78,7 @@ class TaskTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
testApp.openNewTask(device, wmHelper)
tapl.pressBack()
wmHelper.StateSyncBuilder()
- .withFullScreenApp(testApp)
+ .withAppTransitionIdle()
.waitForAndVerify()
}
}
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 45b7be594530..a9fb0f261465 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
@@ -83,6 +83,7 @@ open class QuickSwitchBetweenTwoAppsBackTest(
transitions {
tapl.launchedAppState.quickSwitchToPreviousApp()
wmHelper.StateSyncBuilder()
+ .withFullScreenApp(testApp1)
.withNavOrTaskBarVisible()
.withStatusBarVisible()
.waitForAndVerify()
@@ -269,12 +270,6 @@ open class QuickSwitchBetweenTwoAppsBackTest(
@Test
override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerIsVisibleAtStartAndEnd() =
- super.statusBarLayerIsVisibleAtStartAndEnd()
-
companion object {
private var startDisplayBounds = Rect.EMPTY
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 4ce3b15e292c..3b602126399d 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
@@ -79,6 +79,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(
testApp2.launchViaIntent(wmHelper)
tapl.launchedAppState.quickSwitchToPreviousApp()
wmHelper.StateSyncBuilder()
+ .withFullScreenApp(testApp1)
.withNavOrTaskBarVisible()
.withStatusBarVisible()
.waitForAndVerify()
@@ -89,6 +90,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(
transitions {
tapl.launchedAppState.quickSwitchToPreviousAppSwipeLeft()
wmHelper.StateSyncBuilder()
+ .withFullScreenApp(testApp2)
.withNavOrTaskBarVisible()
.withStatusBarVisible()
.waitForAndVerify()
@@ -283,12 +285,6 @@ open class QuickSwitchBetweenTwoAppsForwardTest(
super.visibleLayersShownMoreThanOneConsecutiveEntry()
/** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() =
- super.statusBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
@FlakyTest(bugId = 239148258)
@Test
override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
diff --git a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
index ab7f24a8d326..03f61fa49926 100644
--- a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
+++ b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
@@ -35,11 +35,11 @@ import android.view.WindowMetrics;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Switch;
-import android.window.SurfaceSyncer;
+import android.window.SurfaceSyncGroup;
/**
* Test app that allows the user to resize the SurfaceView and have the new buffer sync with the
- * main window. This tests that {@link SurfaceSyncer} is working correctly.
+ * main window. This tests that {@link SurfaceSyncGroup} is working correctly.
*/
public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.Callback {
private static final String TAG = "SurfaceViewSyncActivity";
@@ -49,12 +49,10 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
private RenderingThread mRenderingThread;
- private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
-
private Button mExpandButton;
private Switch mEnableSyncSwitch;
- private int mLastSyncId = -1;
+ private SurfaceSyncGroup mSyncGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -76,7 +74,7 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
}
private void updateSurfaceViewSize(Rect bounds, View container) {
- if (mLastSyncId >= 0) {
+ if (mSyncGroup != null) {
return;
}
@@ -91,8 +89,8 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
mLastExpanded = !mLastExpanded;
if (mEnableSyncSwitch.isChecked()) {
- mLastSyncId = mSurfaceSyncer.setupSync(() -> { });
- mSurfaceSyncer.addToSync(mLastSyncId, container);
+ mSyncGroup = new SurfaceSyncGroup();
+ mSyncGroup.addToSync(container.getRootSurfaceControl());
}
ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
@@ -112,14 +110,14 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
if (mEnableSyncSwitch.isChecked()) {
- if (mLastSyncId < 0) {
+ if (mSyncGroup == null) {
mRenderingThread.renderFrame(null, width, height);
return;
}
- mSurfaceSyncer.addToSync(mLastSyncId, mSurfaceView, frameCallback ->
+ mSyncGroup.addToSync(mSurfaceView, frameCallback ->
mRenderingThread.renderFrame(frameCallback, width, height));
- mSurfaceSyncer.markSyncReady(mLastSyncId);
- mLastSyncId = -1;
+ mSyncGroup.markSyncReady();
+ mSyncGroup = null;
} else {
mRenderingThread.renderFrame(null, width, height);
}
@@ -133,7 +131,7 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
private static class RenderingThread extends HandlerThread {
private final SurfaceHolder mSurfaceHolder;
private Handler mHandler;
- private SurfaceSyncer.SurfaceViewFrameCallback mFrameCallback;
+ private SurfaceSyncGroup.SurfaceViewFrameCallback mFrameCallback;
private final Point mSurfaceSize = new Point();
int mColorValue = 0;
@@ -147,7 +145,7 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
mPaint.setTextSize(100);
}
- public void renderFrame(SurfaceSyncer.SurfaceViewFrameCallback frameCallback, int width,
+ public void renderFrame(SurfaceSyncGroup.SurfaceViewFrameCallback frameCallback, int width,
int height) {
if (mHandler != null) {
mHandler.post(() -> {
diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp
index 9a9e42bfc300..9bfcc18ee301 100644
--- a/tests/UpdatableSystemFontTest/Android.bp
+++ b/tests/UpdatableSystemFontTest/Android.bp
@@ -37,6 +37,7 @@ android_test {
"vts",
],
data: [
+ ":EmojiRenderingTestApp",
":UpdatableSystemFontTestCertDer",
":UpdatableSystemFontTest_NotoColorEmoji.ttf",
":UpdatableSystemFontTest_NotoColorEmoji.sig",
diff --git a/tests/backup/Android.bp b/tests/backup/Android.bp
new file mode 100644
index 000000000000..3890a1f58078
--- /dev/null
+++ b/tests/backup/Android.bp
@@ -0,0 +1,54 @@
+// Copyright (C) 2008 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// native test
+// ========================================
+package {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: [
+ "frameworks_base_license",
+ ],
+}
+
+cc_binary {
+ name: "backup_helper_test",
+
+ srcs: ["backup_helper_test.cpp"],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "libandroidfw",
+ "libutils",
+ ],
+
+}
+
+// java test
+// ========================================
+android_app {
+ name: "BackupTest",
+
+ srcs: ["**/*.java"],
+
+ platform_apis: true,
+
+ optimize: {
+ enabled: false,
+ },
+
+}
diff --git a/tests/backup/Android.mk b/tests/backup/Android.mk
deleted file mode 100644
index b6f34717658c..000000000000
--- a/tests/backup/Android.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# native test
-# ========================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- backup_helper_test.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := backup_helper_test
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_SHARED_LIBRARIES := libandroidfw libutils
-
-include $(BUILD_EXECUTABLE)
-
-# java test
-# ========================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := BackupTest
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
-include $(BUILD_PACKAGE)
diff --git a/tools/lint/Android.bp b/tools/lint/Android.bp
index 3458359273b8..260104145505 100644
--- a/tools/lint/Android.bp
+++ b/tools/lint/Android.bp
@@ -34,6 +34,12 @@ java_library_host {
java_test_host {
name: "AndroidFrameworkLintCheckerTest",
+ // TODO(b/239881504): Since this test was written, Android
+ // Lint was updated, and now includes classes that were
+ // compiled for java 15. The soong build doesn't support
+ // java 15 yet, so we can't compile against "lint". Disable
+ // the test until java 15 is supported.
+ enabled: false,
srcs: ["checks/src/test/java/**/*.kt"],
static_libs: [
"AndroidFrameworkLintChecker",