summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp49
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java11
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java104
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java5
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java9
-rw-r--r--config/hiddenapi-unsupported.txt1
-rw-r--r--core/api/current.txt13
-rw-r--r--core/api/module-lib-current.txt9
-rw-r--r--core/api/system-current.txt6
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/app/Activity.java21
-rw-r--r--core/java/android/app/ContextImpl.java11
-rw-r--r--core/java/android/app/INotificationManager.aidl1
-rw-r--r--core/java/android/app/Notification.java17
-rw-r--r--core/java/android/app/NotificationHistory.java20
-rw-r--r--core/java/android/app/SystemServiceRegistry.java2
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java16
-rw-r--r--core/java/android/bluetooth/le/BluetoothLeScanner.java17
-rw-r--r--core/java/android/content/AttributionSource.java17
-rw-r--r--core/java/android/content/Context.java1
-rw-r--r--core/java/android/content/ContextParams.java10
-rw-r--r--core/java/android/content/PermissionChecker.java4
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackageImpl.java3
-rw-r--r--core/java/android/content/rollback/RollbackManagerFrameworkInitializer.java2
-rw-r--r--core/java/android/hardware/biometrics/BiometricTestSession.java23
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java6
-rw-r--r--core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java13
-rw-r--r--core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java2
-rw-r--r--core/java/android/net/INetworkPolicyManager.aidl1
-rw-r--r--core/java/android/net/NetworkIdentity.java14
-rw-r--r--core/java/android/net/NetworkPolicyManager.java27
-rw-r--r--core/java/android/permission/PermissionManager.java1
-rw-r--r--core/java/android/provider/Settings.java3
-rw-r--r--core/java/android/security/ConfirmationPrompt.java180
-rw-r--r--core/java/android/security/keymaster/KeymasterCertificateChain.aidl (renamed from keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java)18
-rw-r--r--core/java/android/security/keystore/recovery/RecoveryController.java16
-rw-r--r--core/java/android/service/notification/NotificationListenerFilter.java14
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java23
-rw-r--r--core/java/android/text/method/TranslationTransformationMethod.java13
-rw-r--r--core/java/android/util/Slog.java27
-rw-r--r--core/java/android/util/TimeUtils.java33
-rw-r--r--core/java/android/uwb/RangingManager.java8
-rw-r--r--core/java/android/uwb/UwbManager.java31
-rw-r--r--core/java/android/view/InsetsState.java14
-rw-r--r--core/java/android/view/View.java5
-rw-r--r--core/java/android/view/inputmethod/EditorInfo.java8
-rw-r--r--core/java/android/widget/EdgeEffect.java35
-rw-r--r--core/java/com/android/internal/jank/FrameTracker.java64
-rw-r--r--core/java/com/android/internal/jank/InteractionJankMonitor.java45
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java7
-rw-r--r--core/java/com/android/internal/policy/DecorView.java26
-rw-r--r--core/res/res/values-af/strings.xml10
-rw-r--r--core/res/res/values-am/strings.xml4
-rw-r--r--core/res/res/values-ar/strings.xml64
-rw-r--r--core/res/res/values-as/strings.xml64
-rw-r--r--core/res/res/values-az/strings.xml64
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml6
-rw-r--r--core/res/res/values-be/strings.xml6
-rw-r--r--core/res/res/values-bg/strings.xml10
-rw-r--r--core/res/res/values-bn/strings.xml64
-rw-r--r--core/res/res/values-bs/strings.xml4
-rw-r--r--core/res/res/values-ca/strings.xml6
-rw-r--r--core/res/res/values-cs/strings.xml4
-rw-r--r--core/res/res/values-da/strings.xml34
-rw-r--r--core/res/res/values-de/strings.xml73
-rw-r--r--core/res/res/values-el/strings.xml88
-rw-r--r--core/res/res/values-en-rAU/strings.xml32
-rw-r--r--core/res/res/values-en-rCA/strings.xml32
-rw-r--r--core/res/res/values-en-rGB/strings.xml32
-rw-r--r--core/res/res/values-en-rIN/strings.xml32
-rw-r--r--core/res/res/values-en-rXC/strings.xml8
-rw-r--r--core/res/res/values-es-rUS/strings.xml94
-rw-r--r--core/res/res/values-es/strings.xml8
-rw-r--r--core/res/res/values-et/strings.xml4
-rw-r--r--core/res/res/values-eu/strings.xml4
-rw-r--r--core/res/res/values-fa/strings.xml10
-rw-r--r--core/res/res/values-fi/strings.xml64
-rw-r--r--core/res/res/values-fr-rCA/strings.xml64
-rw-r--r--core/res/res/values-fr/strings.xml7
-rw-r--r--core/res/res/values-gl/strings.xml4
-rw-r--r--core/res/res/values-gu/strings.xml69
-rw-r--r--core/res/res/values-hi/strings.xml64
-rw-r--r--core/res/res/values-hr/strings.xml4
-rw-r--r--core/res/res/values-hu/strings.xml4
-rw-r--r--core/res/res/values-hy/strings.xml4
-rw-r--r--core/res/res/values-in/strings.xml4
-rw-r--r--core/res/res/values-is/strings.xml28
-rw-r--r--core/res/res/values-it/strings.xml34
-rw-r--r--core/res/res/values-iw/strings.xml602
-rw-r--r--core/res/res/values-ja/strings.xml28
-rw-r--r--core/res/res/values-ka/strings.xml4
-rw-r--r--core/res/res/values-kk/strings.xml4
-rw-r--r--core/res/res/values-km/strings.xml64
-rw-r--r--core/res/res/values-kn/strings.xml64
-rw-r--r--core/res/res/values-ko/strings.xml8
-rw-r--r--core/res/res/values-ky/strings.xml64
-rw-r--r--core/res/res/values-lo/strings.xml64
-rw-r--r--core/res/res/values-lt/strings.xml4
-rw-r--r--core/res/res/values-lv/strings.xml4
-rw-r--r--core/res/res/values-mk/strings.xml4
-rw-r--r--core/res/res/values-ml/strings.xml4
-rw-r--r--core/res/res/values-mn/strings.xml28
-rw-r--r--core/res/res/values-mr/strings.xml7
-rw-r--r--core/res/res/values-ms/strings.xml8
-rw-r--r--core/res/res/values-my/strings.xml12
-rw-r--r--core/res/res/values-nb/strings.xml4
-rw-r--r--core/res/res/values-ne/strings.xml64
-rw-r--r--core/res/res/values-night/values.xml4
-rw-r--r--core/res/res/values-nl/strings.xml28
-rw-r--r--core/res/res/values-or/strings.xml37
-rw-r--r--core/res/res/values-pa/strings.xml67
-rw-r--r--core/res/res/values-pl/strings.xml64
-rw-r--r--core/res/res/values-pt-rBR/strings.xml28
-rw-r--r--core/res/res/values-pt-rPT/strings.xml4
-rw-r--r--core/res/res/values-pt/strings.xml28
-rw-r--r--core/res/res/values-ro/strings.xml64
-rw-r--r--core/res/res/values-ru/strings.xml64
-rw-r--r--core/res/res/values-si/strings.xml28
-rw-r--r--core/res/res/values-sk/strings.xml28
-rw-r--r--core/res/res/values-sl/strings.xml88
-rw-r--r--core/res/res/values-sq/strings.xml4
-rw-r--r--core/res/res/values-sr/strings.xml6
-rw-r--r--core/res/res/values-sv/strings.xml4
-rw-r--r--core/res/res/values-sw/strings.xml4
-rw-r--r--core/res/res/values-ta/strings.xml64
-rw-r--r--core/res/res/values-te/strings.xml64
-rw-r--r--core/res/res/values-th/strings.xml4
-rw-r--r--core/res/res/values-tl/strings.xml4
-rw-r--r--core/res/res/values-tr/strings.xml4
-rw-r--r--core/res/res/values-uk/strings.xml10
-rw-r--r--core/res/res/values-ur/strings.xml4
-rw-r--r--core/res/res/values-uz/strings.xml28
-rw-r--r--core/res/res/values-vi/strings.xml7
-rw-r--r--core/res/res/values-zh-rCN/strings.xml17
-rw-r--r--core/res/res/values-zh-rHK/strings.xml34
-rw-r--r--core/res/res/values-zh-rTW/strings.xml4
-rw-r--r--core/res/res/values-zu/strings.xml4
-rw-r--r--core/res/res/values/config.xml3
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/res/res/values/themes_device_defaults.xml6
-rw-r--r--core/tests/coretests/Android.bp1
-rw-r--r--core/tests/coretests/src/android/app/NotificationHistoryTest.java44
-rw-r--r--core/tests/coretests/src/android/window/OWNERS2
-rw-r--r--core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java20
-rw-r--r--core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java4
-rw-r--r--core/tests/uwbtests/src/android/uwb/RangingManagerTest.java25
-rw-r--r--data/etc/privapp-permissions-platform.xml2
-rw-r--r--graphics/java/android/graphics/RecordingCanvas.java11
-rw-r--r--graphics/java/android/graphics/drawable/RippleAnimationSession.java6
-rw-r--r--graphics/java/android/graphics/drawable/RippleShader.java21
-rw-r--r--keystore/java/android/security/AndroidKeyStoreMaintenance.java5
-rw-r--r--keystore/java/android/security/Authorization.java2
-rw-r--r--keystore/java/android/security/Credentials.java74
-rw-r--r--keystore/java/android/security/KeyChain.java25
-rw-r--r--keystore/java/android/security/KeyStore.java1337
-rw-r--r--keystore/java/android/security/LegacyVpnProfileStore.java37
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStore3DESCipherSpi.java298
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java449
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java279
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java920
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java202
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreECPrivateKey.java40
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreECPublicKey.java57
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java265
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKey.java103
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java151
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java352
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java986
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreLoadStoreParameter.java38
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreProvider.java364
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java71
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java515
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreRSAPrivateKey.java41
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreRSAPublicKey.java55
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java164
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java248
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSignatureSpiBase.java431
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSpi.java1112
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java319
-rw-r--r--keystore/java/android/security/keystore/AttestationUtils.java5
-rw-r--r--keystore/java/android/security/keystore/KeyGenParameterSpec.java20
-rw-r--r--keystore/java/android/security/keystore/KeyProtection.java1
-rw-r--r--keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java225
-rw-r--r--keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java42
-rw-r--r--keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java118
-rw-r--r--keystore/java/android/security/keystore/KeymasterUtils.java241
-rw-r--r--keystore/java/android/security/keystore/SecureKeyImportUnavailableException.java4
-rw-r--r--keystore/java/android/security/keystore/StrongBoxUnavailableException.java5
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java1
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java4
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java15
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java18
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java1
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java1
-rw-r--r--keystore/java/android/security/keystore2/KeymasterUtils.java124
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java4
-rw-r--r--libs/hwui/effects/StretchEffect.cpp4
-rw-r--r--media/java/android/media/IMediaRouterClient.aidl2
-rw-r--r--media/java/android/media/MediaRouter.java20
-rw-r--r--native/android/OWNERS8
-rw-r--r--packages/Connectivity/framework/Android.bp60
-rw-r--r--packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl4
-rw-r--r--packages/Connectivity/framework/api/current.txt2
-rw-r--r--packages/Connectivity/framework/api/system-current.txt2
-rw-r--r--packages/Connectivity/framework/jarjar-rules-proto.txt3
-rw-r--r--packages/Connectivity/framework/jarjar-rules.txt9
-rw-r--r--packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp50
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityManager.java23
-rw-r--r--packages/Connectivity/framework/src/android/net/DnsResolver.java2
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkCapabilities.java13
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkRequest.java24
-rw-r--r--packages/PackageInstaller/res/values-af/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-bg/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-bs/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-da/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-de/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-en-rAU/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-en-rCA/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-en-rGB/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-en-rIN/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-en-rXC/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-es-rUS/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-fa/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-hr/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-it/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-iw/strings.xml18
-rw-r--r--packages/PackageInstaller/res/values-tr/strings.xml18
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java99
-rw-r--r--packages/PrintSpooler/res/values-iw/strings.xml34
-rw-r--r--packages/PrintSpooler/res/values-ml/strings.xml111
-rw-r--r--packages/PrintSpooler/res/values-nl/strings.xml6
-rw-r--r--packages/SettingsLib/SettingsTheme/res/layout/settings_icon.xml (renamed from packages/SettingsLib/SettingsTheme/res/layout/image_frame.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/layout/settings_preference.xml2
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml17
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml11
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml1
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml1
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml1
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml1
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml1
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml11
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml2
-rw-r--r--packages/Shell/AndroidManifest.xml3
-rw-r--r--packages/Shell/res/values-iw/strings.xml12
-rw-r--r--packages/SystemUI/AndroidManifest.xml5
-rw-r--r--packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java16
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java6
-rw-r--r--packages/SystemUI/res-keyguard/values-iw/strings.xml52
-rw-r--r--packages/SystemUI/res-keyguard/values-nl/strings.xml12
-rw-r--r--packages/SystemUI/res-product/values-iw/strings.xml8
-rw-r--r--packages/SystemUI/res/drawable/brightness_progress_drawable.xml62
-rw-r--r--packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml37
-rw-r--r--packages/SystemUI/res/layout-land/global_actions_column.xml2
-rw-r--r--packages/SystemUI/res/layout-land/global_actions_column_seascape.xml2
-rw-r--r--packages/SystemUI/res/layout-land/global_actions_grid.xml2
-rw-r--r--packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml2
-rw-r--r--packages/SystemUI/res/layout/global_actions_column.xml2
-rw-r--r--packages/SystemUI/res/layout/global_actions_grid.xml2
-rw-r--r--packages/SystemUI/res/layout/global_actions_grid_v2.xml6
-rw-r--r--packages/SystemUI/res/layout/global_actions_view.xml2
-rw-r--r--packages/SystemUI/res/layout/long_screenshot.xml6
-rw-r--r--packages/SystemUI/res/layout/notification_conversation_info.xml59
-rw-r--r--packages/SystemUI/res/layout/qs_tile_label.xml3
-rw-r--r--packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml64
-rw-r--r--packages/SystemUI/res/layout/quick_settings_brightness_dialog_thick.xml43
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml2
-rw-r--r--packages/SystemUI/res/values-af/strings.xml6
-rw-r--r--packages/SystemUI/res/values-am/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml18
-rw-r--r--packages/SystemUI/res/values-as/strings.xml6
-rw-r--r--packages/SystemUI/res/values-az/strings.xml6
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-be/strings.xml8
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml18
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml6
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-da/strings.xml27
-rw-r--r--packages/SystemUI/res/values-de/strings.xml6
-rw-r--r--packages/SystemUI/res/values-el/strings.xml27
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml6
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml6
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml6
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml6
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml6
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml27
-rw-r--r--packages/SystemUI/res/values-es/strings.xml6
-rw-r--r--packages/SystemUI/res/values-et/strings.xml6
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml18
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-h740dp-port/dimens.xml4
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml8
-rw-r--r--packages/SystemUI/res/values-in/strings.xml6
-rw-r--r--packages/SystemUI/res/values-is/strings.xml27
-rw-r--r--packages/SystemUI/res/values-it/strings.xml27
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml202
-rw-r--r--packages/SystemUI/res/values-iw/strings_tv.xml2
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml27
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-km/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml18
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml6
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml6
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml27
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml6
-rw-r--r--packages/SystemUI/res/values-my/strings.xml6
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml6
-rw-r--r--packages/SystemUI/res/values-night/colors.xml2
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml27
-rw-r--r--packages/SystemUI/res/values-or/strings.xml27
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml27
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml27
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml6
-rw-r--r--packages/SystemUI/res/values-si/strings.xml27
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml27
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml27
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml27
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml6
-rw-r--r--packages/SystemUI/res/values-te/strings.xml6
-rw-r--r--packages/SystemUI/res/values-television/styles.xml2
-rw-r--r--packages/SystemUI/res/values-th/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml6
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml27
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml6
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml10
-rw-r--r--packages/SystemUI/res/values/flags.xml4
-rw-r--r--packages/SystemUI/res/values/ids.xml6
-rw-r--r--packages/SystemUI/res/values/strings.xml52
-rw-r--r--packages/SystemUI/res/values/styles.xml8
-rw-r--r--packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java9
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java100
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java76
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt71
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java192
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java89
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt (renamed from keystore/java/android/security/keystore/AndroidKeyStorePrivateKey.java)26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt173
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java103
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java70
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java64
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java65
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java95
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java198
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureFrameworkSmokeTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt76
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt151
-rw-r--r--packages/WAPPushManager/AndroidManifest.xml3
-rwxr-xr-xpackages/WAPPushManager/src/com/android/smspush/WapPushManager.java131
-rw-r--r--packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java57
-rw-r--r--services/Android.bp6
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java116
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java24
-rw-r--r--services/core/java/com/android/server/VcnManagementService.java77
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java82
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java14
-rw-r--r--services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java5
-rw-r--r--services/core/java/com/android/server/appop/DiscreteRegistry.java217
-rw-r--r--services/core/java/com/android/server/appop/HistoricalRegistry.java9
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java17
-rw-r--r--services/core/java/com/android/server/camera/CameraServiceProxy.java7
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java5
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java17
-rw-r--r--services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java2
-rw-r--r--services/core/java/com/android/server/locksettings/RebootEscrowKeyStoreManager.java15
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java15
-rw-r--r--services/core/java/com/android/server/media/MediaRouterService.java16
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java91
-rw-r--r--services/core/java/com/android/server/notification/NotificationHistoryDatabase.java48
-rw-r--r--services/core/java/com/android/server/notification/NotificationHistoryManager.java16
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java47
-rw-r--r--services/core/java/com/android/server/pm/IncrementalStates.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java81
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java8
-rw-r--r--services/core/java/com/android/server/pm/Settings.java4
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java14
-rw-r--r--services/core/java/com/android/server/storage/StorageSessionController.java9
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java4
-rw-r--r--services/core/java/com/android/server/utils/Slogf.java276
-rw-r--r--services/core/java/com/android/server/vcn/Vcn.java128
-rw-r--r--services/core/java/com/android/server/vcn/VcnGatewayConnection.java148
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java2
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java1
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java49
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java11
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java19
-rw-r--r--services/java/com/android/server/SystemServer.java5
-rw-r--r--services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java2
-rw-r--r--services/tests/PackageManagerServiceTests/host/Android.bp10
-rw-r--r--services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/intent/verify/IntentFilterVerificationTest.kt413
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/Android.bp37
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/AndroidManifest.xml38
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/src/com/android/server/pm/test/intent/verifier/VerifyReceiver.kt62
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/src/com/android/server/pm/test/intent/verifier/VerifyReceiverTest.kt164
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/Android.bp57
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest1.xml94
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest2.xml34
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest3.xml32
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4Base.xml33
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4NoAutoVerify.xml33
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4Wildcard.xml34
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4WildcardNoAutoVerify.xml34
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java46
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/utils/SlogfTest.java343
-rw-r--r--services/tests/servicestests/Android.bp1
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java101
-rw-r--r--services/tests/servicestests/src/com/android/server/am/DeviceConfigSession.java72
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java70
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java46
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java16
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java133
-rw-r--r--telephony/java/android/telephony/ims/SipMessage.java18
-rw-r--r--telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java7
-rw-r--r--telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java9
-rw-r--r--tests/ActivityManagerPerfTests/tests/Android.bp1
-rw-r--r--tests/ActivityManagerPerfTests/tests/AndroidTest.xml17
-rw-r--r--tests/net/common/java/android/net/NetworkCapabilitiesTest.java14
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java184
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java124
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java142
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java5
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java5
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java5
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java24
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnTest.java122
588 files changed, 7915 insertions, 15398 deletions
diff --git a/Android.bp b/Android.bp
index 7b3005682a66..9e1820e9f6ea 100644
--- a/Android.bp
+++ b/Android.bp
@@ -150,7 +150,6 @@ filegroup {
":incidentcompanion_aidl",
":inputconstants_aidl",
":installd_aidl",
- ":keystore_aidl",
":libaudioclient_aidl",
":libbinder_aidl",
":libbluetooth-binder-aidl",
@@ -351,8 +350,6 @@ java_defaults {
":framework-non-updatable-sources",
"core/java/**/*.logtags",
],
- // See comment on framework-atb-backward-compatibility module below
- exclude_srcs: ["core/java/android/content/pm/AndroidTestBaseUpdater.java"],
aidl: {
generate_get_transaction_name: true,
local_include_dirs: [
@@ -463,20 +460,6 @@ platform_compat_config {
src: ":framework-minus-apex",
}
-// A temporary build target that is conditionally included on the bootclasspath if
-// android.test.base library has been removed and which provides support for
-// maintaining backwards compatibility for APKs that target pre-P and depend on
-// android.test.base classes. This is used iff REMOVE_ATB_FROM_BCP=true is
-// specified on the build command line.
-java_library {
- name: "framework-atb-backward-compatibility",
- installable: true,
- libs: ["app-compat-annotations"],
- srcs: [
- "core/java/android/content/pm/AndroidTestBaseUpdater.java",
- ],
-}
-
genrule {
name: "statslog-framework-java-gen",
tools: ["stats-log-api-gen"],
@@ -1004,38 +987,6 @@ aidl_interface {
},
}
-// TODO(b/77285514): remove this once the last few hidl interfaces have been
-// updated to use hwbinder.stubs.
-java_library {
- name: "hwbinder",
- sdk_version: "core_platform",
-
- srcs: [
- "core/java/android/os/HidlSupport.java",
- "core/java/android/annotation/IntDef.java",
- "core/java/android/annotation/IntRange.java",
- "core/java/android/annotation/NonNull.java",
- "core/java/android/annotation/Nullable.java",
- "core/java/android/annotation/SystemApi.java",
- "core/java/android/annotation/TestApi.java",
- "core/java/android/os/HidlMemory.java",
- "core/java/android/os/HwBinder.java",
- "core/java/android/os/HwBlob.java",
- "core/java/android/os/HwParcel.java",
- "core/java/android/os/IHwBinder.java",
- "core/java/android/os/IHwInterface.java",
- "core/java/android/os/DeadObjectException.java",
- "core/java/android/os/DeadSystemException.java",
- "core/java/android/os/NativeHandle.java",
- "core/java/android/os/RemoteException.java",
- "core/java/android/util/AndroidException.java",
- ],
- libs: ["unsupportedappusage"],
-
- dxflags: ["--core-library"],
- installable: false,
-}
-
python_defaults {
name: "base_default",
version: {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index af867b936d72..41b342cc258c 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1220,6 +1220,7 @@ public class JobSchedulerService extends com.android.server.SystemService
void updateUidState(int uid, int procState) {
synchronized (mLock) {
+ final int prevPriority = mUidPriorityOverride.get(uid, JobInfo.PRIORITY_DEFAULT);
if (procState == ActivityManager.PROCESS_STATE_TOP) {
// Only use this if we are exactly the top app. All others can live
// with just the foreground priority. This means that persistent processes
@@ -1232,6 +1233,16 @@ public class JobSchedulerService extends com.android.server.SystemService
} else {
mUidPriorityOverride.delete(uid);
}
+ final int newPriority = mUidPriorityOverride.get(uid, JobInfo.PRIORITY_DEFAULT);
+ if (prevPriority != newPriority) {
+ if (DEBUG) {
+ Slog.d(TAG, "UID " + uid + " priority changed from " + prevPriority
+ + " to " + newPriority);
+ }
+ for (int c = 0; c < mControllers.size(); ++c) {
+ mControllers.get(c).onUidPriorityChangedLocked(uid, newPriority);
+ }
+ }
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index b97ca20b5d16..f30b75c1af93 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -29,6 +29,7 @@ import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.Network;
import android.net.NetworkCapabilities;
+import android.net.NetworkPolicyManager;
import android.net.NetworkRequest;
import android.os.Handler;
import android.os.Looper;
@@ -83,6 +84,19 @@ public final class ConnectivityController extends RestrictingController implemen
*/
private static final long MIN_STATS_UPDATE_INTERVAL_MS = 30_000L;
+ private static final int UNBYPASSABLE_BG_BLOCKED_REASONS =
+ ~ConnectivityManager.BLOCKED_REASON_NONE;
+ private static final int UNBYPASSABLE_EJ_BLOCKED_REASONS =
+ ~(ConnectivityManager.BLOCKED_REASON_APP_STANDBY
+ | ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER
+ | ConnectivityManager.BLOCKED_REASON_DOZE);
+ private static final int UNBYPASSABLE_FOREGROUND_BLOCKED_REASONS =
+ ~(ConnectivityManager.BLOCKED_REASON_APP_STANDBY
+ | ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER
+ | ConnectivityManager.BLOCKED_REASON_DOZE
+ | ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER
+ | ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED);
+
private final ConnectivityManager mConnManager;
private final NetworkPolicyManagerInternal mNetPolicyManagerInternal;
@@ -152,6 +166,9 @@ public final class ConnectivityController extends RestrictingController implemen
} else if (us1.earliestEJEnqueueTime > us2.earliestEJEnqueueTime) {
return 1;
}
+ if (us1.basePriority != us2.basePriority) {
+ return us2.basePriority - us1.basePriority;
+ }
if (us1.earliestEnqueueTime < us2.earliestEnqueueTime) {
return -1;
}
@@ -454,6 +471,16 @@ public final class ConnectivityController extends RestrictingController implemen
postAdjustCallbacks();
}
+ @GuardedBy("mLock")
+ @Override
+ public void onUidPriorityChangedLocked(int uid, int newPriority) {
+ UidStats uidStats = mUidStats.get(uid);
+ if (uidStats != null && uidStats.basePriority != newPriority) {
+ uidStats.basePriority = newPriority;
+ maybeAdjustRegisteredCallbacksLocked();
+ }
+ }
+
private boolean isUsable(NetworkCapabilities capabilities) {
return capabilities != null
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
@@ -757,6 +784,42 @@ public final class ConnectivityController extends RestrictingController implemen
}
}
+ @GuardedBy("mLock")
+ @Nullable
+ private Network getNetworkLocked(@NonNull JobStatus jobStatus) {
+ final UidDefaultNetworkCallback defaultNetworkCallback =
+ mCurrentDefaultNetworkCallbacks.get(jobStatus.getSourceUid());
+ if (defaultNetworkCallback == null) {
+ return null;
+ }
+
+ UidStats uidStats = mUidStats.get(jobStatus.getSourceUid());
+
+ final int unbypassableBlockedReasons;
+ // TOP will probably have fewer reasons, so we may not have to worry about returning
+ // BG_BLOCKED for a TOP app. However, better safe than sorry.
+ if (uidStats.basePriority >= JobInfo.PRIORITY_BOUND_FOREGROUND_SERVICE
+ || (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
+ if (DEBUG) {
+ Slog.d(TAG, "Using FG bypass for " + jobStatus.getSourceUid());
+ }
+ unbypassableBlockedReasons = UNBYPASSABLE_FOREGROUND_BLOCKED_REASONS;
+ } else if (jobStatus.shouldTreatAsExpeditedJob() || jobStatus.startedAsExpeditedJob) {
+ if (DEBUG) {
+ Slog.d(TAG, "Using EJ bypass for " + jobStatus.getSourceUid());
+ }
+ unbypassableBlockedReasons = UNBYPASSABLE_EJ_BLOCKED_REASONS;
+ } else {
+ if (DEBUG) {
+ Slog.d(TAG, "Using BG bypass for " + jobStatus.getSourceUid());
+ }
+ unbypassableBlockedReasons = UNBYPASSABLE_BG_BLOCKED_REASONS;
+ }
+
+ return (unbypassableBlockedReasons & defaultNetworkCallback.mBlockedReasons) == 0
+ ? defaultNetworkCallback.mDefaultNetwork : null;
+ }
+
private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
final long nowElapsed = sElapsedRealtimeClock.millis();
final UidDefaultNetworkCallback defaultNetworkCallback =
@@ -765,9 +828,7 @@ public final class ConnectivityController extends RestrictingController implemen
maybeRegisterDefaultNetworkCallbackLocked(jobStatus);
return updateConstraintsSatisfied(jobStatus, nowElapsed, null, null);
}
- final Network network =
- (jobStatus.shouldIgnoreNetworkBlocking() || !defaultNetworkCallback.mBlocked)
- ? defaultNetworkCallback.mDefaultNetwork : null;
+ final Network network = getNetworkLocked(jobStatus);
final NetworkCapabilities capabilities = getNetworkCapabilities(network);
return updateConstraintsSatisfied(jobStatus, nowElapsed, network, capabilities);
}
@@ -829,32 +890,15 @@ public final class ConnectivityController extends RestrictingController implemen
return false;
}
- final Network network = defaultNetworkCallback.mBlocked
- ? null : defaultNetworkCallback.mDefaultNetwork;
- final NetworkCapabilities capabilities = getNetworkCapabilities(network);
- final boolean networkMatch = (filterNetwork == null
- || Objects.equals(filterNetwork, network));
- // Ignore blocked
- final Network exemptedNetwork = defaultNetworkCallback.mDefaultNetwork;
- final NetworkCapabilities exemptedNetworkCapabilities =
- getNetworkCapabilities(exemptedNetwork);
- final boolean exemptedNetworkMatch =
- (filterNetwork == null || Objects.equals(filterNetwork, exemptedNetwork));
-
final long nowElapsed = sElapsedRealtimeClock.millis();
boolean changed = false;
for (int i = jobs.size() - 1; i >= 0; i--) {
final JobStatus js = jobs.valueAt(i);
- Network net = network;
- NetworkCapabilities netCap = capabilities;
- boolean match = networkMatch;
-
- if (js.shouldIgnoreNetworkBlocking()) {
- net = exemptedNetwork;
- netCap = exemptedNetworkCapabilities;
- match = exemptedNetworkMatch;
- }
+ final Network net = getNetworkLocked(js);
+ final NetworkCapabilities netCap = getNetworkCapabilities(net);
+ final boolean match = (filterNetwork == null
+ || Objects.equals(filterNetwork, net));
// Update either when we have a network match, or when the
// job hasn't yet been evaluated against the currently
@@ -950,7 +994,7 @@ public final class ConnectivityController extends RestrictingController implemen
private int mUid;
@Nullable
private Network mDefaultNetwork;
- private boolean mBlocked;
+ private int mBlockedReasons;
private void setUid(int uid) {
mUid = uid;
@@ -968,17 +1012,17 @@ public final class ConnectivityController extends RestrictingController implemen
}
@Override
- public void onBlockedStatusChanged(Network network, boolean blocked) {
+ public void onBlockedStatusChanged(Network network, int blockedReasons) {
if (DEBUG) {
Slog.v(TAG, "default-onBlockedStatusChanged(" + mUid + "): "
- + network + " -> " + blocked);
+ + network + " -> " + blockedReasons);
}
if (mUid == UserHandle.USER_NULL) {
return;
}
synchronized (mLock) {
mDefaultNetwork = network;
- mBlocked = blocked;
+ mBlockedReasons = blockedReasons;
updateTrackedJobsLocked(mUid, network);
}
}
@@ -1037,7 +1081,7 @@ public final class ConnectivityController extends RestrictingController implemen
pw.print("Network: ");
pw.print(mDefaultNetwork);
pw.print(" (blocked=");
- pw.print(mBlocked);
+ pw.print(NetworkPolicyManager.blockedReasonsToString(mBlockedReasons));
pw.print(")");
}
pw.println();
@@ -1046,6 +1090,7 @@ public final class ConnectivityController extends RestrictingController implemen
private static class UidStats {
public final int uid;
+ public int basePriority;
public int numRunning;
public int numReadyWithConnectivity;
public int numRequestedNetworkAvailable;
@@ -1062,6 +1107,7 @@ public final class ConnectivityController extends RestrictingController implemen
private void dumpLocked(IndentingPrintWriter pw, final long nowElapsed) {
pw.print("UidStats{");
pw.print("uid", uid);
+ pw.print("pri", basePriority);
pw.print("#run", numRunning);
pw.print("#readyWithConn", numReadyWithConnectivity);
pw.print("#netAvail", numRequestedNetworkAvailable);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index 80e68e9a883b..95eb220cfeb4 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -1139,11 +1139,6 @@ public final class JobStatus {
&& (mDynamicConstraints & CONSTRAINT_BACKGROUND_NOT_RESTRICTED) == 0);
}
- boolean shouldIgnoreNetworkBlocking() {
- return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0
- || (shouldTreatAsExpeditedJob() || startedAsExpeditedJob);
- }
-
/** @return true if the constraint was changed, false otherwise. */
boolean setChargingConstraintSatisfied(final long nowElapsed, boolean state) {
return setConstraintSatisfied(CONSTRAINT_CHARGING, nowElapsed, state);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
index a33ba5b3f8bc..334876f57f29 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
@@ -25,6 +25,7 @@ import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobSchedulerService.Constants;
import com.android.server.job.StateChangedListener;
@@ -125,6 +126,14 @@ public abstract class StateController {
public void reevaluateStateLocked(int uid) {
}
+ /**
+ * Called when a UID's base priority has changed. The more positive the priority, the more
+ * important the UID is.
+ */
+ @GuardedBy("mLock")
+ public void onUidPriorityChangedLocked(int uid, int newPriority) {
+ }
+
protected boolean wouldBeReadyWithConstraintLocked(JobStatus jobStatus, int constraint) {
// This is very cheap to check (just a few conditions on data in JobStatus).
final boolean jobWouldBeReady = jobStatus.wouldBeReadyWithConstraint(constraint);
diff --git a/config/hiddenapi-unsupported.txt b/config/hiddenapi-unsupported.txt
index 48aa8b2c2e30..4281b0dda41a 100644
--- a/config/hiddenapi-unsupported.txt
+++ b/config/hiddenapi-unsupported.txt
@@ -208,7 +208,6 @@ Landroid/os/storage/IObbActionListener$Stub;-><init>()V
Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
Landroid/security/IKeyChainService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/IKeyChainService;
-Landroid/security/keystore/IKeystoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/keystore/IKeystoreService;
Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager;
Landroid/service/notification/INotificationListener$Stub;-><init>()V
Landroid/service/persistentdata/IPersistentDataBlockService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/persistentdata/IPersistentDataBlockService;
diff --git a/core/api/current.txt b/core/api/current.txt
index 893616e05966..25dade12cec1 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9935,9 +9935,9 @@ package android.content {
public static final class AttributionSource.Builder {
ctor public AttributionSource.Builder(int);
method @NonNull public android.content.AttributionSource build();
- method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@NonNull String);
- method @NonNull public android.content.AttributionSource.Builder setNext(@NonNull android.content.AttributionSource);
- method @NonNull public android.content.AttributionSource.Builder setPackageName(@NonNull String);
+ method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@Nullable String);
+ method @NonNull public android.content.AttributionSource.Builder setNext(@Nullable android.content.AttributionSource);
+ method @NonNull public android.content.AttributionSource.Builder setPackageName(@Nullable String);
}
public abstract class BroadcastReceiver {
@@ -35050,7 +35050,7 @@ package android.provider {
field public static final String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
field public static final String ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS = "android.settings.APP_NOTIFICATION_BUBBLE_SETTINGS";
field public static final String ACTION_APP_NOTIFICATION_SETTINGS = "android.settings.APP_NOTIFICATION_SETTINGS";
- field public static final String ACTION_APP_OPEN_BY_DEFAULT_SETTINGS = "com.android.settings.APP_OPEN_BY_DEFAULT_SETTINGS";
+ field public static final String ACTION_APP_OPEN_BY_DEFAULT_SETTINGS = "android.settings.APP_OPEN_BY_DEFAULT_SETTINGS";
field public static final String ACTION_APP_SEARCH_SETTINGS = "android.settings.APP_SEARCH_SETTINGS";
field public static final String ACTION_APP_USAGE_SETTINGS = "android.settings.action.APP_USAGE_SETTINGS";
field public static final String ACTION_AUTO_ROTATE_SETTINGS = "android.settings.AUTO_ROTATE_SETTINGS";
@@ -38532,6 +38532,7 @@ package android.service.notification {
method public final java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups(@NonNull String, @NonNull android.os.UserHandle);
method public final java.util.List<android.app.NotificationChannel> getNotificationChannels(@NonNull String, @NonNull android.os.UserHandle);
method public final android.service.notification.StatusBarNotification[] getSnoozedNotifications();
+ method public final void migrateNotificationFilter(int, @Nullable java.util.List<java.lang.String>);
method public android.os.IBinder onBind(android.content.Intent);
method public void onInterruptionFilterChanged(int);
method public void onListenerConnected();
@@ -51680,8 +51681,8 @@ package android.view.inputmethod {
method public void dump(android.util.Printer, String);
method @Nullable public CharSequence getInitialSelectedText(int);
method @Nullable public android.view.inputmethod.SurroundingText getInitialSurroundingText(@IntRange(from=0) int, @IntRange(from=0) int, int);
- method @Nullable public CharSequence getInitialTextAfterCursor(int, int);
- method @Nullable public CharSequence getInitialTextBeforeCursor(int, int);
+ method @Nullable public CharSequence getInitialTextAfterCursor(@IntRange(from=0) int, int);
+ method @Nullable public CharSequence getInitialTextBeforeCursor(@IntRange(from=0) int, int);
method public final void makeCompatible(int);
method public void setInitialSurroundingSubText(@NonNull CharSequence, int);
method public void setInitialSurroundingText(@NonNull CharSequence);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 4fb9926e7742..869d7909c555 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -61,6 +61,7 @@ package android.content {
public abstract class Context {
method @NonNull public android.os.UserHandle getUser();
+ field public static final String PAC_PROXY_SERVICE = "pac_proxy";
field public static final String TEST_NETWORK_SERVICE = "test_network";
}
@@ -78,14 +79,6 @@ package android.content.pm {
}
-package android.content.rollback {
-
- public class RollbackManagerFrameworkInitializer {
- method public static void initialize();
- }
-
-}
-
package android.hardware.usb {
public class UsbManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 3f2aa79da3fc..a81411b8a091 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2235,7 +2235,7 @@ package android.content {
}
public static final class AttributionSource.Builder {
- method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.AttributionSource.Builder setRenouncedPermissions(@NonNull java.util.Set<java.lang.String>);
+ method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.AttributionSource.Builder setRenouncedPermissions(@Nullable java.util.Set<java.lang.String>);
}
public abstract class BroadcastReceiver {
@@ -13591,7 +13591,7 @@ package android.telephony.ims {
method @NonNull public byte[] getEncodedMessage();
method @NonNull public String getHeaderSection();
method @NonNull public String getStartLine();
- method @Nullable public String getViaBranchParameter();
+ method @NonNull public String getViaBranchParameter();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.SipMessage> CREATOR;
}
@@ -14237,7 +14237,7 @@ package android.uwb {
public final class UwbManager {
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public long elapsedRealtimeResolutionNanos();
method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.PersistableBundle getSpecificationInfo();
- method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
+ method @NonNull @RequiresPermission(allOf={android.Manifest.permission.UWB_PRIVILEGED, android.Manifest.permission.UWB_RANGING}) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback);
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback);
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 7b6f9b3f2b26..90a3667016de 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -666,6 +666,7 @@ package android.content {
public final class AttributionSource implements android.os.Parcelable {
ctor public AttributionSource(int, @Nullable String, @Nullable String);
ctor public AttributionSource(int, @Nullable String, @Nullable String, @Nullable android.content.AttributionSource);
+ ctor public AttributionSource(int, @Nullable String, @Nullable String, @Nullable java.util.Set<java.lang.String>, @Nullable android.content.AttributionSource);
}
public final class AutofillOptions implements android.os.Parcelable {
@@ -1985,6 +1986,7 @@ package android.permission {
public final class PermissionManager {
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData();
+ method @NonNull public android.content.AttributionSource registerAttributionSource(@NonNull android.content.AttributionSource);
}
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0f38b5fdb5c3..f0d5a893bb96 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5254,32 +5254,17 @@ public class Activity extends ContextThemeWrapper
return;
}
- List<String> filteredPermissions = null;
-
if (!getAttributionSource().getRenouncedPermissions().isEmpty()) {
final int permissionCount = permissions.length;
for (int i = 0; i < permissionCount; i++) {
if (getAttributionSource().getRenouncedPermissions().contains(permissions[i])) {
- if (filteredPermissions == null) {
- filteredPermissions = new ArrayList<>(i);
- for (int j = 0; j < i; j++) {
- filteredPermissions.add(permissions[i]);
- }
- }
- } else if (filteredPermissions != null) {
- filteredPermissions.add(permissions[i]);
+ throw new IllegalArgumentException("Cannot request renounced permission: "
+ + permissions[i]);
}
}
}
- final Intent intent;
- if (filteredPermissions == null) {
- intent = getPackageManager().buildRequestPermissionsIntent(permissions);
- } else {
- intent = getPackageManager().buildRequestPermissionsIntent(
- filteredPermissions.toArray(new String[0]));
- }
-
+ final Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
mHasCurrentPermissionsRequest = true;
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index eb31b5294a26..89312f4b3837 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -115,6 +115,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.Executor;
class ReceiverRestrictedContext extends ContextWrapper {
@@ -3074,14 +3075,16 @@ class ContextImpl extends Context {
mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName;
mParams = Objects.requireNonNull(params);
- mAttributionSource = createAttributionSource(attributionTag, nextAttributionSource);
+ mAttributionSource = createAttributionSource(attributionTag, nextAttributionSource,
+ params.getRenouncedPermissions());
mContentResolver = new ApplicationContentResolver(this, mainThread);
}
private @NonNull AttributionSource createAttributionSource(@Nullable String attributionTag,
- @Nullable AttributionSource nextAttributionSource) {
- AttributionSource attributionSource = new AttributionSource(Process.myUid(), mOpPackageName,
- attributionTag, nextAttributionSource);
+ @Nullable AttributionSource nextAttributionSource,
+ @Nullable Set<String> renouncedPermissions) {
+ AttributionSource attributionSource = new AttributionSource(Process.myUid(),
+ mOpPackageName, attributionTag, renouncedPermissions, nextAttributionSource);
// If we want to access protected data on behalf of another app we need to
// tell the OS that we opt in to participate in the attribution chain.
if (nextAttributionSource != null) {
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index d0e17f00e990..dab5aff5c9a8 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -228,6 +228,7 @@ interface INotificationManager
NotificationListenerFilter getListenerFilter(in ComponentName cn, int userId);
void setListenerFilter(in ComponentName cn, int userId, in NotificationListenerFilter nlf);
+ void migrateNotificationFilter(in INotificationListener token, int defaultTypes, in List<String> disallowedPkgs);
void setToastRateLimitingEnabled(boolean enable);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 92f707e543c8..3de78f6e3cab 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5358,8 +5358,8 @@ public class Notification implements Parcelable
int pillColor = getProtectionColor(p);
contentView.setInt(R.id.expand_button, "setDefaultTextColor", textColor);
contentView.setInt(R.id.expand_button, "setDefaultPillColor", pillColor);
- // Use different highlighted colors except when low-priority mode prevents that
- if (!p.mReduceHighlights) {
+ // Use different highlighted colors for conversations' unread count
+ if (p.mHighlightExpander) {
pillColor = getAccentTertiaryColor(p);
// TODO(b/183710694): The accent tertiary is currently too bright in dark mode, so
// we need to pick a contrasting color.
@@ -5993,7 +5993,7 @@ public class Notification implements Parcelable
.viewType(StandardTemplateParams.VIEW_TYPE_PUBLIC)
.fillTextsFrom(this);
if (isLowPriority) {
- params.reduceHighlights();
+ params.highlightExpander(false);
}
view = makeNotificationHeader(params);
view.setBoolean(R.id.notification_header, "setExpandOnlyOnButton", true);
@@ -6016,7 +6016,7 @@ public class Notification implements Parcelable
public RemoteViews makeLowPriorityContentView(boolean useRegularSubtext) {
StandardTemplateParams p = mParams.reset()
.viewType(StandardTemplateParams.VIEW_TYPE_MINIMIZED)
- .reduceHighlights()
+ .highlightExpander(false)
.fillTextsFrom(this);
if (!useRegularSubtext || TextUtils.isEmpty(mParams.summaryText)) {
p.summaryText(createSummaryText());
@@ -8293,6 +8293,7 @@ public class Notification implements Parcelable
StandardTemplateParams p = mBuilder.mParams.reset()
.viewType(isCollapsed ? StandardTemplateParams.VIEW_TYPE_NORMAL
: StandardTemplateParams.VIEW_TYPE_BIG)
+ .highlightExpander(isConversationLayout)
.hideProgress(true)
.title(conversationTitle)
.text(null)
@@ -12178,7 +12179,7 @@ public class Notification implements Parcelable
int maxRemoteInputHistory = Style.MAX_REMOTE_INPUT_HISTORY_LINES;
boolean hideLargeIcon;
boolean allowColorization = true;
- boolean mReduceHighlights = false;
+ boolean mHighlightExpander = false;
final StandardTemplateParams reset() {
mViewType = VIEW_TYPE_UNSPECIFIED;
@@ -12202,7 +12203,7 @@ public class Notification implements Parcelable
maxRemoteInputHistory = Style.MAX_REMOTE_INPUT_HISTORY_LINES;
hideLargeIcon = false;
allowColorization = true;
- mReduceHighlights = false;
+ mHighlightExpander = false;
return this;
}
@@ -12310,8 +12311,8 @@ public class Notification implements Parcelable
return this;
}
- final StandardTemplateParams reduceHighlights() {
- this.mReduceHighlights = true;
+ final StandardTemplateParams highlightExpander(boolean highlight) {
+ this.mHighlightExpander = highlight;
return this;
}
diff --git a/core/java/android/app/NotificationHistory.java b/core/java/android/app/NotificationHistory.java
index 0c8188b9a51e..eb9ec869af12 100644
--- a/core/java/android/app/NotificationHistory.java
+++ b/core/java/android/app/NotificationHistory.java
@@ -404,6 +404,26 @@ public final class NotificationHistory implements Parcelable {
}
/**
+ * Removes all notifications from a channel and regenerates the string pool
+ */
+ public boolean removeChannelFromWrite(String packageName, String channelId) {
+ boolean removed = false;
+ for (int i = mNotificationsToWrite.size() - 1; i >= 0; i--) {
+ HistoricalNotification hn = mNotificationsToWrite.get(i);
+ if (packageName.equals(hn.getPackage())
+ && Objects.equals(channelId, hn.getChannelId())) {
+ removed = true;
+ mNotificationsToWrite.remove(i);
+ }
+ }
+ if (removed) {
+ poolStringsFromNotifications();
+ }
+
+ return removed;
+ }
+
+ /**
* Gets pooled strings in order to write them to disk
*/
public @NonNull String[] getPooledStringsToWrite() {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 31b0d413c395..47a9fbb5fe4a 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -722,7 +722,7 @@ public final class SystemServiceRegistry {
new CachedServiceFetcher<UwbManager>() {
@Override
public UwbManager createService(ContextImpl ctx) {
- return UwbManager.getInstance();
+ return UwbManager.getInstance(ctx);
}
});
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 0be7b732b4bd..5446deb5605a 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -38,12 +38,14 @@ import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
import android.content.Context;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.ParcelUuid;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -853,8 +855,8 @@ public final class BluetoothAdapter {
}
synchronized (mLock) {
if (sBluetoothLeScanner == null) {
- sBluetoothLeScanner = new BluetoothLeScanner(mManagerService, getOpPackageName(),
- getAttributionTag());
+ sBluetoothLeScanner =
+ new BluetoothLeScanner(mManagerService, getAttributionSource());
}
}
return sBluetoothLeScanner;
@@ -1664,13 +1666,11 @@ public final class BluetoothAdapter {
return ActivityThread.currentOpPackageName();
}
- private String getAttributionTag() {
- // Workaround for legacy API for getting a BluetoothAdapter not
- // passing a context
+ private AttributionSource getAttributionSource() {
if (mContext != null) {
- return mContext.getAttributionTag();
+ return mContext.getAttributionSource();
}
- return null;
+ return new AttributionSource(Process.myUid(), ActivityThread.currentOpPackageName(), null);
}
/**
@@ -1710,7 +1710,7 @@ public final class BluetoothAdapter {
try {
mServiceLock.readLock().lock();
if (mService != null) {
- return mService.startDiscovery(getOpPackageName(), getAttributionTag());
+ return mService.startDiscovery(getAttributionSource());
}
} catch (RemoteException e) {
Log.e(TAG, "", e);
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 2888fbd8a363..2601cd4300ea 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -26,6 +26,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
+import android.content.AttributionSource;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
@@ -82,9 +83,7 @@ public final class BluetoothLeScanner {
private final Handler mHandler;
private BluetoothAdapter mBluetoothAdapter;
private final Map<ScanCallback, BleScanCallbackWrapper> mLeScanClients;
-
- private final String mOpPackageName;
- private final String mFeatureId;
+ private final AttributionSource mAttributionSource;
/**
* Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
@@ -95,13 +94,12 @@ public final class BluetoothLeScanner {
* @hide
*/
public BluetoothLeScanner(IBluetoothManager bluetoothManager,
- @NonNull String opPackageName, @Nullable String featureId) {
+ @NonNull AttributionSource attributionSource) {
mBluetoothManager = bluetoothManager;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = new Handler(Looper.getMainLooper());
mLeScanClients = new HashMap<ScanCallback, BleScanCallbackWrapper>();
- mOpPackageName = opPackageName;
- mFeatureId = featureId;
+ mAttributionSource = attributionSource;
}
/**
@@ -256,8 +254,7 @@ public final class BluetoothLeScanner {
wrapper.startRegistration();
} else {
try {
- gatt.startScanForIntent(callbackIntent, settings, filters, mOpPackageName,
- mFeatureId);
+ gatt.startScanForIntent(callbackIntent, settings, filters, mAttributionSource);
} catch (RemoteException e) {
return ScanCallback.SCAN_FAILED_INTERNAL_ERROR;
}
@@ -298,7 +295,7 @@ public final class BluetoothLeScanner {
IBluetoothGatt gatt;
try {
gatt = mBluetoothManager.getBluetoothGatt();
- gatt.stopScanForIntent(callbackIntent, mOpPackageName);
+ gatt.stopScanForIntent(callbackIntent);
} catch (RemoteException e) {
}
}
@@ -458,7 +455,7 @@ public final class BluetoothLeScanner {
} else {
mScannerId = scannerId;
mBluetoothGatt.startScan(mScannerId, mSettings, mFilters,
- mResultStorages, mOpPackageName, mFeatureId);
+ mResultStorages, mAttributionSource);
}
} catch (RemoteException e) {
Log.e(TAG, "fail to start le scan: " + e);
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
index 053bfc1a3253..c851519e9b50 100644
--- a/core/java/android/content/AttributionSource.java
+++ b/core/java/android/content/AttributionSource.java
@@ -179,6 +179,15 @@ public final class AttributionSource implements Parcelable {
}
/** @hide */
+ @TestApi
+ public AttributionSource(int uid, @Nullable String packageName,
+ @Nullable String attributionTag, @Nullable Set<String> renouncedPermissions,
+ @Nullable AttributionSource next) {
+ this(uid, packageName, attributionTag, /*token*/ null,
+ renouncedPermissions, next);
+ }
+
+ /** @hide */
public AttributionSource(@NonNull AttributionSource current,
@Nullable AttributionSource next) {
this(current.getUid(), current.getPackageName(), current.getAttributionTag(),
@@ -526,7 +535,7 @@ public final class AttributionSource implements Parcelable {
/**
* The package that is accessing the permission protected data.
*/
- public @NonNull Builder setPackageName(@NonNull String value) {
+ public @NonNull Builder setPackageName(@Nullable String value) {
checkNotUsed();
mBuilderFieldsSet |= 0x2;
mPackageName = value;
@@ -536,7 +545,7 @@ public final class AttributionSource implements Parcelable {
/**
* The attribution tag of the app accessing the permission protected data.
*/
- public @NonNull Builder setAttributionTag(@NonNull String value) {
+ public @NonNull Builder setAttributionTag(@Nullable String value) {
checkNotUsed();
mBuilderFieldsSet |= 0x4;
mAttributionTag = value;
@@ -550,7 +559,7 @@ public final class AttributionSource implements Parcelable {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
- public @NonNull Builder setRenouncedPermissions(@NonNull Set<String> value) {
+ public @NonNull Builder setRenouncedPermissions(@Nullable Set<String> value) {
checkNotUsed();
mBuilderFieldsSet |= 0x10;
mRenouncedPermissions = value;
@@ -560,7 +569,7 @@ public final class AttributionSource implements Parcelable {
/**
* The next app to receive the permission protected data.
*/
- public @NonNull Builder setNext(@NonNull AttributionSource value) {
+ public @NonNull Builder setNext(@Nullable AttributionSource value) {
checkNotUsed();
mBuilderFieldsSet |= 0x20;
mNext = value;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 232daa8f8b47..36769825c439 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4165,6 +4165,7 @@ public abstract class Context {
* @see android.net.PacProxyManager
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final String PAC_PROXY_SERVICE = "pac_proxy";
/**
diff --git a/core/java/android/content/ContextParams.java b/core/java/android/content/ContextParams.java
index bd3eaea24126..ace2ba721c10 100644
--- a/core/java/android/content/ContextParams.java
+++ b/core/java/android/content/ContextParams.java
@@ -16,10 +16,13 @@
package android.content;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.app.ActivityThread;
+import android.content.pm.PackageManager;
import java.util.Collections;
import java.util.Objects;
@@ -179,6 +182,13 @@ public final class ContextParams {
@RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
public @NonNull Builder setRenouncedPermissions(
@Nullable Set<String> renouncedPermissions) {
+ // This is not a security check but a fail fast - the OS enforces the permission too
+ if (renouncedPermissions != null && !renouncedPermissions.isEmpty()
+ && ActivityThread.currentApplication().checkSelfPermission(Manifest.permission
+ .RENOUNCE_PERMISSIONS) != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Renouncing permissions requires: "
+ + Manifest.permission.RENOUNCE_PERMISSIONS);
+ }
mRenouncedPermissions = renouncedPermissions;
return this;
}
diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java
index fc963fef3eb4..049bfe7f23fb 100644
--- a/core/java/android/content/PermissionChecker.java
+++ b/core/java/android/content/PermissionChecker.java
@@ -979,7 +979,9 @@ public final class PermissionChecker {
int uid, @NonNull Set<String> renouncedPermissions) {
final boolean permissionGranted = context.checkPermission(permission, /*pid*/ -1,
uid) == PackageManager.PERMISSION_GRANTED;
- if (permissionGranted && renouncedPermissions.contains(permission)) {
+ if (permissionGranted && renouncedPermissions.contains(permission)
+ && context.checkPermission(Manifest.permission.RENOUNCE_PERMISSIONS,
+ /*pid*/ -1, uid) == PackageManager.PERMISSION_GRANTED) {
return false;
}
return permissionGranted;
diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
index 72c9879c9360..97e1b543520e 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
@@ -72,7 +72,6 @@ import com.android.internal.util.Parcelling.BuiltIn.ForInternedStringValueMap;
import com.android.internal.util.Parcelling.BuiltIn.ForStringSet;
import java.security.PublicKey;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -1346,7 +1345,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
this.gwpAsanMode = in.readInt();
this.minExtensionVersions = in.readSparseIntArray();
this.mBooleans = in.readLong();
- this.mProperties = in.createTypedArrayMap(Property.CREATOR);
+ this.mProperties = in.readHashMap(boot);
this.memtagMode = in.readInt();
this.nativeHeapZeroInitialized = in.readInt();
this.requestOptimizedExternalStorageAccess = sForBoolean.unparcel(in);
diff --git a/core/java/android/content/rollback/RollbackManagerFrameworkInitializer.java b/core/java/android/content/rollback/RollbackManagerFrameworkInitializer.java
index c5e4f9947550..24617a0bcb9a 100644
--- a/core/java/android/content/rollback/RollbackManagerFrameworkInitializer.java
+++ b/core/java/android/content/rollback/RollbackManagerFrameworkInitializer.java
@@ -15,7 +15,6 @@
*/
package android.content.rollback;
-import android.annotation.SystemApi;
import android.app.SystemServiceRegistry;
import android.content.Context;
@@ -24,7 +23,6 @@ import android.content.Context;
*
* @hide
*/
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public class RollbackManagerFrameworkInitializer {
private RollbackManagerFrameworkInitializer() {}
diff --git a/core/java/android/hardware/biometrics/BiometricTestSession.java b/core/java/android/hardware/biometrics/BiometricTestSession.java
index ff1a17e07c11..41672b7cbaea 100644
--- a/core/java/android/hardware/biometrics/BiometricTestSession.java
+++ b/core/java/android/hardware/biometrics/BiometricTestSession.java
@@ -38,7 +38,7 @@ import java.util.concurrent.TimeUnit;
*/
@TestApi
public class BiometricTestSession implements AutoCloseable {
- private static final String TAG = "BiometricTestSession";
+ private static final String BASE_TAG = "BiometricTestSession";
/**
* @hide
@@ -66,12 +66,12 @@ public class BiometricTestSession implements AutoCloseable {
private final ITestSessionCallback mCallback = new ITestSessionCallback.Stub() {
@Override
public void onCleanupStarted(int userId) {
- Log.d(TAG, "onCleanupStarted, sensor: " + mSensorId + ", userId: " + userId);
+ Log.d(getTag(), "onCleanupStarted, sensor: " + mSensorId + ", userId: " + userId);
}
@Override
public void onCleanupFinished(int userId) {
- Log.d(TAG, "onCleanupFinished, sensor: " + mSensorId
+ Log.d(getTag(), "onCleanupFinished, sensor: " + mSensorId
+ ", userId: " + userId
+ ", remaining users: " + mUsersCleaningUp.size());
mUsersCleaningUp.remove(userId);
@@ -107,7 +107,7 @@ public class BiometricTestSession implements AutoCloseable {
@RequiresPermission(TEST_BIOMETRIC)
private void setTestHalEnabled(boolean enabled) {
try {
- Log.w(TAG, "setTestHalEnabled, sensor: " + mSensorId + " enabled: " + enabled);
+ Log.w(getTag(), "setTestHalEnabled, sensor: " + mSensorId + " enabled: " + enabled);
mTestSession.setTestHalEnabled(enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -217,7 +217,7 @@ public class BiometricTestSession implements AutoCloseable {
public void cleanupInternalState(int userId) {
try {
if (mUsersCleaningUp.contains(userId)) {
- Log.w(TAG, "Cleanup already in progress for user: " + userId);
+ Log.w(getTag(), "Cleanup already in progress for user: " + userId);
}
mUsersCleaningUp.add(userId);
@@ -230,6 +230,7 @@ public class BiometricTestSession implements AutoCloseable {
@Override
@RequiresPermission(TEST_BIOMETRIC)
public void close() {
+ Log.d(getTag(), "Close, mTestedUsers size; " + mTestedUsers.size());
// Cleanup can be performed using the test HAL, since it always responds to enumerate with
// zero enrollments.
if (!mTestedUsers.isEmpty()) {
@@ -239,15 +240,19 @@ public class BiometricTestSession implements AutoCloseable {
}
try {
- Log.d(TAG, "Awaiting latch...");
- mCloseLatch.await(10, TimeUnit.SECONDS);
- Log.d(TAG, "Finished awaiting");
+ Log.d(getTag(), "Awaiting latch...");
+ mCloseLatch.await(3, TimeUnit.SECONDS);
+ Log.d(getTag(), "Finished awaiting");
} catch (InterruptedException e) {
- Log.e(TAG, "Latch interrupted", e);
+ Log.e(getTag(), "Latch interrupted", e);
}
}
// Disable the test HAL after the sensor becomes idle.
setTestHalEnabled(false);
}
+
+ private String getTag() {
+ return BASE_TAG + "_" + mSensorId;
+ }
}
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 1e62a15772e9..c1009ffb3814 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -1503,7 +1503,11 @@ public final class CameraManager {
*/
public boolean cameraIdHasConcurrentStreamsLocked(String cameraId) {
if (!mDeviceStatus.containsKey(cameraId)) {
- Log.e(TAG, "cameraIdHasConcurrentStreamsLocked called on non existing camera id");
+ // physical camera ids aren't advertised in concurrent camera id combinations.
+ if (DEBUG) {
+ Log.v(TAG, " physical camera id " + cameraId + " is hidden." +
+ " Available logical camera ids : " + mDeviceStatus.toString());
+ }
return false;
}
for (Set<String> comb : mConcurrentCameraIdCombinations) {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java b/core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java
index 8eb1dccdf65e..bf4593260a70 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java
@@ -25,6 +25,7 @@ import android.media.Image;
import android.media.ImageReader;
import android.media.ImageWriter;
import android.annotation.NonNull;
+import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.util.Size;
@@ -39,6 +40,7 @@ public class CameraExtensionForwardProcessor {
private final IPreviewImageProcessorImpl mProcessor;
private final long mOutputSurfaceUsage;
private final int mOutputSurfaceFormat;
+ private final Handler mHandler;
private ImageReader mIntermediateReader = null;
private Surface mIntermediateSurface = null;
@@ -48,10 +50,11 @@ public class CameraExtensionForwardProcessor {
private boolean mOutputAbandoned = false;
public CameraExtensionForwardProcessor(@NonNull IPreviewImageProcessorImpl processor,
- int format, long surfaceUsage) {
+ int format, long surfaceUsage, @NonNull Handler handler) {
mProcessor = processor;
mOutputSurfaceUsage = surfaceUsage;
mOutputSurfaceFormat = format;
+ mHandler = handler;
}
public void close() {
@@ -98,7 +101,7 @@ public class CameraExtensionForwardProcessor {
mResolution.getHeight(), CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT,
FORWARD_QUEUE_SIZE, mOutputSurfaceUsage);
mIntermediateSurface = mIntermediateReader.getSurface();
- mIntermediateReader.setOnImageAvailableListener(new ForwardCallback(), null);
+ mIntermediateReader.setOnImageAvailableListener(new ForwardCallback(), mHandler);
mProcessor.onOutputSurface(mIntermediateSurface, mOutputSurfaceFormat);
// PreviewImageProcessorImpl always expect the extension processing format as input
@@ -124,11 +127,15 @@ public class CameraExtensionForwardProcessor {
@Override public void onImageAvailable(ImageReader reader) {
Image processedImage = null;
try {
- processedImage = mIntermediateReader.acquireNextImage();
+ processedImage = reader.acquireNextImage();
} catch (IllegalStateException e) {
Log.e(TAG, "Failed to acquire processed image!");
return;
}
+ if (processedImage == null) {
+ Log.e(TAG, "Invalid image");
+ return;
+ }
if (mOutputSurface != null && mOutputSurface.isValid() && !mOutputAbandoned) {
if (mOutputWriter == null) {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 1f5098f80735..3d771c01e8ac 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -352,7 +352,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
try {
mPreviewImageProcessor = new CameraExtensionForwardProcessor(
mPreviewExtender.getPreviewImageProcessor(), repeatingSurfaceInfo.mFormat,
- repeatingSurfaceInfo.mUsage);
+ repeatingSurfaceInfo.mUsage, mHandler);
} catch (ClassCastException e) {
throw new UnsupportedOperationException("Failed casting preview processor!");
}
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 171c6a2c6a19..f50aa991a67c 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -78,5 +78,4 @@ interface INetworkPolicyManager {
boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork);
boolean isUidRestrictedOnMeteredNetworks(int uid);
- boolean checkUidNetworkingBlocked(int uid, int uidRules, boolean isNetworkMetered, boolean isBackgroundRestricted);
}
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index b037261f0bc2..1eef7d9a5337 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -198,15 +198,11 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
final int oemManaged = getOemBitfield(snapshot.networkCapabilities);
if (legacyType == TYPE_WIFI) {
- if (snapshot.networkCapabilities.getSsid() != null) {
- networkId = snapshot.networkCapabilities.getSsid();
- if (networkId == null) {
- // TODO: Figure out if this code path never runs. If so, remove them.
- final WifiManager wifi = (WifiManager) context.getSystemService(
- Context.WIFI_SERVICE);
- final WifiInfo info = wifi.getConnectionInfo();
- networkId = info != null ? info.getSSID() : null;
- }
+ networkId = snapshot.networkCapabilities.getSsid();
+ if (networkId == null) {
+ final WifiManager wifi = context.getSystemService(WifiManager.class);
+ final WifiInfo info = wifi.getConnectionInfo();
+ networkId = info != null ? info.getSSID() : null;
}
}
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 68606ec90dc9..632eb15ecdde 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -564,31 +564,6 @@ public class NetworkPolicyManager {
}
/**
- * Figure out if networking is blocked for a given set of conditions.
- *
- * This is used by ConnectivityService via passing stale copies of conditions, so it must not
- * take any locks.
- *
- * @param uid The target uid.
- * @param uidRules The uid rules which are obtained from NetworkPolicyManagerService.
- * @param isNetworkMetered True if the network is metered.
- * @param isBackgroundRestricted True if data saver is enabled.
- *
- * @return true if networking is blocked for the UID under the specified conditions.
- *
- * @hide
- */
- public boolean checkUidNetworkingBlocked(int uid, int uidRules,
- boolean isNetworkMetered, boolean isBackgroundRestricted) {
- try {
- return mService.checkUidNetworkingBlocked(uid, uidRules, isNetworkMetered,
- isBackgroundRestricted);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Check that the given uid is restricted from doing networking on metered networks.
*
* @param uid The target uid.
@@ -794,7 +769,7 @@ public class NetworkPolicyManager {
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@NonNull
public static String blockedReasonsToString(int blockedReasons) {
- return DebugUtils.flagsToString(NetworkPolicyManager.class, "BLOCKED_", blockedReasons);
+ return DebugUtils.flagsToString(ConnectivityManager.class, "BLOCKED_", blockedReasons);
}
/**
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 936cbfc70708..751e9aafdf09 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1114,6 +1114,7 @@ public final class PermissionManager {
*
* @hide
*/
+ @TestApi
public @NonNull AttributionSource registerAttributionSource(@NonNull AttributionSource source) {
try {
return mPermissionManager.registerAttributionSource(source);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ecb1700bf7d5..eb562b7067f2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -471,10 +471,9 @@ public final class Settings {
* <p>
* Output: Nothing.
*/
- @SuppressLint("ActionValue")
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_APP_OPEN_BY_DEFAULT_SETTINGS =
- "com.android.settings.APP_OPEN_BY_DEFAULT_SETTINGS";
+ "android.settings.APP_OPEN_BY_DEFAULT_SETTINGS";
/**
* Activity Action: Show trusted credentials settings, opening to the user tab,
diff --git a/core/java/android/security/ConfirmationPrompt.java b/core/java/android/security/ConfirmationPrompt.java
index 232903724d82..d8c44adcc322 100644
--- a/core/java/android/security/ConfirmationPrompt.java
+++ b/core/java/android/security/ConfirmationPrompt.java
@@ -21,7 +21,6 @@ import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
-import android.security.keystore.AndroidKeyStoreProvider;
import android.text.TextUtils;
import android.util.Log;
@@ -106,32 +105,6 @@ public class ConfirmationPrompt {
private void doCallback(int responseCode, byte[] dataThatWasConfirmed,
ConfirmationCallback callback) {
switch (responseCode) {
- case KeyStore.CONFIRMATIONUI_OK:
- callback.onConfirmed(dataThatWasConfirmed);
- break;
-
- case KeyStore.CONFIRMATIONUI_CANCELED:
- callback.onDismissed();
- break;
-
- case KeyStore.CONFIRMATIONUI_ABORTED:
- callback.onCanceled();
- break;
-
- case KeyStore.CONFIRMATIONUI_SYSTEM_ERROR:
- callback.onError(new Exception("System error returned by ConfirmationUI."));
- break;
-
- default:
- callback.onError(new Exception("Unexpected responseCode=" + responseCode
- + " from onConfirmtionPromptCompleted() callback."));
- break;
- }
- }
-
- private void doCallback2(int responseCode, byte[] dataThatWasConfirmed,
- ConfirmationCallback callback) {
- switch (responseCode) {
case AndroidProtectedConfirmation.ERROR_OK:
callback.onConfirmed(dataThatWasConfirmed);
break;
@@ -155,31 +128,6 @@ public class ConfirmationPrompt {
}
}
- private final android.os.IBinder mCallbackBinder =
- new android.security.IConfirmationPromptCallback.Stub() {
- @Override
- public void onConfirmationPromptCompleted(
- int responseCode, final byte[] dataThatWasConfirmed)
- throws android.os.RemoteException {
- if (mCallback != null) {
- ConfirmationCallback callback = mCallback;
- Executor executor = mExecutor;
- mCallback = null;
- mExecutor = null;
- if (executor == null) {
- doCallback(responseCode, dataThatWasConfirmed, callback);
- } else {
- executor.execute(new Runnable() {
- @Override
- public void run() {
- doCallback(responseCode, dataThatWasConfirmed, callback);
- }
- });
- }
- }
- }
- };
-
private final android.security.apc.IConfirmationCallback mConfirmationCallback =
new android.security.apc.IConfirmationCallback.Stub() {
@Override
@@ -191,11 +139,11 @@ public class ConfirmationPrompt {
mCallback = null;
mExecutor = null;
if (executor == null) {
- doCallback2(result, dataThatWasConfirmed, callback);
+ doCallback(result, dataThatWasConfirmed, callback);
} else {
executor.execute(new Runnable() {
@Override public void run() {
- doCallback2(result, dataThatWasConfirmed, callback);
+ doCallback(result, dataThatWasConfirmed, callback);
}
});
}
@@ -266,29 +214,7 @@ public class ConfirmationPrompt {
mExtraData = extraData;
}
- private static final int UI_OPTION_ACCESSIBILITY_INVERTED_FLAG = 1 << 0;
- private static final int UI_OPTION_ACCESSIBILITY_MAGNIFIED_FLAG = 1 << 1;
-
private int getUiOptionsAsFlags() {
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- return getUiOptionsAsFlags2();
- }
- int uiOptionsAsFlags = 0;
- ContentResolver contentResolver = mContext.getContentResolver();
- int inversionEnabled = Settings.Secure.getInt(contentResolver,
- Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0);
- if (inversionEnabled == 1) {
- uiOptionsAsFlags |= UI_OPTION_ACCESSIBILITY_INVERTED_FLAG;
- }
- float fontScale = Settings.System.getFloat(contentResolver,
- Settings.System.FONT_SCALE, (float) 1.0);
- if (fontScale > 1.0) {
- uiOptionsAsFlags |= UI_OPTION_ACCESSIBILITY_MAGNIFIED_FLAG;
- }
- return uiOptionsAsFlags;
- }
-
- private int getUiOptionsAsFlags2() {
int uiOptionsAsFlags = 0;
ContentResolver contentResolver = mContext.getContentResolver();
int inversionEnabled = Settings.Secure.getInt(contentResolver,
@@ -349,52 +275,26 @@ public class ConfirmationPrompt {
mExecutor = executor;
String locale = Locale.getDefault().toLanguageTag();
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- int uiOptionsAsFlags = getUiOptionsAsFlags2();
- int responseCode = getService().presentConfirmationPrompt(
- mConfirmationCallback, mPromptText.toString(), mExtraData, locale,
- uiOptionsAsFlags);
- switch (responseCode) {
- case AndroidProtectedConfirmation.ERROR_OK:
- return;
-
- case AndroidProtectedConfirmation.ERROR_OPERATION_PENDING:
- throw new ConfirmationAlreadyPresentingException();
-
- case AndroidProtectedConfirmation.ERROR_UNIMPLEMENTED:
- throw new ConfirmationNotAvailableException();
-
- default:
- // Unexpected error code.
- Log.w(TAG,
- "Unexpected responseCode=" + responseCode
- + " from presentConfirmationPrompt() call.");
- throw new IllegalArgumentException();
- }
- } else {
- int uiOptionsAsFlags = getUiOptionsAsFlags();
- int responseCode = mKeyStore.presentConfirmationPrompt(
- mCallbackBinder, mPromptText.toString(), mExtraData, locale, uiOptionsAsFlags);
- switch (responseCode) {
- case KeyStore.CONFIRMATIONUI_OK:
- return;
-
- case KeyStore.CONFIRMATIONUI_OPERATION_PENDING:
- throw new ConfirmationAlreadyPresentingException();
+ int uiOptionsAsFlags = getUiOptionsAsFlags();
+ int responseCode = getService().presentConfirmationPrompt(
+ mConfirmationCallback, mPromptText.toString(), mExtraData, locale,
+ uiOptionsAsFlags);
+ switch (responseCode) {
+ case AndroidProtectedConfirmation.ERROR_OK:
+ return;
- case KeyStore.CONFIRMATIONUI_UNIMPLEMENTED:
- throw new ConfirmationNotAvailableException();
+ case AndroidProtectedConfirmation.ERROR_OPERATION_PENDING:
+ throw new ConfirmationAlreadyPresentingException();
- case KeyStore.CONFIRMATIONUI_UIERROR:
- throw new IllegalArgumentException();
+ case AndroidProtectedConfirmation.ERROR_UNIMPLEMENTED:
+ throw new ConfirmationNotAvailableException();
- default:
- // Unexpected error code.
- Log.w(TAG,
- "Unexpected responseCode=" + responseCode
- + " from presentConfirmationPrompt() call.");
- throw new IllegalArgumentException();
- }
+ default:
+ // Unexpected error code.
+ Log.w(TAG,
+ "Unexpected responseCode=" + responseCode
+ + " from presentConfirmationPrompt() call.");
+ throw new IllegalArgumentException();
}
}
@@ -408,33 +308,18 @@ public class ConfirmationPrompt {
* @throws IllegalStateException if no prompt is currently being presented.
*/
public void cancelPrompt() {
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- int responseCode =
- getService().cancelConfirmationPrompt(mConfirmationCallback);
- if (responseCode == AndroidProtectedConfirmation.ERROR_OK) {
- return;
- } else if (responseCode == AndroidProtectedConfirmation.ERROR_OPERATION_PENDING) {
- throw new IllegalStateException();
- } else {
- // Unexpected error code.
- Log.w(TAG,
- "Unexpected responseCode=" + responseCode
- + " from cancelConfirmationPrompt() call.");
- throw new IllegalStateException();
- }
+ int responseCode =
+ getService().cancelConfirmationPrompt(mConfirmationCallback);
+ if (responseCode == AndroidProtectedConfirmation.ERROR_OK) {
+ return;
+ } else if (responseCode == AndroidProtectedConfirmation.ERROR_OPERATION_PENDING) {
+ throw new IllegalStateException();
} else {
- int responseCode = mKeyStore.cancelConfirmationPrompt(mCallbackBinder);
- if (responseCode == KeyStore.CONFIRMATIONUI_OK) {
- return;
- } else if (responseCode == KeyStore.CONFIRMATIONUI_OPERATION_PENDING) {
- throw new IllegalStateException();
- } else {
- // Unexpected error code.
- Log.w(TAG,
- "Unexpected responseCode=" + responseCode
- + " from cancelConfirmationPrompt() call.");
- throw new IllegalStateException();
- }
+ // Unexpected error code.
+ Log.w(TAG,
+ "Unexpected responseCode=" + responseCode
+ + " from cancelConfirmationPrompt() call.");
+ throw new IllegalStateException();
}
}
@@ -448,9 +333,6 @@ public class ConfirmationPrompt {
if (isAccessibilityServiceRunning(context)) {
return false;
}
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- return new AndroidProtectedConfirmation().isConfirmationPromptSupported();
- }
- return KeyStore.getInstance().isConfirmationPromptSupported();
+ return new AndroidProtectedConfirmation().isConfirmationPromptSupported();
}
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java b/core/java/android/security/keymaster/KeymasterCertificateChain.aidl
index b8e6af7d936e..e01db7acce99 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java
+++ b/core/java/android/security/keymaster/KeymasterCertificateChain.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,18 +14,6 @@
* limitations under the License.
*/
-package android.security.keystore;
+package android.security.keymaster;
-import javax.crypto.SecretKey;
-
-/**
- * {@link SecretKey} backed by Android Keystore.
- *
- * @hide
- */
-public class AndroidKeyStoreSecretKey extends AndroidKeyStoreKey implements SecretKey {
-
- public AndroidKeyStoreSecretKey(String alias, int uid, String algorithm) {
- super(alias, uid, algorithm);
- }
-}
+parcelable KeymasterCertificateChain;
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index 6788353ba2fb..ad9b79606455 100644
--- a/core/java/android/security/keystore/recovery/RecoveryController.java
+++ b/core/java/android/security/keystore/recovery/RecoveryController.java
@@ -712,18 +712,10 @@ public class RecoveryController {
*/
@NonNull Key getKeyFromGrant(@NonNull String grantAlias)
throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
- if (grantAlias.startsWith(APPLICATION_KEY_GRANT_PREFIX)) {
- return AndroidKeyStoreProvider
- .loadAndroidKeyStoreSecretKeyFromKeystore(
- KeyStore2.getInstance(),
- getGrantDescriptor(grantAlias));
- }
- // TODO(b/171305545): remove KeyStore1 logic.
- return android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
- mKeyStore,
- grantAlias,
- KeyStore.UID_SELF);
-
+ return AndroidKeyStoreProvider
+ .loadAndroidKeyStoreSecretKeyFromKeystore(
+ KeyStore2.getInstance(),
+ getGrantDescriptor(grantAlias));
}
private static final String APPLICATION_KEY_GRANT_PREFIX = "recoverable_key:";
diff --git a/core/java/android/service/notification/NotificationListenerFilter.java b/core/java/android/service/notification/NotificationListenerFilter.java
index 9de75cac159a..a69d33c17e9d 100644
--- a/core/java/android/service/notification/NotificationListenerFilter.java
+++ b/core/java/android/service/notification/NotificationListenerFilter.java
@@ -31,15 +31,17 @@ import android.util.ArraySet;
* @hide
*/
public class NotificationListenerFilter implements Parcelable {
+
+ private static final int DEFAULT_TYPES = FLAG_FILTER_TYPE_CONVERSATIONS
+ | FLAG_FILTER_TYPE_ALERTING
+ | FLAG_FILTER_TYPE_SILENT
+ | FLAG_FILTER_TYPE_ONGOING;
private int mAllowedNotificationTypes;
// VersionedPackage is holding the pkg name and pkg uid
private ArraySet<VersionedPackage> mDisallowedPackages;
public NotificationListenerFilter() {
- mAllowedNotificationTypes = FLAG_FILTER_TYPE_CONVERSATIONS
- | FLAG_FILTER_TYPE_ALERTING
- | FLAG_FILTER_TYPE_SILENT
- | FLAG_FILTER_TYPE_ONGOING;
+ mAllowedNotificationTypes = DEFAULT_TYPES;
mDisallowedPackages = new ArraySet<>();
}
@@ -80,6 +82,10 @@ public class NotificationListenerFilter implements Parcelable {
return (mAllowedNotificationTypes & type) != 0;
}
+ public boolean areAllTypesAllowed() {
+ return DEFAULT_TYPES == mAllowedNotificationTypes;
+ }
+
public boolean isPackageAllowed(VersionedPackage pkg) {
return !mDisallowedPackages.contains(pkg);
}
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 09c3b2effcb0..6c775852fcee 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -792,6 +792,29 @@ public abstract class NotificationListenerService extends Service {
}
}
+ /**
+ * Lets an app migrate notification filters from its app into the OS.
+ *
+ * <p>This call will be ignored if the app has already migrated these settings or the user
+ * has set filters in the UI. This method is intended for user specific settings; if an app has
+ * already specified defaults types in its manifest with
+ * {@link #META_DATA_DEFAULT_FILTER_TYPES}, the defaultTypes option will be ignored.</p>
+ * @param defaultTypes A value representing the types of notifications that this listener should
+ * receive by default
+ * @param disallowedPkgs A list of package names whose notifications should not be seen by this
+ * listener, by default, because the listener does not process or display them, or because a
+ * user had previously disallowed these packages in the listener app's UI
+ */
+ public final void migrateNotificationFilter(@NotificationFilterTypes int defaultTypes,
+ @Nullable List<String> disallowedPkgs) {
+ if (!isBound()) return;
+ try {
+ getNotificationInterface().migrateNotificationFilter(
+ mWrapper, defaultTypes, disallowedPkgs);
+ } catch (android.os.RemoteException ex) {
+ Log.v(TAG, "Unable to contact notification manager", ex);
+ }
+ }
/**
* Inform the notification manager that these notifications have been viewed by the
diff --git a/core/java/android/text/method/TranslationTransformationMethod.java b/core/java/android/text/method/TranslationTransformationMethod.java
index 54c0ffcdbb65..7db999a89fbe 100644
--- a/core/java/android/text/method/TranslationTransformationMethod.java
+++ b/core/java/android/text/method/TranslationTransformationMethod.java
@@ -78,11 +78,24 @@ public class TranslationTransformationMethod implements TransformationMethod2 {
if (TextUtils.isEmpty(translatedText) || isWhitespace(translatedText.toString())) {
return source;
} else {
+ // TODO(b/179693024): Remove this once we have the fix to pad the view text instead.
+ translatedText = ellipsize(translatedText, ((TextView) view).getText().length());
// TODO(b/174283799): apply the spans to the text
return translatedText;
}
}
+ private static CharSequence ellipsize(CharSequence text, int newLength) {
+ if (text.length() <= newLength) {
+ return text;
+ }
+ String ellipsis = String.valueOf('\u2026');
+ if (newLength == 1) {
+ return ellipsis;
+ }
+ return TextUtils.concat(TextUtils.trimToSize(text, newLength - 1), ellipsis);
+ }
+
@Override
public void onFocusChanged(View view, CharSequence sourceText,
boolean focused, int direction,
diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java
index 2a43222b9e48..78c4739968e3 100644
--- a/core/java/android/util/Slog.java
+++ b/core/java/android/util/Slog.java
@@ -61,7 +61,10 @@ public final class Slog {
* of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
* calling this method in a critical path, make sure to explicitly do the check before calling
* it.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void v(String tag, String format, @Nullable Object... args) {
if (!Log.isLoggable(tag, Log.VERBOSE)) return;
@@ -87,7 +90,10 @@ public final class Slog {
* of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
* calling this method in a critical path, make sure to explicitly do the check before calling
* it.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void d(String tag, String format, @Nullable Object... args) {
if (!Log.isLoggable(tag, Log.DEBUG)) return;
@@ -112,7 +118,10 @@ public final class Slog {
* of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
* calling this method in a critical path, make sure to explicitly do the check before calling
* it.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void i(String tag, String format, @Nullable Object... args) {
if (!Log.isLoggable(tag, Log.INFO)) return;
@@ -142,7 +151,10 @@ public final class Slog {
* of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
* calling this method in a critical path, make sure to explicitly do the check before calling
* it.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void w(String tag, String format, @Nullable Object... args) {
if (!Log.isLoggable(tag, Log.WARN)) return;
@@ -157,7 +169,10 @@ public final class Slog {
* of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
* calling this method in a critical path, make sure to explicitly do the check before calling
* it.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void w(String tag, Exception exception, String format, @Nullable Object... args) {
if (!Log.isLoggable(tag, Log.WARN)) return;
@@ -183,7 +198,10 @@ public final class Slog {
* of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
* calling this method in a critical path, make sure to explicitly do the check before calling
* it.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void e(String tag, String format, @Nullable Object... args) {
if (!Log.isLoggable(tag, Log.ERROR)) return;
@@ -198,7 +216,10 @@ public final class Slog {
* of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
* calling this method in a critical path, make sure to explicitly do the check before calling
* it.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void e(String tag, Exception exception, String format, @Nullable Object... args) {
if (!Log.isLoggable(tag, Log.ERROR)) return;
@@ -217,14 +238,20 @@ public final class Slog {
/**
* Logs a {@code wtf} message.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void wtf(String tag, String format, @Nullable Object... args) {
wtf(tag, getMessage(format, args));
}
/**
* Logs a {@code wtf} message with an exception.
+ *
+ * @deprecated use {@code com.android.server.utils.SLogF} instead.
*/
+ @Deprecated
public static void wtf(String tag, Exception exception, String format,
@Nullable Object... args) {
wtf(tag, getMessage(format, args), exception);
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index cd6585cd3fa1..5fd0c33ca205 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -30,6 +30,7 @@ import com.android.i18n.timezone.ZoneInfoDb;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
+import java.time.Instant;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Calendar;
@@ -43,11 +44,39 @@ import java.util.List;
public class TimeUtils {
/** @hide */ public TimeUtils() {}
/** {@hide} */
- private static SimpleDateFormat sLoggingFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ private static final SimpleDateFormat sLoggingFormat =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/** @hide */
public static final SimpleDateFormat sDumpDateFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ /**
+ * This timestamp is used in TimeUtils methods and by the SettingsUI to filter time zones
+ * to only "effective" ones in a country. It is compared against the notUsedAfter metadata that
+ * Android records for some time zones.
+ *
+ * <p>What is notUsedAfter?</p>
+ * Android chooses to avoid making users choose between functionally identical time zones at the
+ * expense of not being able to represent local times in the past.
+ *
+ * notUsedAfter exists because some time zones can "merge" with other time zones after a given
+ * point in time (i.e. they change to have identical transitions, offsets, display names, etc.).
+ * From the notUsedAfter time, the zone will express the same local time as the one it merged
+ * with.
+ *
+ * <p>Why hardcoded?</p>
+ * Rather than using System.currentTimeMillis(), a timestamp known to be in the recent past is
+ * used to ensure consistent behavior across devices and time, and avoid assumptions that the
+ * system clock on a device is currently set correctly. The fixed value should be updated
+ * occasionally, but it doesn't have to be very often as effective time zones for a country
+ * don't change very often.
+ *
+ * @hide
+ */
+ public static final Instant MIN_USE_DATE_OF_TIMEZONE =
+ Instant.ofEpochMilli(1546300800000L); // 1/1/2019 00:00 UTC
+
/**
* Tries to return a time zone that would have had the specified offset
* and DST value at the specified moment in the specified country.
@@ -109,7 +138,7 @@ public class TimeUtils {
List<String> timeZoneIds = new ArrayList<>();
for (TimeZoneMapping timeZoneMapping : countryTimeZones.getTimeZoneMappings()) {
- if (timeZoneMapping.isShownInPicker()) {
+ if (timeZoneMapping.isShownInPickerAt(MIN_USE_DATE_OF_TIMEZONE)) {
timeZoneIds.add(timeZoneMapping.getTimeZoneId());
}
}
diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java
index 85f2c1ccc180..5c7f0f5cb1e0 100644
--- a/core/java/android/uwb/RangingManager.java
+++ b/core/java/android/uwb/RangingManager.java
@@ -17,6 +17,7 @@
package android.uwb;
import android.annotation.NonNull;
+import android.content.AttributionSource;
import android.os.CancellationSignal;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -42,6 +43,9 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
/**
* Open a new ranging session
*
+ * @param attributionSource Attribution source to use for the enforcement of
+ * {@link android.Manifest.permission#ULTRAWIDEBAND_RANGING} runtime
+ * permission.
* @param params the parameters that define the ranging session
* @param executor {@link Executor} to run callbacks
* @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession}
@@ -49,7 +53,8 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
* @return a {@link CancellationSignal} that may be used to cancel the opening of the
* {@link RangingSession}.
*/
- public CancellationSignal openSession(@NonNull PersistableBundle params,
+ public CancellationSignal openSession(@NonNull AttributionSource attributionSource,
+ @NonNull PersistableBundle params,
@NonNull Executor executor,
@NonNull RangingSession.Callback callbacks) {
synchronized (this) {
@@ -58,6 +63,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
new RangingSession(executor, callbacks, mAdapter, sessionHandle);
mRangingSessionTable.put(sessionHandle, session);
try {
+ // TODO: Pass in the attributionSource to the service.
mAdapter.openRanging(sessionHandle, this, params);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 844bbbe7970b..bed77e664337 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -16,7 +16,7 @@
package android.uwb;
-import android.Manifest;
+import android.Manifest.permission;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -24,7 +24,9 @@ import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.content.AttributionSource;
import android.content.Context;
+import android.content.ContextParams;
import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.PersistableBundle;
@@ -47,9 +49,10 @@ import java.util.concurrent.Executor;
@SystemApi
@SystemService(Context.UWB_SERVICE)
public final class UwbManager {
- private IUwbAdapter mUwbAdapter;
private static final String SERVICE_NAME = "uwb";
+ private final Context mContext;
+ private final IUwbAdapter mUwbAdapter;
private final AdapterStateListener mAdapterStateListener;
private final RangingManager mRangingManager;
@@ -116,9 +119,11 @@ public final class UwbManager {
/**
* Use <code>Context.getSystemService(UwbManager.class)</code> to get an instance.
*
+ * @param ctx Context of the client.
* @param adapter an instance of an {@link android.uwb.IUwbAdapter}
*/
- private UwbManager(IUwbAdapter adapter) {
+ private UwbManager(@NonNull Context ctx, @NonNull IUwbAdapter adapter) {
+ mContext = ctx;
mUwbAdapter = adapter;
mAdapterStateListener = new AdapterStateListener(adapter);
mRangingManager = new RangingManager(adapter);
@@ -127,7 +132,7 @@ public final class UwbManager {
/**
* @hide
*/
- public static UwbManager getInstance() {
+ public static UwbManager getInstance(@NonNull Context ctx) {
IBinder b = ServiceManager.getService(SERVICE_NAME);
if (b == null) {
return null;
@@ -138,7 +143,7 @@ public final class UwbManager {
return null;
}
- return new UwbManager(adapter);
+ return new UwbManager(ctx, adapter);
}
/**
@@ -153,7 +158,7 @@ public final class UwbManager {
* @param executor an {@link Executor} to execute given callback
* @param callback user implementation of the {@link AdapterStateCallback}
*/
- @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
+ @RequiresPermission(permission.UWB_PRIVILEGED)
public void registerAdapterStateCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull AdapterStateCallback callback) {
mAdapterStateListener.register(executor, callback);
@@ -168,7 +173,7 @@ public final class UwbManager {
*
* @param callback user implementation of the {@link AdapterStateCallback}
*/
- @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
+ @RequiresPermission(permission.UWB_PRIVILEGED)
public void unregisterAdapterStateCallback(@NonNull AdapterStateCallback callback) {
mAdapterStateListener.unregister(callback);
}
@@ -182,7 +187,7 @@ public final class UwbManager {
* @return {@link PersistableBundle} of the device's supported UWB protocols and parameters
*/
@NonNull
- @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
+ @RequiresPermission(permission.UWB_PRIVILEGED)
public PersistableBundle getSpecificationInfo() {
try {
return mUwbAdapter.getSpecificationInfo();
@@ -199,7 +204,7 @@ public final class UwbManager {
* @return the timestamp resolution in nanoseconds
*/
@SuppressLint("MethodNameUnits")
- @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
+ @RequiresPermission(permission.UWB_PRIVILEGED)
public long elapsedRealtimeResolutionNanos() {
try {
return mUwbAdapter.getTimestampResolutionNanos();
@@ -235,10 +240,14 @@ public final class UwbManager {
* {@link RangingSession.Callback#onOpened(RangingSession)}.
*/
@NonNull
- @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
+ @RequiresPermission(allOf = {
+ permission.UWB_PRIVILEGED,
+ permission.UWB_RANGING
+ })
public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
@NonNull @CallbackExecutor Executor executor,
@NonNull RangingSession.Callback callbacks) {
- return mRangingManager.openSession(parameters, executor, callbacks);
+ return mRangingManager.openSession(
+ mContext.getAttributionSource(), parameters, executor, callbacks);
}
}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 3d1c8ff515c7..f487c6c61973 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -34,6 +34,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.graphics.Insets;
@@ -808,7 +809,7 @@ public class InsetsState implements Parcelable {
dest.writeTypedObject(mRoundedCorners, flags);
}
- public static final @android.annotation.NonNull Creator<InsetsState> CREATOR = new Creator<InsetsState>() {
+ public static final @NonNull Creator<InsetsState> CREATOR = new Creator<InsetsState>() {
public InsetsState createFromParcel(Parcel in) {
return new InsetsState(in);
@@ -842,5 +843,16 @@ public class InsetsState implements Parcelable {
+ ", mSources= { " + joiner
+ " }";
}
+
+ public @NonNull String toSourceVisibilityString() {
+ StringJoiner joiner = new StringJoiner(", ");
+ for (int i = 0; i < SIZE; i++) {
+ InsetsSource source = mSources[i];
+ if (source != null) {
+ joiner.add(typeToString(i) + ": " + (source.isVisible() ? "visible" : "invisible"));
+ }
+ }
+ return joiner.toString();
+ }
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1e2b2aedfc08..dd5c95404510 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -19782,6 +19782,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return;
}
+ if (mAttachInfo == null) {
+ // View is not attached.
+ return;
+ }
+
final int h = dr.getIntrinsicHeight();
final int w = dr.getIntrinsicWidth();
final Rect rect = mAttachInfo.mTmpInvalRect;
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index bde4cb7c4fc3..4a52b1f01b46 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -725,7 +725,8 @@ public class EditorInfo implements InputType, Parcelable {
* protocol.
*/
@Nullable
- public CharSequence getInitialTextBeforeCursor(int length, int flags) {
+ public CharSequence getInitialTextBeforeCursor(
+ @IntRange(from = 0) int length, @InputConnection.GetTextType int flags) {
if (mInitialSurroundingText == null) {
return null;
}
@@ -750,7 +751,7 @@ public class EditorInfo implements InputType, Parcelable {
* this protocol is not supported.
*/
@Nullable
- public CharSequence getInitialSelectedText(int flags) {
+ public CharSequence getInitialSelectedText(@InputConnection.GetTextType int flags) {
if (mInitialSurroundingText == null) {
return null;
}
@@ -792,7 +793,8 @@ public class EditorInfo implements InputType, Parcelable {
* protocol.
*/
@Nullable
- public CharSequence getInitialTextAfterCursor(int length, int flags) {
+ public CharSequence getInitialTextAfterCursor(
+ @IntRange(from = 0) int length, @InputConnection.GetTextType int flags) {
if (mInitialSurroundingText == null) {
return null;
}
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 1951194816bd..ae426d2c897f 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -626,20 +626,31 @@ public class EdgeEffect {
// assume rotations of increments of 90 degrees
float x = mTmpPoints[10] - mTmpPoints[8];
float width = right - left;
- float vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width)));
+ float vecX = 0f;
+ if (width > 0) {
+ vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width)));
+ }
+
float y = mTmpPoints[11] - mTmpPoints[9];
float height = bottom - top;
- float vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height)));
- renderNode.stretch(
- left,
- top,
- right,
- bottom,
- vecX,
- vecY,
- mWidth,
- mHeight
- );
+ float vecY = 0f;
+ if (height > 0) {
+ vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height)));
+ }
+
+ boolean hasStretchVectors = Float.compare(vecX, 0) != 0 || Float.compare(vecY, 0) != 0;
+ if (right > left && bottom > top && mWidth > 0 && mHeight > 0 && hasStretchVectors) {
+ renderNode.stretch(
+ left,
+ top,
+ right,
+ bottom,
+ vecX,
+ vecY,
+ mWidth,
+ mHeight
+ );
+ }
} else {
// This is TYPE_STRETCH and drawing into a Canvas that isn't a Recording Canvas,
// so no effect can be shown. Just end the effect.
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 7f0178e29d85..594a1a72ffcf 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -26,7 +26,9 @@ import static android.view.SurfaceControl.JankData.SURFACE_FLINGER_SCHEDULING;
import static com.android.internal.jank.InteractionJankMonitor.ACTION_METRICS_LOGGED;
import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_BEGIN;
+import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_CANCEL;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.HardwareRendererObserver;
@@ -45,6 +47,9 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor.Session;
import com.android.internal.util.FrameworkStatsLog;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* A class that allows the app to get the frame metrics from HardwareRendererObserver.
* @hide
@@ -57,6 +62,26 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
private static final long INVALID_ID = -1;
public static final int NANOS_IN_MILLISECOND = 1_000_000;
+ static final int REASON_END_UNKNOWN = -1;
+ static final int REASON_END_NORMAL = 0;
+ static final int REASON_END_SURFACE_DESTROYED = 1;
+ static final int REASON_CANCEL_NORMAL = 16;
+ static final int REASON_CANCEL_NOT_BEGUN = 17;
+ static final int REASON_CANCEL_SAME_VSYNC = 18;
+
+ /** @hide */
+ @IntDef({
+ REASON_END_UNKNOWN,
+ REASON_END_NORMAL,
+ REASON_END_SURFACE_DESTROYED,
+ REASON_CANCEL_NORMAL,
+ REASON_CANCEL_NOT_BEGUN,
+ REASON_CANCEL_SAME_VSYNC,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Reasons {
+ }
+
private final HardwareRendererObserver mObserver;
private SurfaceControl mSurfaceControl;
private final int mTraceThresholdMissedFrames;
@@ -156,7 +181,14 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
// force finish the session.
mHandler.postDelayed(() -> {
synchronized (FrameTracker.this) {
+ if (DEBUG) {
+ Log.d(TAG, "surfaceDestroyed: " + mSession.getName()
+ + ", finalized=" + mMetricsFinalized
+ + ", info=" + mJankInfos.size()
+ + ", vsync=" + mBeginVsyncId + "-" + mEndVsyncId);
+ }
if (!mMetricsFinalized) {
+ end(REASON_END_SURFACE_DESTROYED);
finish(mJankInfos.size() - 1);
}
}
@@ -176,6 +208,9 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
mSession.setTimeStamp(System.nanoTime());
Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId);
mRendererWrapper.addObserver(mObserver);
+ if (DEBUG) {
+ Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId);
+ }
if (mSurfaceControl != null) {
mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
}
@@ -187,15 +222,25 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
/**
* End the trace session of the CUJ.
*/
- public synchronized void end() {
+ public synchronized void end(@Reasons int reason) {
+ if (mEndVsyncId != INVALID_ID) return;
mEndVsyncId = mChoreographer.getVsyncId();
+
// Cancel the session if:
// 1. The session begins and ends at the same vsync id.
// 2. The session never begun.
- if (mEndVsyncId == mBeginVsyncId || mBeginVsyncId == INVALID_ID) {
- cancel();
+ if (mBeginVsyncId == INVALID_ID) {
+ cancel(REASON_CANCEL_NOT_BEGUN);
+ } else if (mEndVsyncId == mBeginVsyncId) {
+ cancel(REASON_CANCEL_SAME_VSYNC);
} else {
+ if (DEBUG) {
+ Log.d(TAG, "end: " + mSession.getName()
+ + ", end=" + mEndVsyncId + ", reason=" + reason);
+ }
Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+ mSession.setReason(reason);
+ InteractionJankMonitor.getInstance().removeTimeout(mSession.getCuj());
}
// We don't remove observer here,
// will remove it when all the frame metrics in this duration are called back.
@@ -205,7 +250,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
/**
* Cancel the trace session of the CUJ.
*/
- public synchronized void cancel() {
+ public synchronized void cancel(@Reasons int reason) {
// We don't need to end the trace section if it never begun.
if (mBeginVsyncId != INVALID_ID) {
Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
@@ -215,10 +260,16 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
// Always remove the observers in cancel call to avoid leakage.
removeObservers();
+ if (DEBUG) {
+ Log.d(TAG, "cancel: " + mSession.getName()
+ + ", begin=" + mBeginVsyncId + ", end=" + mEndVsyncId + ", reason=" + reason);
+ }
+
+ mSession.setReason(reason);
// Notify the listener the session has been cancelled.
// We don't notify the listeners if the session never begun.
- if (mListener != null && mBeginVsyncId != INVALID_ID) {
- mListener.onNotifyCujEvents(mSession, InteractionJankMonitor.ACTION_SESSION_CANCEL);
+ if (mListener != null) {
+ mListener.onNotifyCujEvents(mSession, ACTION_SESSION_CANCEL);
}
}
@@ -399,6 +450,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
}
if (DEBUG) {
Log.i(TAG, "FrameTracker: CUJ=" + mSession.getName()
+ + " (" + mBeginVsyncId + "," + mEndVsyncId + ")"
+ " totalFrames=" + totalFramesCount
+ " missedAppFrames=" + missedAppFramesCount
+ " missedSfFrames=" + missedSfFramesCounts
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index fbc92c1f99c4..6c56d421a1fb 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -19,6 +19,7 @@ package com.android.internal.jank;
import static android.content.Intent.FLAG_RECEIVER_REGISTERED_ONLY;
import static com.android.internal.jank.FrameTracker.ChoreographerWrapper;
+import static com.android.internal.jank.FrameTracker.REASON_CANCEL_NOT_BEGUN;
import static com.android.internal.jank.FrameTracker.SurfaceControlWrapper;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME;
@@ -104,7 +105,7 @@ public class InteractionJankMonitor {
public static final String BUNDLE_KEY_CUJ_NAME = ACTION_PREFIX + ".CUJ_NAME";
public static final String BUNDLE_KEY_TIMESTAMP = ACTION_PREFIX + ".TIMESTAMP";
@VisibleForTesting
- public static final String PROP_NOTIFY_CUJ_EVENT = "debug.notify_cuj_events";
+ public static final String PROP_NOTIFY_CUJ_EVENT = "debug.jank.notify_cuj_events";
// Every value must have a corresponding entry in CUJ_STATSD_INTERACTION_TYPE.
public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE = 0;
@@ -287,6 +288,10 @@ public class InteractionJankMonitor {
}
private void notifyEvents(Context context, String action, Session session) {
+ if (action.equals(ACTION_SESSION_CANCEL)
+ && session.getReason() == REASON_CANCEL_NOT_BEGUN) {
+ return;
+ }
Intent intent = new Intent(action);
intent.putExtra(BUNDLE_KEY_CUJ_NAME, getNameOfCuj(session.getCuj()));
intent.putExtra(BUNDLE_KEY_TIMESTAMP, session.getTimeStamp());
@@ -294,6 +299,16 @@ public class InteractionJankMonitor {
context.sendBroadcast(intent);
}
+ void removeTimeout(@CujType int cujType) {
+ synchronized (this) {
+ Runnable timeout = mTimeoutActions.get(cujType);
+ if (timeout != null) {
+ mWorker.getThreadHandler().removeCallbacks(timeout);
+ mTimeoutActions.remove(cujType);
+ }
+ }
+ }
+
/**
* Begin a trace session.
*
@@ -351,16 +366,11 @@ public class InteractionJankMonitor {
synchronized (this) {
// remove the timeout action first.
- Runnable timeout = mTimeoutActions.get(cujType);
- if (timeout != null) {
- mWorker.getThreadHandler().removeCallbacks(timeout);
- mTimeoutActions.remove(cujType);
- }
-
+ removeTimeout(cujType);
FrameTracker tracker = getTracker(cujType);
// Skip this call since we haven't started a trace yet.
if (tracker == null) return false;
- tracker.end();
+ tracker.end(FrameTracker.REASON_END_NORMAL);
mRunningTrackers.remove(cujType);
return true;
}
@@ -375,16 +385,11 @@ public class InteractionJankMonitor {
//TODO (163505250): This should be no-op if not in droid food rom.
synchronized (this) {
// remove the timeout action first.
- Runnable timeout = mTimeoutActions.get(cujType);
- if (timeout != null) {
- mWorker.getThreadHandler().removeCallbacks(timeout);
- mTimeoutActions.remove(cujType);
- }
-
+ removeTimeout(cujType);
FrameTracker tracker = getTracker(cujType);
// Skip this call since we haven't started a trace yet.
if (tracker == null) return false;
- tracker.cancel();
+ tracker.cancel(FrameTracker.REASON_CANCEL_NORMAL);
mRunningTrackers.remove(cujType);
return true;
}
@@ -509,6 +514,8 @@ public class InteractionJankMonitor {
@CujType
private int mCujType;
private long mTimeStamp;
+ @FrameTracker.Reasons
+ private int mReason = FrameTracker.REASON_END_UNKNOWN;
public Session(@CujType int cujType) {
mCujType = cujType;
@@ -543,5 +550,13 @@ public class InteractionJankMonitor {
public long getTimeStamp() {
return mTimeStamp;
}
+
+ public void setReason(@FrameTracker.Reasons int reason) {
+ mReason = reason;
+ }
+
+ public int getReason() {
+ return mReason;
+ }
}
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index f907e2576c43..361b836d6051 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -41,6 +41,7 @@ import android.os.UserHandle;
import android.os.ZygoteProcess;
import android.os.storage.StorageManager;
import android.provider.DeviceConfig;
+import android.security.keystore2.AndroidKeyStoreProvider;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -216,10 +217,8 @@ public class ZygoteInit {
long startTime = SystemClock.uptimeMillis();
Trace.traceBegin(
Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
- // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
- // preferred providers. Note this is not done via security.properties as the JCA providers
- // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
- android.security.keystore2.AndroidKeyStoreProvider.install();
+
+ AndroidKeyStoreProvider.install();
Log.i(TAG, "Installed AndroidKeyStoreProvider in "
+ (SystemClock.uptimeMillis() - startTime) + "ms.");
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 9a91d2028953..424632fe82eb 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -258,6 +258,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
private Drawable mLastOriginalBackgroundDrawable;
private Drawable mResizingBackgroundDrawable;
private BackgroundBlurDrawable mBackgroundBlurDrawable;
+ private BackgroundBlurDrawable mLastBackgroundBlurDrawable;
/**
* Temporary holder for a window background when it is set before {@link #mWindow} is
@@ -289,7 +290,6 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
private int mOriginalBackgroundBlurRadius = 0;
private int mBackgroundBlurRadius = 0;
- private int mLastBackgroundBlurRadius = 0;
private boolean mCrossWindowBlurEnabled;
private final ViewTreeObserver.OnPreDrawListener mBackgroundBlurOnPreDrawListener = () -> {
updateBackgroundBlurCorners();
@@ -1278,13 +1278,13 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
if (mBackgroundInsets.equals(mLastBackgroundInsets)
- && mBackgroundBlurRadius == mLastBackgroundBlurRadius
+ && mBackgroundBlurDrawable == mLastBackgroundBlurDrawable
&& mLastOriginalBackgroundDrawable == mOriginalBackgroundDrawable) {
return;
}
Drawable destDrawable = mOriginalBackgroundDrawable;
- if (mBackgroundBlurRadius > 0) {
+ if (mBackgroundBlurDrawable != null) {
destDrawable = new LayerDrawable(new Drawable[] {mBackgroundBlurDrawable,
mOriginalBackgroundDrawable});
}
@@ -1309,7 +1309,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
super.setBackgroundDrawable(destDrawable);
mLastBackgroundInsets = mBackgroundInsets;
- mLastBackgroundBlurRadius = mBackgroundBlurRadius;
+ mLastBackgroundBlurDrawable = mBackgroundBlurDrawable;
mLastOriginalBackgroundDrawable = mOriginalBackgroundDrawable;
}
@@ -1334,11 +1334,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
? mOriginalBackgroundBlurRadius : 0;
if (mBackgroundBlurDrawable == null && mBackgroundBlurRadius > 0) {
mBackgroundBlurDrawable = getViewRootImpl().createBackgroundBlurDrawable();
+ updateBackgroundDrawable();
}
if (mBackgroundBlurDrawable != null) {
mBackgroundBlurDrawable.setBlurRadius(mBackgroundBlurRadius);
- updateBackgroundDrawable();
}
}
@@ -1357,12 +1357,20 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
updateBackgroundBlurRadius();
}
} else if (mCrossWindowBlurEnabledListener != null) {
- mCrossWindowBlurEnabledListener = null;
+ updateBackgroundBlurRadius();
+ removeBackgroundBlurDrawable();
+ }
+ }
+
+ void removeBackgroundBlurDrawable() {
+ if (mCrossWindowBlurEnabledListener != null) {
getContext().getSystemService(WindowManager.class)
.removeCrossWindowBlurEnabledListener(mCrossWindowBlurEnabledListener);
- getViewTreeObserver().removeOnPreDrawListener(mBackgroundBlurOnPreDrawListener);
- updateBackgroundBlurRadius();
+ mCrossWindowBlurEnabledListener = null;
}
+ getViewTreeObserver().removeOnPreDrawListener(mBackgroundBlurOnPreDrawListener);
+ mBackgroundBlurDrawable = null;
+ updateBackgroundDrawable();
}
@Override
@@ -1847,6 +1855,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
mFloatingToolbar = null;
}
+ removeBackgroundBlurDrawable();
+
PhoneWindow.PanelFeatureState st = mWindow.getPanelState(Window.FEATURE_OPTIONS_PANEL, false);
if (st != null && st.menu != null && mFeatureId < 0) {
st.menu.close();
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 26ac8c154f75..9d891d531634 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Laat die program toe om Bluetooth-toestelle in die omtrek te ontdek en saam te bind"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"koppel aan saamgebinde Bluetooth-toestelle"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Laat die program toe om aan saamgebinde Bluetooth-toestelle te koppel"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Voorkeur-NFC-betalingdiensinligting"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Laat die program toe om voorkeur-NFC-betalingdiensinligting soos geregistreerde hulpmiddels en roetebestemming te kry."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"beheer kortveldkommunikasie"</string>
@@ -573,8 +577,7 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Geen PIN, patroon of wagwoord is gestel nie"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Kon nie staaf nie"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gebruik skermslot"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Voer jou skermslot in om voort te gaan"</string>
<!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
<skip />
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kon nie vingerafdruk verwerk nie. Probeer asseblief weer."</string>
@@ -661,8 +664,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Gesig <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Gebruik gesigslot"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gebruik gesig- of skermslot"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Gebruik jou gesig om voort te gaan"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Gebruik jou gesig of skermslot om voort te gaan"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index bad2d4364c6b..75b4f7cf207d 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"መተግበሪያው በአቅራቢያ ያሉ የብሉቱዝ መሣሪያዎችን እንዲያገኝ እና እንዲጣመር ይፈቅድለታል"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ከተጣመሩ የብሉቱዝ መሣሪያዎች ጋር ያገናኙ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"መተግበሪያው ከተጣመሩ የብሉቱዝ መሣሪያዎች ጋር እንዲገናኝ ይፈቅድለታል"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ተመራጭ NFC የክፍያ አገልግሎት መረጃ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"እንደ የተመዘገቡ እርዳታዎች እና የጉዞ መሥመር መዳረሻ የመሳሰለ ተመራጭ nfc የክፍያ አገልግሎት መረጃን ለማግኘት ለመተግበሪያው ያፈቅድለታል።"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ቅርብ የግኑኙነትመስክ (NFC) ተቆጣጠር"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 564f1368bd0b..f5d3872100af 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -551,6 +551,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"يسمح هذا الإذن للتطبيق باكتشاف الأجهزة القريبة التي تتضمّن بلوتوث والاقتران بها."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"تسمح بالربط الأجهزة المقترنة التي تتضمّن بلوتوث."</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"يسمح هذا الإذن للتطبيق بالارتباط بالأجهزة المقترنة التي تتضمّن بلوتوث."</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏يسمح هذا الإذن للتطبيق بالحصول على معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل، مثلاً المساعدات المسجّلة ووجهة المسار."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"التحكم في اتصال الحقل القريب"</string>
@@ -633,14 +637,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"فتح القفل بالوجه"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"إعادة تسجيل وجهك"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"لتحسين قدرة الجهاز على معرفة وجهك، يُرجى إعادة تسجيل الوجه."</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"إعداد ميزة \"فتح القفل بالوجه\""</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"يمكنك فتح قفل هاتفك بمجرّد النظر إلى الشاشة."</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"إعداد المزيد من الطرق لفتح قفل الجهاز"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"انقر لإضافة بصمة إصبع."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"تعذّر تسجيل بيانات دقيقة للوجه. حاول مرة أخرى."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ساطع للغاية. تجربة مستوى سطوع أقلّ."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"الصورة معتمة للغاية. يُرجى زيادة السطوع."</string>
@@ -1045,12 +1045,9 @@
<string name="copied" msgid="4675902854553014676">"تم النسخ."</string>
<string name="pasted_from_app" msgid="5627698450808256545">"تم لصق محتوى في <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> من <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>."</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"تم لصق محتوى في <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> من الحافظة."</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"لصق تطبيق <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> النص الذي نسخته."</string>
+ <string name="pasted_image" msgid="4729097394781491022">"لصق تطبيق <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> الصورة التي نسختها."</string>
+ <string name="pasted_content" msgid="646276353060777131">"لصق تطبيق <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> المحتوى الذي نسخته."</string>
<string name="more_item_label" msgid="7419249600215749115">"المزيد"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"القائمة+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2279,31 +2276,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"للعمل"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"عرض المحتوى الشخصي"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"عرض محتوى العمل"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"حظر مشرف تكنولوجيا المعلومات مشاركة المحتوى"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"لا يمكن مشاركة هذا المحتوى مع تطبيقات العمل."</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"لا يمكن فتح هذا المحتوى باستخدام تطبيقات العمل."</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"لا يمكن مشاركة هذا المحتوى مع التطبيقات الشخصية."</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"لا يمكن فتح هذا المحتوى باستخدام التطبيقات الشخصية."</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"الملف الشخصي للعمل متوقف مؤقتًا."</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"انقر لتفعيل الميزة"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ما مِن تطبيقات عمل."</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ما مِن تطبيقات شخصية."</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"هل تريد فتح المحتوى في <xliff:g id="APP">%s</xliff:g> في ملفك الشخصي؟"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"هل تريد فتح المحتوى في <xliff:g id="APP">%s</xliff:g> في ملفك الشخصي للعمل؟"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"استخدام المتصفّح الشخصي"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"استخدام متصفّح العمل"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏رقم التعريف الشخصي لإلغاء قفل شبكة شريحة SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"‏رقم التعريف الشخصي لإلغاء قفل المجموعة الفرعية لشبكة شريحة SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"‏رقم التعريف الشخصي لإلغاء قفل شريحة SIM للشركات"</string>
@@ -2416,8 +2401,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"إعدادات التكبير الجديدة"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"يمكنك الآن تكبير جزء من الشاشة."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"التفعيل من خلال \"الإعدادات\""</string>
<string name="dismiss_action" msgid="1728820550388704784">"إغلاق"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 890410998072..927441a1045d 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"এপ্‌টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰি উলিয়াবলৈ আৰু সেইসমূহৰ সৈতে পেয়াৰ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰক"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"এপ্‌টোক পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰিবলৈ অনুমতি দিয়ে"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"অগ্ৰাধিকাৰ দিয়া NFC পৰিশোধ সেৱাৰ তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"এপ্‌টোক অগ্ৰাধিকাৰ দিয়া nfc পৰিশোধ সেৱাৰ পঞ্জীকৃত সহায়কসমূহ আৰু পৰিশোধ কৰিব লগা লক্ষ্যস্থান দৰে তথ্য পাবলৈ অনুমতি দিয়ে।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"মুখাৱয়বৰদ্বাৰা আনলক কৰা সুবিধা"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"আপোনাৰ মুখমণ্ডল পুনৰ পঞ্জীয়ণ কৰক"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"চিনাক্তকৰণৰ সুবিধাটো উন্নত কৰিবলৈ, অনুগ্ৰহ কৰি আপোনাৰ মুখমণ্ডল পুনৰ পঞ্জীয়ন কৰক"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"মুখাৱয়বৰদ্বাৰা আনলক কৰা সুবিধাটো ছেট আপ কৰক"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"আপোনাৰ ফ’নটোলৈ চাই সেইটো আনলক কৰক"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"আনলক কৰাৰ অধিক উপায় ছেট আপ কৰক"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"এটা ফিংগাৰপ্ৰিণ্ট যোগ দিবলৈ টিপক"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"সঠিক মুখমণ্ডলৰ ডেটা কেপচাৰ নহ’ল। আকৌ চেষ্টা কৰক।"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"অতি উজ্জ্বল। ইয়াতকৈ কম পোহৰৰ উৎস ব্যৱহাৰ কৰক।"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"অতি আন্ধাৰ। উজ্জ্বল লাইট ব্যৱহাৰ কৰক।"</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"প্ৰতিলিপি কৰা হ’ল"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>ৰ পৰা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> পে’ষ্ট কৰা হৈছে"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"ক্লিপব’ৰ্ডৰ পৰা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> পে’ষ্ট কৰা হৈছে"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>এ আপুনি প্ৰতিলিপি কৰা সমল পে’ষ্ট কৰিছে"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>এ আপুনি প্ৰতিলিপি কৰা এটা প্ৰতিচ্ছবি পে’ষ্ট কৰিছে"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>এ আপুনি প্ৰতিলিপি কৰা সমল পে’ষ্ট কৰিছে"</string>
<string name="more_item_label" msgid="7419249600215749115">"অধিক"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"মেনু+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"মেটা+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"কৰ্মস্থান"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"ব্যক্তিগত ভিউ"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"কৰ্মস্থানৰ ভিউ"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"আপোনাৰ আইটি প্ৰশাসকে অৱৰোধ কৰিছে"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"এই সমল কৰ্মস্থানৰ এপৰ সৈতে শ্বেয়াৰ কৰিব নোৱাৰি"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"এই সমল কৰ্মস্থানৰ এপৰ জৰিয়তে খুলিব নোৱাৰি"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"এই সমল ব্যক্তিগত এপৰ সৈতে শ্বেয়াৰ কৰিব নোৱাৰি"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"এই সমল ব্যক্তিগত এপৰ জৰিয়তে খুলিব নোৱাৰি"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"কৰ্মস্থানৰ প্ৰ\'ফাইলটো পজ কৰা আছে"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"অন কৰিবলৈ টিপক"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"কোনো কৰ্মস্থানৰ এপ্‌ নাই"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"কোনো ব্যক্তিগত এপ্‌ নাই"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"<xliff:g id="APP">%s</xliff:g>ত ব্যক্তিগত প্ৰ’ফাইলত খুলিবনে?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"<xliff:g id="APP">%s</xliff:g>ত কৰ্মস্থানৰ প্ৰ’ফাইলত খুলিবনে?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ব্যক্তিগত ব্ৰাউজাৰ ব্যৱহাৰ কৰক"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"কৰ্মস্থানৰ ব্ৰাউজাৰ ব্যৱহাৰ কৰক"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ছিম নেটৱৰ্ক আনলক কৰা পিন"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ছিম নেটৱৰ্ক আনলক কৰা পিন"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ছিম কৰ্পৰে\'ট আনলক কৰা পিন"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"বিবৰ্ধনৰ নতুন ছেটিং"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"আপুনি এতিয়া আপোনাৰ স্ক্ৰীনখনৰ কিছু অংশ বিবৰ্ধন কৰিব পাৰে"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ছেটিঙত অন কৰক"</string>
<string name="dismiss_action" msgid="1728820550388704784">"অগ্ৰাহ্য কৰক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index a753fd891a4e..53c8738d4e96 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Tətbiqə yaxınlıqdakı Bluetooth cihazlarını aşkarlamaq və birləşdirməyə icazə verir"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"birləşdirilmiş Bluetooth cihazlarına qoşulmaq"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Tətbiqə birləşdirilmiş Bluetooth cihazlarına qoşulmağa icazə verir"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tərcih edilən NFC ödəniş xidməti məlumatı"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tətbiqə qeydiyyatdan keçmiş yardım və marşrut təyinatı kimi tərcih edilən nfc ödəniş xidməti məlumatını əldə etmək icazəsi verir."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication\'ı kontrol et"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Üz kilidi"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Üzünüzü yenidən qeydiyyatdan keçirin"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Tanınmanı təkmilləşdirmək üçün üzünüzü yenidən qeydiyyatdan keçirin"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Üz ilə kiliddən çıxarmanı ayarlayın"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefona baxaraq onu kiliddən çıxarın"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Kiliddən çıxarmağın daha çox yolunu ayarlayın"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Barmaq izi əlavə etmək üçün toxunun"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Dəqiq üz datası əldə edilmədi. Yenidən cəhd edin."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Çox işıqlıdır. Daha az işıqlı şəkli sınayın."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Çox qaranlıqdır. Parlaq işıqdan istifadə edin."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"Kopyalandı"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> tətbiqindən əlavə edilib"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> mübadilə buferindən əlavə edilib"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kopyaladığınız mətni əlavə etdi"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kopyaladığınız şəkli əlavə etdi"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kopyaladığınız kontenti əlavə etdi"</string>
<string name="more_item_label" msgid="7419249600215749115">"Digər"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Menyu+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"İş"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Şəxsi məzmuna baxış"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"İş məzmununa baxış"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"IT admininiz tərəfindən bloklanıb"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Bu kontenti iş tətbiqləri ilə paylaşmaq mümkün deyil"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Bu kontenti iş tətbiqləri ilə açmaq mümkün deyil"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Bu kontenti şəxsi tətbiqlər ilə paylaşmaq mümkün deyil"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Bu kontenti şəxsi tətbiqlər ilə açmaq mümkün deyil"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"İş profilinə fasilə verilib"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Aktiv etmək üçün toxunun"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"İş tətbiqi yoxdur"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Şəxsi tətbiq yoxdur"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Şəxsi profildə <xliff:g id="APP">%s</xliff:g> tətbiqində açılsın?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"İş profilində <xliff:g id="APP">%s</xliff:g> tətbiqində açılsın?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Şəxsi brauzerdən istifadə edin"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"İş brauzerindən istifadə edin"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM şəbəkəsi kilidaçma PİN\'i"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM Şəbəkəsi Alt Dəstinin kilidaçma PIN\'i"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM korporativ kilidaçma PIN\'i"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Yeni böyütmə ayarları"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"İndi ekranınızın bir hissəsini böyüdə bilərsiniz"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlarda aktiv edin"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Qapadın"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 9d913a265cb9..a8f8226a49fd 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -542,6 +542,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Dozvoljava aplikaciji da otkriva Bluetooth uređaje u blizini i uparuje se sa njima"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezivanje sa uparenim Bluetooth uređajima"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Dozvoljava aplikaciji da se povezuje sa uparenim Bluetooth uređajima"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o željenoj NFC usluzi za plaćanje"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da preuzima informacije o željenoj NFC usluzi za plaćanje, poput registrovanih identifikatora aplikacija i odredišta preusmeravanja."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrola komunikacije u užem polju (Near Field Communication)"</string>
@@ -1493,7 +1497,7 @@
<string name="ime_action_previous" msgid="6548799326860401611">"Prethodno"</string>
<string name="ime_action_default" msgid="8265027027659800121">"Izvrši"</string>
<string name="dial_number_using" msgid="6060769078933953531">"Biraj broj\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <string name="create_contact_using" msgid="6200708808003692594">"Kreirajte kontakt\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="create_contact_using" msgid="6200708808003692594">"Napravite kontakt\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Sledeće aplikacije zahtevaju dozvolu za pristup nalogu, kako sada, tako i ubuduće."</string>
<string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Želite da odobrite ovaj zahtev?"</string>
<string name="grant_permissions_header_text" msgid="3420736827804657201">"Zahtev za pristup"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index eb30d2d5fa13..93adffd1ef23 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -545,6 +545,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дазваляе праграме выяўляць прылады з Bluetooth і спалучацца з імі"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"падключацца да спалучаных прылад з Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дазваляе праграме падключацца да спалучаных прылад з Bluetooth"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Інфармацыя пра прыярытэтны сэрвіс аплаты NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дазваляе праграме атрымаць доступ да інфармацыі пра прыярытэтны сэрвіс аплаты NFC, напрыклад зарэгістраваныя ідэнтыфікатары праграм і маршруты адпраўкі даных."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"кантроль Near Field Communication"</string>
@@ -1777,7 +1781,7 @@
<string name="error_message_title" msgid="4082495589294631966">"Памылка"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Ваш адміністратар не дазваляе гэту змену"</string>
<string name="app_not_found" msgid="3429506115332341800">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
- <string name="revoke" msgid="5526857743819590458">"Ануляваць"</string>
+ <string name="revoke" msgid="5526857743819590458">"Адклікаць"</string>
<string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string>
<string name="mediasize_iso_a1" msgid="4063589931031977223">"ISO A1"</string>
<string name="mediasize_iso_a2" msgid="2779860175680233980">"ISO A2"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 317ad7ab46c8..2cdc8d1db804 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дава възможност на приложението да открива устройства с Bluetooth в близост и да се сдвоява с тях"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"свързване със сдвоените устройства с Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дава възможност на приложението да се свързва със сдвоените устройства с Bluetooth"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информация за предпочитаната услуга за плащане чрез NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дава възможност на приложението да получава информация за предпочитаната услуга за плащане чрез NFC, като например регистрирани помощни средства и местоназначение."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контролиране на комуникацията в близкото поле"</string>
@@ -573,8 +577,7 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Няма зададен ПИН код, фигура или парола"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при удостоверяването"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ползване на заключв. на екрана"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Въведете опцията си за заключване на екрана, за да продължите"</string>
<!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
<skip />
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатъкът не бе обработен. Моля, опитайте отново."</string>
@@ -661,8 +664,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Използване на отключв. с лице"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Използване на отключването с лице или опцията за заключване на екрана"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Използвайте лицето си, за да продължите"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Използвайте лицето си или опцията за заключване на екрана, за да продължите"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 52fc66649d4b..75a33afedc1b 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"অ্যাপটিকে কাছাকাছি ব্লুটুথ ডিভাইস খুঁজে দেখতে এবং তার সাথে পেয়ার করার অনুমতি দেয়"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়ার করা ব্লুটুথ ডিভাইসের সাথে কানেক্ট করুন"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"অ্যাপটিকে পেয়ার করা ব্লুটুথ ডিভাইসের সাথে কানেক্ট করতে অনুমতি দেয়"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"পছন্দের NFC পেমেন্ট পরিষেবার তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"অ্যাপের মাধ্যমে পছন্দসই এনএফসি পেমেন্ট পরিষেবার তথ্য, যেমন রেজিস্ট্রার করার সহায়তা এবং রুট ডেস্টিনেশন সম্পর্কিত তথ্য অ্যাক্সেস করার অনুমতি দেয়।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়ার ফিল্ড কমিউনিকেশন নিয়ন্ত্রণ করে"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"মুখের সাহায্যে আনলক"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"আপনার ফেস আবার এনরোল করুন"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"শনাক্তকরণের উন্নতি করতে আপনার ফেস আবার এনরোল করুন"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"মুখের সাহায্যে আনলক করার ফিচার সেট-আপ করুন"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"আপনার ফোনের দিকে তাকিয়ে এটিকে আনলক করুন"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"আনলক করার জন্য বিভিন্ন উপায়ে সেট আপ করুন"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"একটি আঙ্গুলের ছাপ যোগ করতে ট্যাপ করুন"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"মুখের সঠিক ডেটা পাওয়া যায়নি। আবার চেষ্টা করুন।"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"খুব উজ্জ্বল। আলো কমিয়ে চেষ্টা করে দেখুন।"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"খুব অন্ধকার। আরও উজ্জ্বল আলো ব্যবহার করে দেখুন।"</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"কপি করা হয়েছে"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> থেকে কপি করা ডেটা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-এ পেস্ট করা হয়েছে"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"ক্লিপবোর্ডের ডেটা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-এ পেস্ট করা হয়েছে"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"আপনার কপি করা টেক্সট <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> অ্যাপ পেস্ট করেছে"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"আপনার কপি করা ছবি <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> অ্যাপ পেস্ট করেছে"</string>
+ <string name="pasted_content" msgid="646276353060777131">"আপনার কপি করা কন্টেন্ট <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> অ্যাপ পেস্ট করেছে"</string>
<string name="more_item_label" msgid="7419249600215749115">"আরও"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"মেনু+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"অফিস"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"ব্যক্তিগত ভিউ"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"অফিসের ভিউ"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"আপনার আইটি অ্যাডমিন ব্লক করেছেন"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"অফিসের অ্যাপে এই কন্টেন্ট শেয়ার করা যাবে না"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"অফিসের অ্যাপে এই খোলা যাবে না"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ব্যক্তিগত অ্যাপে এই কন্টেন্ট শেয়ার করা যাবে না"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ব্যক্তিগত অ্যাপে এই কন্টেন্ট খোলা যাবে না"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"অফিস প্রোফাইল বন্ধ করা আছে"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"চালু করতে ট্যাপ করুন"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"অফিসের অ্যাপ ব্যবহার করা যাবে না"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ব্যক্তিগত অ্যাপে দেখা যাবে না"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"ব্যক্তিগত প্রোফাইলে <xliff:g id="APP">%s</xliff:g> অ্যাপ খুলতে চান?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"অফিস প্রোফাইলে <xliff:g id="APP">%s</xliff:g> অ্যাপ খুলতে চান?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ব্যক্তিগত ব্রাউজার ব্যবহার করুন"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"অফিস ব্রাউজার ব্যবহার করুন"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"সিম নেটওয়ার্ক আনলক পিন"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"সিম নেটওয়ার্ক সাবসেট আনলক পিন"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"কর্পোরেট সিম আনলক পিন"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"বড় করে দেখার নতুন সেটিংস"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"আপনার স্ক্রিনের অংশ এখন আপনি বড় করে দেখতে পারবেন"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"সেটিংস থেকে চালু করুন"</string>
<string name="dismiss_action" msgid="1728820550388704784">"বাতিল করুন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0921e5f6a077..c891a539f99d 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -542,6 +542,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Dozvoljava aplikaciji da otkrije Bluetooth uređaje u blizini i upari se s njima"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezivanje s uparenim Bluetooth uređajima"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Dozvoljava aplikaciji da se poveže s uparenim Bluetooth uređajima"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja putem NFC-a"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da dobije informacije o preferiranoj usluzi plaćanja putem NFC-a kao što su registrirana pomagala i odredište rute."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje NFC-om"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 35ae1debed14..0d97a7053ea8 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permet que l\'aplicació detecti i vinculi dispositius Bluetooth propers"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connectar-se a dispositius Bluetooth vinculats"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permet que l\'aplicació es connecti a dispositius Bluetooth vinculats"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informació preferent sobre el servei de pagament per NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet que l\'aplicació obtingui informació preferent sobre el servei de pagament per NFC, com ara complements registrats i destinacions de rutes."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicació de camp proper (NFC)"</string>
@@ -2136,7 +2140,7 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Feina"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Visualització personal"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Visualització de treball"</string>
- <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"L\'administrador de TI ha bloquejat la compartició"</string>
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Bloquejat per l\'administrador de TI"</string>
<string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"No es pot compartir aquest contingut amb aplicacions de treball"</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"No es pot obrir aquest contingut amb aplicacions de treball"</string>
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"No es pot compartir aquest contingut amb aplicacions personals"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 36e130ec0b9e..7e163e198187 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -545,6 +545,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Umožňuje aplikaci vyhledávat zařízení Bluetooth v okolí a spárovávat se s nimi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"připojovat se ke spárovaným zařízením Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Umožňuje aplikaci připojovat se ke spárovaným zařízením Bluetooth"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informace o preferované platební službě NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikaci získat informace o preferované platební službě NFC, například o registrovaných pomůckách a cíli směrování."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ovládání technologie NFC"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0e00d3e3bb37..e79be9111524 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Appen kører"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps, der bruger batteri"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Forstørrelse"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Brug af hjælpefunktioner"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruger batteri"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps bruger batteri"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tryk for at se info om batteri- og dataforbrug"</string>
@@ -541,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Tillader, at appen registrerer og parrer Bluetooth-enheder i nærheden"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"opret forbindelse til parrede Bluetooth-enheder"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Tillader, at appen opretter forbindelse til parrede Bluetooth-enheder"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Foretrukne oplysninger vedrørende NFC-betalingstjeneste"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillader, at appen får foretrukne oplysninger vedrørende NFC-betalingstjeneste, f.eks. registrerede hjælpemidler og rutedestinationer."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"administrere Near Field Communication"</string>
@@ -575,30 +578,22 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Der er ikke angivet pinkode, mønster eller adgangskode"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Der opstod fejl i forbindelse med godkendelse"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Brug skærmlås"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Angiv din skærmlås for at fortsætte"</string>
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Et delvist fingeraftryk blev registreret"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingeraftrykket kunne ikke behandles. Prøv igen."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Rengør sensoren"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Fingeren blev flyttet for hurtigt"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du bevægede fingeren for langsomt. Prøv igen."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv med et andet fingeraftryk"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Der er for lyst"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prøv at justere den"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeraftrykket blev godkendt"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansigtet er godkendt"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansigtet er godkendt. Tryk på Bekræft."</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardwaren til fingeraftryk er ikke tilgængelig."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Fingeraftrykket kan ikke gemmes"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Registrering af fingeraftryk fik timeout. Prøv igen."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingeraftrykshandlingen blev annulleret."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeraftrykshandlingen blev annulleret af brugeren."</string>
@@ -663,8 +658,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Ansigt <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Brug ansigtslås"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Brug ansigts- eller skærmlås"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Brug dit ansigt for at fortsætte"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Brug din ansigts- eller skærmlås for at fortsætte"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 0a516453d329..1c4da39b0ba7 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Erlaubt der App, Bluetooth-Geräte in der Nähe zu finden und zu koppeln"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Mit gekoppelten Bluetooth-Geräten verbinden"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Erlaubt der App, sich mit gekoppelten Bluetooth-Geräten zu verbinden"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informationen zum bevorzugten NFC-Zahlungsdienst"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ermöglicht der App, Informationen zum bevorzugten NFC-Zahlungsdienst abzurufen, etwa registrierte Hilfsmittel oder das Routenziel."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Nahfeldkommunikation steuern"</string>
@@ -573,8 +577,7 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Keine PIN, kein Muster und kein Passwort festgelegt"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Fehler bei der Authentifizierung"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Displaysperre verwenden"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Displaysperre eingeben, um fortzufahren"</string>
<!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
<skip />
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingerabdruck konnte nicht verarbeitet werden. Bitte versuche es noch einmal."</string>
@@ -621,14 +624,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Face Unlock"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Gesicht neu scannen lassen"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Für bessere Erkennung Gesicht neu scannen lassen"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Face Unlock einrichten"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Entsperre dein Smartphone, indem du es ansiehst"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Weitere Möglichkeiten zum Entsperren einrichten"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tippe, um einen Fingerabdruck hinzuzufügen"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Gesichtsdaten nicht gut erfasst. Erneut versuchen."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Zu hell. Schwächere Beleuchtung ausprobieren."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Zu dunkel. Probier eine hellere Beleuchtung aus."</string>
@@ -665,8 +664,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Gesicht <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlock verwenden"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Unlock oder Displaysperre verwenden"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Per Gesichtserkennung fortfahren"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Verwende die Gesichtserkennung oder deine Display-Entsperrmethode, um fortzufahren"</string>
<string-array name="face_error_vendor">
</string-array>
@@ -1033,12 +1031,9 @@
<string name="copied" msgid="4675902854553014676">"Kopiert"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat etwas von <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> eingefügt"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat etwas aus der Zwischenablage eingefügt"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat einen von dir kopierten Text eingefügt"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat ein von dir kopiertes Bild eingefügt"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat den von dir kopierten Inhalt eingefügt"</string>
<string name="more_item_label" msgid="7419249600215749115">"Mehr"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Menü+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta-Taste +"</string>
@@ -2143,31 +2138,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Geschäftlich"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Private Ansicht"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Geschäftliche Ansicht"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Von deinem IT-Administrator blockiert"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Diese Art von Inhalt kann nicht über geschäftliche Apps geteilt werden"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Diese Art von Inhalt kann nicht mit geschäftlichen Apps geöffnet werden"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Diese Art von Inhalt kann nicht über private Apps geteilt werden"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Diese Art von Inhalt kann nicht mit privaten Apps geöffnet werden"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Arbeitsprofil pausiert"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Zum Aktivieren tippen"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Keine geschäftlichen Apps"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Keine privaten Apps"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"In <xliff:g id="APP">%s</xliff:g> im privaten Profil öffnen?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"In <xliff:g id="APP">%s</xliff:g> im Arbeitsprofil öffnen?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Privaten Browser verwenden"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Arbeitsbrowser verwenden"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Entsperr-PIN für netzgebundenes Gerät"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Entsperr-PIN für subnetzgebundenes Gerät"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Entsperr-PIN für unternehmensgebundenes Gerät"</string>
@@ -2280,10 +2263,8 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
- <!-- no translation found for window_magnification_prompt_content (8159173903032344891) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Neue Vergrößerungseinstellungen"</string>
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Du kannst das Display teilweise vergrößern"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"In den Einstellungen aktivieren"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Schließen"</string>
<string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Zum Fortfahren benötigt, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; Zugriff auf das Mikrofon deines Geräts."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index ddefff5fab92..4204b9ce5789 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Η εφαρμογή εκτελείται"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Εφαρμογές που καταναλώνουν μπαταρία"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Μεγιστοποίηση"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Χρήση προσβασιμότητας"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> χρησιμοποιεί μπαταρία"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> εφαρμογές χρησιμοποιούν μπαταρία"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Επιτρέπει στην εφαρμογή την ανακάλυψη και τη σύζευξη κοντινών συσκευών Bluetooth"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"σύνδεση σε συζευγμένες συσκευές Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Επιτρέπει στην εφαρμογή τη σύνδεση σε συζευγμένες συσκευές Bluetooth"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Πληροφορίες προτιμώμενης υπηρεσίας πληρωμών NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Επιτρέπει στην εφαρμογή να λαμβάνει πληροφορίες προτιμώμενης υπηρεσίας πληρωμής NFC, όπως καταχωρημένα βοηθήματα και προορισμό διαδρομής."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ελέγχει την Επικοινωνία κοντινού πεδίου (FNC)"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Χρήση κλειδώματος οθόνης"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Εντοπίστηκε μέρους του δακτυλικού αποτυπώματος"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Δεν ήταν δυνατή η επεξεργασία του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Καθαρίστε τον αισθητήρα"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Το δάχτυλο μετακινήθηκε πολύ γρήγορα"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Πολύ αργή κίνηση δαχτύλου. Δοκιμάστε ξανά."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Δοκιμάστε άλλο δακτυλικό αποτύπωμα"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Υπερβολικά έντονος φωτισμός"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Δοκιμάστε να το προσαρμόσετε"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Η ταυτότητα του δακτυλικού αποτυπώματος ελέγχθηκε"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Έγινε έλεγχος ταυτότητας προσώπου"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Έγινε έλεγχος ταυτότητας προσώπου, πατήστε \"Επιβεβαίωση\""</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Ο εξοπλισμός δακτυλικού αποτυπώματος δεν είναι διαθέσιμος."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Δεν είναι δυνατή η ρύθμιση του δακτυλικού αποτυπώματος"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Λήξη χρονικού ορίου δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Η λειτουργία δακτυλικού αποτυπώματος ακυρώθηκε."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Η λειτουργία δακτυλικού αποτυπώματος ακυρώθηκε από τον χρήστη."</string>
@@ -621,14 +617,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Face Unlock"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Εγγράψτε ξανά το πρόσωπό σας"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Για να βελτιώσετε την αναγνώριση, εγγράψτε ξανά το πρόσωπό σας"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Ρυθμίστε το Face Unlock"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Ξεκλειδώστε το τηλέφωνό σας απλώς κοιτώντας το"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Ρυθμίστε περισσότερους τρόπους ξεκλειδώματος"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Πατήστε για να προσθέσετε δακτυλικό αποτύπωμα"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Αδύνατη λήψη ακριβών δεδομ. προσώπου. Επανάληψη."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Υπερβολικά έντονος φωτισμός. Δοκιμάστε πιο ήπιο."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Πολύ σκοτεινό περιβάλλον. Φροντίστε τον φωτισμό."</string>
@@ -1033,12 +1025,9 @@
<string name="copied" msgid="4675902854553014676">"Αντιγράφηκε"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> έκανε επικόλληση από την εφαρμογή <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> έκανε επικόλληση από το πρόχειρο"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε το κείμενο που αντιγράψατε"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε την εικόνα που αντιγράψατε"</string>
+ <string name="pasted_content" msgid="646276353060777131">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε περιεχόμενο που αντιγράψατε"</string>
<string name="more_item_label" msgid="7419249600215749115">"Περισσότερα"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Πλήκτρο Menu+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2132,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Εργασία"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Προσωπική προβολή"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Προβολή εργασίας"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Αποκλείστηκε από τον διαχειριστή IT"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Δεν είναι δυνατή η κοινοποίηση αυτού του περιεχομένου με εφαρμογές εργασιών"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Δεν είναι δυνατό το άνοιγμα αυτού του περιεχομένου με εφαρμογές εργασιών"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Δεν είναι δυνατή η κοινοποίηση αυτού του περιεχομένου με προσωπικές εφαρμογές"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Δεν είναι δυνατό το άνοιγμα αυτού του περιεχομένου με προσωπικές εφαρμογές"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Το προφίλ εργασίας σας έχει τεθεί σε παύση."</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Πατήστε για ενεργοποίηση"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Δεν υπάρχουν εφαρμογές εργασιών"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Δεν υπάρχουν προσωπικές εφαρμογές"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Άνοιγμα εφαρμογής <xliff:g id="APP">%s</xliff:g> στο προσωπικό προφίλ;"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"Άνοιγμα εφαρμογής <xliff:g id="APP">%s</xliff:g> στο προφίλ εργασίας;"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Χρήση προσωπικού προγράμματος περιήγησης"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Χρήση προγράμματος περιήγησης εργασίας"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ξεκλειδώματος δικτύου κάρτας SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN ξεκλειδώματος υποσυνόλου δικτύου κάρτας SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN ξεκλειδώματος εταιρικής SIM"</string>
@@ -2280,8 +2257,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Νέες ρυθμίσεις μεγιστοποίησης"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Μπορείτε πλέον να μεγεθύνετε μέρος της οθόνης σας"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ενεργοποίηση στις Ρυθμίσεις"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Παράβλεψη"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index ff07433cb2ce..70ae1b70b025 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Accessibility usage"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tap for details on battery and data usage"</string>
@@ -539,6 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Allows the app to discover and pair nearby Bluetooth devices"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connect to paired Bluetooth devices"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Allows the app to connect to paired Bluetooth devices"</string>
+ <string name="permlab_uwb_ranging" msgid="1386872477514626447">"range to devices using ultra-wideband"</string>
+ <string name="permdesc_uwb_ranging" product="default" msgid="1583519616137382182">"Allows the app to range to devices using ultra-wideband"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -573,30 +574,22 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string>
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Clean the sensor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Finger moved too fast"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger moved too slow. Please try again."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Fingerprint timeout reached. Try again."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string>
@@ -661,8 +654,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Use your face to continue"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use your face or screen lock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 9e314c17e686..91732c0ccaca 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Accessibility usage"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tap for details on battery and data usage"</string>
@@ -539,6 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Allows the app to discover and pair nearby Bluetooth devices"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connect to paired Bluetooth devices"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Allows the app to connect to paired Bluetooth devices"</string>
+ <string name="permlab_uwb_ranging" msgid="1386872477514626447">"range to devices using ultra-wideband"</string>
+ <string name="permdesc_uwb_ranging" product="default" msgid="1583519616137382182">"Allows the app to range to devices using ultra-wideband"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -573,30 +574,22 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string>
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Clean the sensor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Finger moved too fast"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger moved too slow. Please try again."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Fingerprint timeout reached. Try again."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string>
@@ -661,8 +654,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Use your face to continue"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use your face or screen lock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 1e3bbdeebb68..79476d53a357 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Accessibility usage"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tap for details on battery and data usage"</string>
@@ -539,6 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Allows the app to discover and pair nearby Bluetooth devices"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connect to paired Bluetooth devices"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Allows the app to connect to paired Bluetooth devices"</string>
+ <string name="permlab_uwb_ranging" msgid="1386872477514626447">"range to devices using ultra-wideband"</string>
+ <string name="permdesc_uwb_ranging" product="default" msgid="1583519616137382182">"Allows the app to range to devices using ultra-wideband"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -573,30 +574,22 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string>
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Clean the sensor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Finger moved too fast"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger moved too slow. Please try again."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Fingerprint timeout reached. Try again."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string>
@@ -661,8 +654,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Use your face to continue"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use your face or screen lock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index b4c6c851afba..34fd93b1a5d8 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Accessibility usage"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tap for details on battery and data usage"</string>
@@ -539,6 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Allows the app to discover and pair nearby Bluetooth devices"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connect to paired Bluetooth devices"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Allows the app to connect to paired Bluetooth devices"</string>
+ <string name="permlab_uwb_ranging" msgid="1386872477514626447">"range to devices using ultra-wideband"</string>
+ <string name="permdesc_uwb_ranging" product="default" msgid="1583519616137382182">"Allows the app to range to devices using ultra-wideband"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -573,30 +574,22 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string>
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Clean the sensor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Finger moved too fast"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger moved too slow. Please try again."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Fingerprint timeout reached. Try again."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string>
@@ -661,8 +654,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Use your face to continue"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Use your face or screen lock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 9e9025cae05e..6530693088c9 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -538,6 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎Allows the app to discover and pair nearby Bluetooth devices‎‏‎‎‏‎"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‎‎connect to paired Bluetooth devices‎‏‎‎‏‎"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‏‎Allows the app to connect to paired Bluetooth devices‎‏‎‎‏‎"</string>
+ <string name="permlab_uwb_ranging" msgid="1386872477514626447">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‏‎range to devices using ultra-wideband‎‏‎‎‏‎"</string>
+ <string name="permdesc_uwb_ranging" product="default" msgid="1583519616137382182">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎Allows the app to range to devices using ultra-wideband‎‏‎‎‏‎"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎Preferred NFC Payment Service Information‎‏‎‎‏‎"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎Allows the app to get preferred nfc payment service information like registered aids and route destination.‎‏‎‎‏‎"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎control Near Field Communication‎‏‎‎‏‎"</string>
@@ -572,8 +574,7 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎No pin, pattern, or password set‎‏‎‎‏‎"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎Error authenticating‎‏‎‎‏‎"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎Use screen lock‎‏‎‎‏‎"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎Enter your screen lock to continue‎‏‎‎‏‎"</string>
<string name="fingerprint_acquired_partial" msgid="694598777291084823">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎Partial fingerprint detected‎‏‎‎‏‎"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎Couldn\'t process fingerprint. Please try again.‎‏‎‎‏‎"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‎‏‏‏‎Clean the sensor‎‏‎‎‏‎"</string>
@@ -653,8 +654,7 @@
<string name="face_name_template" msgid="3877037340223318119">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‏‎Face ‎‏‎‎‏‏‎<xliff:g id="FACEID">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎Use face unlock‎‏‎‎‏‎"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎Use face or screen lock‎‏‎‎‏‎"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎Use your face to continue‎‏‎‎‏‎"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎Use your face or screen lock to continue‎‏‎‎‏‎"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 55850e3c58b2..c5660cf702c9 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App en ejecución"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que consumen batería"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliación"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uso de accesibilidad"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> está consumiendo batería"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps están consumiendo batería"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que la app descubra dispositivos Bluetooth cercanos y se conecte a ellos"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectarse a dispositivos Bluetooth vinculados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que la app se conecte a dispositivos Bluetooth vinculados"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre servicio de pago NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la app reciba información del servicio de pago NFC preferido, como el servicio de asistencia registrado y el destino de la ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar la Transmisión de datos en proximidad"</string>
@@ -573,30 +576,22 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No se estableció ningún PIN, patrón ni contraseña"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error de autenticación"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ingresa tu bloqueo de pantalla para continuar"</string>
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Detección parcial de una huella dactilar"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se pudo procesar la huella dactilar. Vuelve a intentarlo."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Limpia el sensor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Se movió el dedo demasiado rápido"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Moviste el dedo muy lento. Vuelve a intentarlo."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella dactilar"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prueba ajustarla"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Se autenticó la huella dactilar"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Se autenticó el rostro"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se autenticó el rostro; presiona Confirmar"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El hardware para detectar huellas dactilares no está disponible."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"No se puede configurar la huella dactilar"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Finalizó el tiempo de espera para la huella dactilar. Vuelve a intentarlo."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Se canceló la operación de huella dactilar."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"El usuario canceló la operación de huella dactilar."</string>
@@ -621,14 +616,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Desbloqueo facial"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Vuelve a registrar tu rostro"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para mejorar el reconocimiento, vuelve a registrar tu rostro"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Configurar Desbloqueo facial"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Desbloquea el teléfono con solo mirarlo"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configura más formas de desbloquear el dispositivo"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Presiona para agregar una huella dactilar"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Datos faciales imprecisos. Vuelve a intentarlo."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Demasiado brillante. Prueba con menos iluminación."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Demasiado oscuro. Prueba con más iluminación."</string>
@@ -665,8 +656,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Rostro <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueo facial"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar bloqueo facial o de pantalla"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Usa el rostro para continuar"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Usa tu rostro o bloqueo de pantalla para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
@@ -1033,12 +1023,9 @@
<string name="copied" msgid="4675902854553014676">"Copiado"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó contenido de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó contenido del portapapeles"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó texto que copiaste"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó una imagen que copiaste"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó el contenido que copiaste"</string>
<string name="more_item_label" msgid="7419249600215749115">"Más"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Menú+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2130,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Trabajo"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Vista personal"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Vista de trabajo"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Tu administrador de IT impide compartir este contenido"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"No se puede compartir este contenido con apps de trabajo"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"No se puede abrir este contenido con apps de trabajo"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"No se puede compartir este contenido con apps personales"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"No se puede abrir este contenido con apps personales"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"El perfil de trabajo está en pausa"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Presionar para activar"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"El contenido no es compatible con apps de trabajo"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"El contenido no es compatible con apps personales"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"¿Quieres abrir <xliff:g id="APP">%s</xliff:g> con tu perfil personal?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"¿Quieres abrir <xliff:g id="APP">%s</xliff:g> con tu perfil de trabajo?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar un navegador personal"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar un navegador de trabajo"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueo del dispositivo para la red de tarjeta SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN de desbloqueo del dispositivo para el subconjunto de redes de tarjeta SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN de desbloqueo corporativo del dispositivo para tarjeta SIM"</string>
@@ -2280,8 +2255,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nueva configuración de ampliación"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Ahora puedes ampliar parte de la pantalla"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Configuración"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Descartar"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 8276269555e1..32121a521b9b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que la aplicación detecte y vincule dispositivos Bluetooth cercanos"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectarse a dispositivos Bluetooth vinculados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que la aplicación se conecte a dispositivos Bluetooth vinculados"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre el servicio de pago por NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la aplicación obtenga información sobre el servicio de pago por NFC preferido, como identificadores de aplicación registrados y destinos de rutas."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicación de campo cercano (NFC)"</string>
@@ -2147,8 +2151,8 @@
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ninguna aplicación personal"</string>
<string name="miniresolver_open_in_personal" msgid="2937599899213467617">"¿Abrir en <xliff:g id="APP">%s</xliff:g> en el perfil personal?"</string>
<string name="miniresolver_open_in_work" msgid="152208044699347924">"¿Abrir en <xliff:g id="APP">%s</xliff:g> en el perfil de trabajo?"</string>
- <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar el navegador personal"</string>
- <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar el navegador del trabajo"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar navegador personal"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar navegador de trabajo"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueo de red de tarjeta SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN de desbloqueo de subconjunto de red SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN de desbloqueo corporativo de SIM"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 264fa4172edd..d0a046314188 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lubab rakendusel avastada lähedalasuvaid Bluetooth-seadmeid ja nendega siduda"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"seotud Bluetooth-seadmetega ühenduse loomine"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lubab rakendusel luua ühenduse seotud Bluetooth-seadmetega"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Eelistatud NFC-makseteenuse teave"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Võimaldab rakendusel hankida eelistatud NFC-makseteenuse teavet (nt registreeritud abi ja marsruudi sihtkoht)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"lähiväljaside juhtimine"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 2a6b107a2599..1fd31a114bfb 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Inguruko Bluetooth bidezko gailuak hautemateko eta haiekin parekatzeko baimena ematen die aplikazioei"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"parekatutako Bluetooth bidezko gailuetara konektatu"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Parekatutako Bluetooth bidezko gailuetara konektatzeko baimena ematen die aplikazioei"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikazioari baimena ematen dio NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa jasotzeko, hala nola erregistratutako laguntzaileak eta ibilbidearen helmuga."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 80f0870866a8..e0ffd46a9ae9 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"به برنامه اجازه می‌دهد دستگاه‌های بلوتوث اطراف را پیدا کند و با آن‌ها مرتبط شود"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"اتصال به دستگاه‌های بلوتوث مرتبط‌شده"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"به برنامه اجازه می‌دهد به دستگاه‌های بلوتوث مرتبط‌شده متصل شود"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏اطلاعات ترجیحی سرویس پولی «ارتباط میدان نزدیک» (NFC)"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏به برنامه اجازه می‌دهد اطلاعات ترجیحی سرویس پولی «ارتباط میدان نزدیک» (NFC)، مانند کمک‌های ثبت‌شده و مقصد مسیر را دریافت کند."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"کنترل ارتباط راه نزدیک"</string>
@@ -573,8 +577,7 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"پین، الگو یا گذرواژه‌ای تنظیم نشده است"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"خطا هنگام اصالت‌سنجی"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"از قفل صفحه استفاده کنید"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"برای ادامه، قفل صفحه‌تان را وارد کنید"</string>
<!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
<skip />
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"اثرانگشت پردازش نشد. لطفاً دوباره امتحان کنید."</string>
@@ -661,8 +664,7 @@
<string name="face_name_template" msgid="3877037340223318119">"چهره <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"استفاده از «بازگشایی با چهره»"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"استفاده از قفل صفحه یا چهره"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"برای ادامه، از چهره‌تان استفاده کنید"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"برای ادامه، از تشخیص چهره یا قفل صفحه استفاده کنید"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 95951dde74ea..b7c81d7aff09 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Sallii sovelluksen löytää lähellä olevia Bluetooth-laitteita ja muodostaa niistä laitepareja"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"yhdistää pariliitettyihin Bluetooth-laitteisiin"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Sallii sovelluksen muodostaa yhteyden pariliitettyihin Bluetooth-laitteisiin"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ensisijaiset NFC-maksupalvelutiedot"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Sallii sovelluksen noutaa tietoja rekisteröidyistä sovellustunnuksista, maksureitin kohteesta ja muita ensisijaisia NFC-maksupalvelutietoja."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"hallitse Near Field Communication -tunnistusta"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Face Unlock"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Lisää kasvot uudelleen"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Lisää kasvosi uudelleen tunnistamisen parantamiseksi"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Ota Face Unlock käyttöön"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Avaa puhelimesi lukitus katsomalla laitetta"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Ota käyttöön lisää tapoja avata lukitus"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Napauta lisätäksesi sormenjälki"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Tarkan kasvodatan tallennus epäonnistui. Yritä uudelleen."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Liian kirkasta. Kokeile pehmeämpää valaistusta."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Liian pimeää. Kokeile kirkkaampaa valaistusta."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"Kopioitu"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> liitetty täältä: <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> liitetty leikepöydältä"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> on liittänyt kopioimasi tekstin"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> on liittänyt kopioimasi kuvan"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> on liittänyt kopioimasi sisällön"</string>
<string name="more_item_label" msgid="7419249600215749115">"Lisää"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Valikko+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Työ"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Henkilökohtainen näkymä"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Työnäkymä"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"IT-järjestelmänvalvojasi estämä"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Tätä sisältöä ei voi jakaa työsovelluksilla"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Tätä sisältöä ei voi avata työsovelluksilla"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Tätä sisältöä ei voi jakaa henkilökohtaisilla sovelluksilla"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Tätä sisältöä ei voi avata henkilökohtaisilla sovelluksilla"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Työprofiilin käyttö on keskeytetty"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Laita päälle napauttamalla"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ei työsovelluksia"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ei henkilökohtaisia sovelluksia"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Avataanko <xliff:g id="APP">%s</xliff:g> henkilökohtaisessa profiilissa?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"Avataanko <xliff:g id="APP">%s</xliff:g> työprofiilissa?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Käytä henkilökohtaista selainta"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Käytä työselainta"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM-kortin verkkoversion lukituksen avaamisen PIN-koodi"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM-kortin verkkoversion alijoukon lukituksen avaamisen PIN-koodi"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM-kortin yritysversion lukituksen avaamisen PIN-koodi"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Uudet suurennusasetukset"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Voit nyt suurentaa näytön osan"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Laita päälle asetuksista"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Hylkää"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 8a1ddd531f86..e757fbb65c79 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permet à l\'application de découvrir les appareils Bluetooth à proximité et de s\'y connecter"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"se connecter aux appareils Bluetooth associés"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permet à l\'application de se connecter aux appareils Bluetooth associés"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information sur le service préféré de paiement NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir de l\'information sur le service préféré de paiement NFC comme les aides enregistrées et la route de destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Déverrouillage par reconnaissance faciale"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Inscrivez votre visage à nouveau"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Pour améliorer la reconnaissance, veuillez enregistrer à nouveau votre visage"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Configurer le déverrouillage par reconnaissance faciale"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Déverrouillez votre téléphone en le regardant"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurer d\'autres méthodes de déverrouillage"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Touchez pour ajouter une empreinte digitale"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Imposs. capt. données visage précises. Réessayez."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Trop lumineux. Essayez un éclairage plus faible."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Trop sombre. Essayez avec un éclairage plus fort."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"Copié"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé à partir de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé à partir du presse-papiers"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé du texte que vous avez copié"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé une image que vous avez copiée"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé le contenu que vous avez copié"</string>
<string name="more_item_label" msgid="7419249600215749115">"Plus"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Méta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Professionnel"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Affichage personnel"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Affichage professionnel"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Bloqué par votre administrateur informatique"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Impossible de partager ce contenu avec des applications professionnelles"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applications professionnelles"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applications personnelles"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applications personnelles"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Le profil professionnel est interrompu"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Touchez pour activer"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune application professionnelle"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune application personnelle"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans votre profil personnel?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans votre profil professionnel?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utiliser le navigateur du profil personnel"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utiliser le navigateur du profil professionnel"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"NIP de déverrouillage du réseau associé au module SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"NIP de déverrouillage du sous-ensemble du réseau associé au module SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"NIP de déverrouillage du module SIM professionnel"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nouveaux paramètres d\'agrandissement"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Vous pouvez agrandir une partie votre écran."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 479adf1422a1..bbf896a3fa4f 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Autorise l\'appli à détecter et à associer les appareils Bluetooth à proximité"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"se connecter aux appareils Bluetooth associés"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Autorise l\'appli à se connecter à des appareils Bluetooth associés"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informations sur le service de paiement NFC préféré"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir des informations sur le service de paiement NFC préféré, y compris les ID d\'applications et les destinations de routage enregistrés."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"contrôler la communication en champ proche"</string>
@@ -2262,8 +2266,7 @@
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
<string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nouveaux paramètres d\'agrandissement"</string>
- <!-- no translation found for window_magnification_prompt_content (8159173903032344891) -->
- <skip />
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Vous pouvez désormais agrandir une partie de l\'écran"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
<string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Pour continuer, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; a besoin d\'accéder au micro de votre appareil."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 2e252e51da6c..0e781054c3b8 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que a aplicación detecte dispositivos Bluetooth próximos e se vincule a eles"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectarse a dispositivos Bluetooth vinculados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que a aplicación se conecte aos dispositivos Bluetooth vinculados"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información do servizo de pago de NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a aplicación obteña información do servizo de pago de NFC preferido, como as axudas rexistradas e o destino da ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Near Field Communication"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index fe918d847f38..5ee5c98a51b0 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ઍપને આસપાસના બ્લૂટૂથ ડિવાઇસ શોધવાની અને તેની સાથે જોડી કરવાની મંજૂરી આપે છે"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"જોડી કરેલા બ્લૂટૂથ ડિવાઇસ સાથે કનેક્ટ કરો"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ઍપને જોડી કરેલા બ્લૂટૂથ ડિવાઇસ સાથે કનેક્ટ કરવાની મંજૂરી આપે છે"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"આ મંજૂરીને આપવાથી, ઍપ તમારી પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી મેળવી શકે છે, જેમ કે રજિસ્ટર થયેલી સહાય અને નિર્ધારિત સ્થાન."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"નિઅર ફીલ્ડ કમ્યુનિકેશન નિયંત્રિત કરો"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"ફેસ અનલૉક"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"તમારા ચહેરાની ફરી નોંધણી કરાવો"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"ઓળખવાની પ્રક્રિયાને બહેતર બનાવવા માટે કૃપા કરીને તમારા ચહેરાની ફરી નોંધણી કરાવો"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"ફેસ અનલૉક સુવિધાનું સેટઅપ કરો"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"તમારા ફોનની તરફ જોઈને તેને અનલૉક કરો"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"અનલૉક કરવાની બીજી રીતોનું સેટઅપ કરો"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ફિંગરપ્રિન્ટ ઉમેરવા માટે ટૅપ કરો"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"ચહેરાનો સચોટ ડેટા કૅપ્ચર ન થયો. ફરી પ્રયાસ કરો."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"અતિશય પ્રકાશિત. થોડો હળવો પ્રકાશ અજમાવી જુઓ."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"અતિશય ઘેરી. વધુ ઝળહળતો પ્રકાશ અજમાવો"</string>
@@ -753,7 +753,7 @@
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"ચેતવણી વિના આ Android TV ડિવાઇસ પર રહેલો આ વપરાશકર્તાનો ડેટા કાઢી નાખો."</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"ચેતવણી વિના આ ફોન પરનો આ વપરાશકર્તાનો ડેટા કાઢી નાખો."</string>
<string name="policylab_setGlobalProxy" msgid="215332221188670221">"ઉપકરણ વૈશ્વિક પ્રોક્સી સેટ કરો"</string>
- <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"પૉલિસી સક્ષમ હોય તે વખતે ઉપયોગ કરવા માટેના ડિવાઇસ વૈશ્વિક પ્રોક્સીને સેટ કરો. ફક્ત ડિવાઇસના માલિક વૈશ્વિક પ્રોક્સી સેટ કરી શકે છે."</string>
+ <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"પૉલિસી ચાલુ હોય તે વખતે ઉપયોગ કરવા માટેના ડિવાઇસ વૈશ્વિક પ્રોક્સીને સેટ કરો. ફક્ત ડિવાઇસના માલિક વૈશ્વિક પ્રોક્સી સેટ કરી શકે છે."</string>
<string name="policylab_expirePassword" msgid="6015404400532459169">"સ્ક્રીન લૉક પાસવર્ડ સમાપ્તિ સેટ કરો"</string>
<string name="policydesc_expirePassword" msgid="9136524319325960675">"કેટલા સમયાંતરે સ્ક્રીન લૉક પાસવર્ડ, પિન અથવા પૅટર્ન બદલવો આવશ્યક છે, તેને બદલો."</string>
<string name="policylab_encryptedStorage" msgid="9012936958126670110">"સંગ્રહ એન્ક્રિપ્શન સેટ કરો"</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"કૉપિ કરેલ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>માંથી કૉપિ કરાયેલો ડેટા <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>માં પેસ્ટ કરવામાં આવ્યો"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"ક્લિપબોર્ડ ડેટાને <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>માં પેસ્ટ કર્યો"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> દ્વારા તમે કૉપિ કરેલી ટેક્સ્ટ પેસ્ટ કરાઈ"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> દ્વારા તમે કૉપિ કરેલી છબી પેસ્ટ કરાઈ"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> દ્વારા તમે કૉપિ કરેલું કન્ટેન્ટ પેસ્ટ કરાયું"</string>
<string name="more_item_label" msgid="7419249600215749115">"વધુ"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"મેનૂ+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"ઑફિસ"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"વ્યક્તિગત વ્યૂ"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"ઑફિસ વ્યૂ"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"તમારા IT વ્યવસ્થાપકે બ્લૉક કર્યું છે"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"આ કન્ટેન્ટ ઑફિસ માટેની ઍપ સાથે શેર કરી શકાતું નથી"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"આ કન્ટેન્ટ ઑફિસ માટેની ઍપ વડે ખોલી શકાતું નથી"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"આ કન્ટેન્ટ વ્યક્તિગત ઍપ સાથે શેર કરી શકાતું નથી"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"આ કન્ટેન્ટ વ્યક્તિગત ઍપ વડે ખોલી શકાતું નથી"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ઑફિસની પ્રોફાઇલ થોભાવી છે"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"ચાલુ કરવા માટે ટૅપ કરો"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"કોઈ ઑફિસ માટેની ઍપ સપોર્ટ કરતી નથી"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"કોઈ વ્યક્તિગત ઍપ સપોર્ટ કરતી નથી"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"વ્યક્તિગત પ્રોફાઇલમાં <xliff:g id="APP">%s</xliff:g>માં ખોલીએ?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"ઑફિસની પ્રોફાઇલમાં <xliff:g id="APP">%s</xliff:g>માં ખોલીએ?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"વ્યક્તિગત બ્રાઉઝરનો ઉપયોગ કરો"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ઑફિસના બ્રાઉઝરના ઉપયોગ કરો"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"સિમ નેટવર્કને અનલૉક કરવાનો પિન"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"સિમ નેટવર્ક સબસેટને અનલૉક કરવાનો પિન"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"સિમ કૉર્પોરેટ કાર્ડના લૉકને અનલૉક કરવાનો પિન"</string>
@@ -2280,10 +2265,8 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
- <!-- no translation found for window_magnification_prompt_content (8159173903032344891) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"મોટું કરવા માટેના નવા સેટિંગ"</string>
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"હવે તમે તમારી સ્ક્રીનનો અમુક ભાગ મોટો કરી શકો છો"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"સેટિંગમાં ચાલુ કરો"</string>
<string name="dismiss_action" msgid="1728820550388704784">"છોડી દો"</string>
<string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ચાલુ રાખવા માટે, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;ને તમારા ડિવાઇસના માઇક્રોફોનના ઍક્સેસની જરૂર છે."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 4994da950e02..1cd7c3cb0532 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"अनुमति देने पर, ऐप्लिकेशन, आस-पास मौजूद ब्लूटूथ डिवाइसों को खोज पाएगा और उनसे जुड़ पाएगा"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"जोड़े गए ब्लूटूथ डिवाइसों से कनेक्ट करें"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"अनुमति देने पर, ऐप्लिकेशन, जोड़े गए ब्लूटूथ डिवाइसों से कनेक्ट कर पाएगा"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC का इस्तेमाल करने वाली पैसे चुकाने की पसंदीदा सेवा की जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"अगर ऐप्लिकेशन को अनुमति दी जाती है, तो वह पैसे चुकाने की आपकी उस पसंदीदा सेवा के बारे में जानकारी पा सकता है जो NFC का इस्तेमाल करती है. इसमें रजिस्टर किए गए डिवाइस और उनके आउटपुट के रूट जैसी जानकारी शामिल होती है."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"नियर फ़ील्‍ड कम्‍यूनिकेशन नियंत्रित करें"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"मालिक का चेहरा पहचानकर अनलॉक"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"अपना चेहरा फिर से दर्ज करें"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"कृपया अपना चेहरा फिर से दर्ज करें ताकि आपको बेहतर तरीके से पहचाना जा सके"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"फ़ेस अनलॉक की सुविधा सेट अप करें"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"अपने फ़ोन की तरफ़ देखकर उसे अनलॉक करें"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"फ़ोन को अनलॉक करने के दूसरे तरीके सेट अप करें"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फ़िंगरप्रिंट जोड़ने के लिए टैप करें"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"चेहरे से जुड़ा सटीक डेटा कैप्चर नहीं किया जा सका. फिर से कोशिश करें."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"बहुत रोशनी है. हल्की रोशनी आज़माएं."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"बहुत अंधेरा है. बेहतर रोशनी में आज़माएं."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"कॉपी किया गया"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> से कॉपी किए गए डेटा को <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> में चिपकाया गया है"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"क्लिपबोर्ड के डेटा को <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> में चिपकाया गया है"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने आपका कॉपी किया हुआ टेक्स्ट चिपका दिया है"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने आपकी कॉपी की हुई इमेज चिपका दी है"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने आपका कॉपी किया हुआ कॉन्टेंट चिपका दिया है"</string>
<string name="more_item_label" msgid="7419249600215749115">"और"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"मेन्यू+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"वर्क प्रोफ़ाइल"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"निजी व्यू"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"वर्क व्यू"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"आपके आईटी एडमिन ने इस कॉन्टेंट को शेयर करने की सुविधा ब्लॉक कर रखी है"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"इस कॉन्टेंट को ऑफ़िस के काम से जुड़े ऐप्लिकेशन का इस्तेमाल करके, शेयर नहीं किया जा सकता"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"इस कॉन्टेंट को ऑफ़िस के काम से जुड़े ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"इस कॉन्टेंट को निजी ऐप्लिकेशन का इस्तेमाल करके, शेयर नहीं किया जा सकता"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"इस कॉन्टेंट को निजी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"वर्क प्रोफ़ाइल रोक दी गई है"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"वर्क प्रोफ़ाइल चालू करने के लिए टैप करें"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"यह कॉन्टेंट, ऑफ़िस के काम से जुड़े आपके किसी भी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"यह कॉन्टेंट आपके किसी भी निजी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"क्या आप <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन को निजी प्रोफ़ाइल में खोलना चाहते हैं?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"क्या आप <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन को वर्क प्रोफ़ाइल में खोलना चाहते हैं?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"निजी ब्राउज़र का इस्तेमाल करें"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ऑफ़िस के काम से जुड़े ब्राउज़र का इस्तेमाल करें"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"सिम नेटवर्क को अनलॉक करने का पिन"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"सिम नेटवर्क के सबसेट को अनलॉक करने का पिन"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"कारोबार के लिए इस्तेमाल होने वाले सिम को अनलॉक करने का पिन"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"ज़ूम करके देखने की नई सुविधा उपलब्ध है"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"अब आप अपनी स्क्रीन के किसी हिस्से को ज़ूम करके देख सकते हैं"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग में जाकर, इस सुविधा को चालू करें"</string>
<string name="dismiss_action" msgid="1728820550388704784">"खारिज करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3d774ee5dac7..d85123f40bb4 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -542,6 +542,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Aplikaciji omogućuje otkrivanje i uparivanje Bluetooth uređaja u blizini"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezati se s uparenim Bluetooth uređajima"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Aplikaciji omogućuje povezivanje s uparenim Bluetooth uređajima"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Omogućuje aplikaciji primanje informacija o preferiranoj usluzi plaćanja NFC kao što su registrirana pomagala i odredište."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 4ef186461e5e..38fc52965d4d 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lehetővé teszi az alkalmazás számára a közeli Bluetooth-eszközök felfedezését és a velük való párosítást."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"csatlakozás párosított Bluetooth-eszközökhöz"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lehetővé teszi az alkalmazás számára a párosított Bluetooth-eszközökhöz való csatlakozást."</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferált NFC fizetési szolgáltatási információk"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lehetővé teszi az alkalmazás számára preferált NFC fizetési szolgáltatási információk (pl. regisztrált alkalmazásazonosítók és útvonali cél) lekérését."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC technológia vezérlése"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 980f1afb60f7..04de38e8d6f8 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Թույլ է տալիս հավելվածին հայտնաբերել և զուգակցել մոտակա Bluetooth սարքերը"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"միանալ զուգակցված Bluetooth սարքերի"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Թույլ է տալիս հավելվածին միանալ զուգակցված Bluetooth սարքերի"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Տեղեկություններ NFC վճարային ծառայության մասին"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Թույլ է տալիս հավելվածին ստանալ նախընտրելի NFC վճարային ծառայության մասին տեղեկություններ (օր․՝ գրանցված լրացուցիչ սարքերի և երթուղու նպատակակետի մասին տվյալներ)։"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"վերահսկել Մոտ Տարածությամբ Հաղորդակցումը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 82a193de3947..62b7adbb9530 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Mengizinkan aplikasi menemukan dan menyambungkan perangkat Bluetooth di sekitar"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"hubungkan ke perangkat Bluetooth yang disambungkan"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Mengizinkan aplikasi terhubung ke perangkat Bluetooth yang disambungkan"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasi Layanan Pembayaran NFC Pilihan"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Mengizinkan aplikasi untuk mendapatkan informasi layanan pembayaran NFC pilihan seperti bantuan terdaftar dan tujuan rute."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrol NFC"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 8e7c9ec1e751..63c2e4f9641c 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Forrit er í gangi"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Forrit sem nota rafhlöðuorku"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Stækkun"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Aðgengisnotkun"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> notar rafhlöðuorku"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> forrit nota rafhlöðuorku"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Leyfir forritinu að finna nálæg Bluetooth-tæki og parast við þau"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"tengjast pöruðum Bluetooth-tækjum"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Leyfir forritinu að tengjast pöruðum Bluetooth-tækjum"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Upplýsingar um valda NFC-greiðsluþjónustu"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gerir forritinu kleift að fá valda NFC-greiðsluþjónustu, svo sem skráða aðstoð og áfangastað leiðar."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"stjórna nándarsamskiptum (NFC)"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Nota skjálás"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Hluti fingrafars greindist"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ekki var hægt að vinna úr fingrafarinu. Reyndu aftur."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Hreinsaðu lesarann"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Fingur hreyfður of hratt"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Fingurinn hreyfðist of hægt. Reyndu aftur."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prófaðu annað fingrafar"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Of bjart"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prófaðu að breyta stöðu fingursins"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingrafar staðfest"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Andlit staðfest"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Andlit staðfest, ýttu til að staðfesta"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingrafarsvélbúnaður ekki til staðar."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Ekki er hægt að setja upp fingrafar"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Tímamörk runnu út fyrir fingrafar. Reyndu aftur."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Hætt við fingrafarsaðgerð."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Notandi hætti við að nota fingrafar."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index c34defc721e2..f7922cc41eee 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App in esecuzione"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"App che consumano la batteria"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ingrandimento"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Utilizzo dell\'accessibilità"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> sta consumando la batteria"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> app stanno consumando la batteria"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Consente all\'app di rilevare e accoppiare dispositivi Bluetooth nelle vicinanze"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Connessione a dispositivi Bluetooth accoppiati"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Consente all\'app di connettersi ai dispositivi Bluetooth accoppiati"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informazioni del servizio di pagamento NFC preferito"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Consente all\'app di recuperare informazioni del servizio di pagamento NFC preferito, quali destinazione della route e identificatori applicazione registrati."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controllo Near Field Communication"</string>
@@ -573,30 +576,22 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Non hai impostato PIN, sequenza o password"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Errore durante l\'autenticazione"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usa il blocco schermo"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Inserisci il blocco schermo per continuare"</string>
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impronta parziale rilevata"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossibile elaborare l\'impronta. Riprova."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Pulisci il sensore"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Hai tolto il dito troppo presto"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Movimento del dito troppo lento. Riprova."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prova con un\'altra impronta"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Troppa luce"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prova a regolare"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Impronta autenticata"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Volto autenticato"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Volto autenticato, premi Conferma"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware per l\'impronta non disponibile."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Impossibile configurare l\'impronta"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Timeout impronta. Riprova."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Operazione associata all\'impronta annullata."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operazione di autenticazione dell\'impronta annullata dall\'utente."</string>
@@ -661,8 +656,7 @@
<string name="face_name_template" msgid="3877037340223318119">"Volto <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"Usa Sblocco con il volto"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usa Sblocco con il volto o il blocco schermo"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Usa il tuo volto per continuare"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Per continuare devi usare il tuo volto o il tuo blocco schermo"</string>
<string-array name="face_error_vendor">
</string-array>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 7dda7ce3278f..ca66487ba506 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -46,19 +46,19 @@
<string name="badPuk" msgid="4232069163733147376">"‏ה-PUK שהקלדת שגוי."</string>
<string name="mismatchPin" msgid="2929611853228707473">"קודי הגישה שהקלדת לא תואמים."</string>
<string name="invalidPin" msgid="7542498253319440408">"יש להקליד קוד אימות שאורכו 4 עד 8 ספרות."</string>
- <string name="invalidPuk" msgid="8831151490931907083">"‏הקלד PUK באורך 8 מספרים או יותר."</string>
+ <string name="invalidPuk" msgid="8831151490931907083">"‏יש להקליד PUK באורך 8 ספרות לפחות."</string>
<string name="needPuk" msgid="7321876090152422918">"‏כרטיס ה-SIM נעול באמצעות PUK. יש להקליד את קוד ה-PUK כדי לבטל את הנעילה."</string>
<string name="needPuk2" msgid="7032612093451537186">"‏יש להקליד PUK2 כדי לבטל את חסימת כרטיס ה-SIM."</string>
<string name="enablePin" msgid="2543771964137091212">"‏לא הצלחת. יש להפעיל נעילת SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
- <item quantity="two">‏נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני נעילת כרטיס ה-SIM.</item>
- <item quantity="many">‏נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני נעילת כרטיס ה-SIM.</item>
- <item quantity="other">‏נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני נעילת כרטיס ה-SIM.</item>
- <item quantity="one">‏נותר לך ניסיון <xliff:g id="NUMBER_0">%d</xliff:g> לפני נעילת כרטיס ה-SIM.</item>
+ <item quantity="two">‏נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני שכרטיס ה-SIM‏ יינעל.</item>
+ <item quantity="many">‏נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני שכרטיס ה-SIM יינעל‏.</item>
+ <item quantity="other">‏נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני שכרטיס ה-SIM‏ יינעל.</item>
+ <item quantity="one">‏נותר לך ניסיון אחד (<xliff:g id="NUMBER_0">%d</xliff:g>) לפני שכרטיס ה-SIM‏ יינעל.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"IMEI"</string>
<string name="meid" msgid="3291227361605924674">"MEID"</string>
- <string name="ClipMmi" msgid="4110549342447630629">"זיהוי מתקשר של שיחה נכנסת"</string>
+ <string name="ClipMmi" msgid="4110549342447630629">"זיהוי מתקשר בשיחה נכנסת"</string>
<string name="ClirMmi" msgid="6752346475055446417">"הסתרת זיהוי מתקשר בשיחה יוצאת"</string>
<string name="ColpMmi" msgid="4736462893284419302">"מזהה של קו מחובר"</string>
<string name="ColrMmi" msgid="5889782479745764278">"הגבלה של מזהה קו מחובר"</string>
@@ -66,15 +66,15 @@
<string name="CwMmi" msgid="3164609577675404761">"שיחה ממתינה"</string>
<string name="BaMmi" msgid="7205614070543372167">"חסימת שיחות"</string>
<string name="PwdMmi" msgid="3360991257288638281">"שינוי סיסמה"</string>
- <string name="PinMmi" msgid="7133542099618330959">"שנה את קוד הגישה"</string>
+ <string name="PinMmi" msgid="7133542099618330959">"שינוי קוד האימות"</string>
<string name="CnipMmi" msgid="4897531155968151160">"מספר מתקשר נמצא"</string>
- <string name="CnirMmi" msgid="885292039284503036">"מספר מתקשר חסוי"</string>
+ <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="DndMmi" msgid="8797375819689129800">"נא לא להפריע"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"השירות \'שיחה מזוהה\' עובר כברירת מחדל למצב מוגבל. השיחה הבאה: מוגבלת"</string>
- <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"זיהוי מתקשר עובר כברירת מחדל למצב מוגבל. השיחה הבאה: לא מוגבלת"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"שירות השיחה המזוהה עובר כברירת מחדל למצב מוגבל. השיחה הבאה: לא מוגבלת"</string>
<string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"שירות \'שיחה מזוהה\' עובר כברירת מחדל למצב לא מוגבל. השיחה הבאה: מוגבלת"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"זיהוי מתקשר עובר כברירת מחדל למצב לא מוגבל. השיחה הבאה: לא מוגבלת"</string>
<string name="serviceNotProvisioned" msgid="8289333510236766193">"השירות לא הוקצה."</string>
@@ -107,7 +107,7 @@
<string name="serviceClassFAX" msgid="2561653371698904118">"פקס"</string>
<string name="serviceClassSMS" msgid="1547664561704509004">"SMS"</string>
<string name="serviceClassDataAsync" msgid="2029856900898545984">"אסינכרוני"</string>
- <string name="serviceClassDataSync" msgid="7895071363569133704">"סינכרוני"</string>
+ <string name="serviceClassDataSync" msgid="7895071363569133704">"סנכרון"</string>
<string name="serviceClassPacket" msgid="1430642951399303804">"מנה"</string>
<string name="serviceClassPAD" msgid="6850244583416306321">"PAD"</string>
<string name="roamingText0" msgid="7793257871609854208">"נורית מצב נדידה מופעלת"</string>
@@ -163,7 +163,7 @@
<string name="httpErrorLookup" msgid="3099834738227549349">"‏לא ניתן למצוא את כתובת ה-URL."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"סכימת אימות האתר אינה נתמכת."</string>
<string name="httpErrorAuth" msgid="469553140922938968">"האימות נכשל."</string>
- <string name="httpErrorProxyAuth" msgid="7229662162030113406">"‏האימות דרך שרת ה-Proxy נכשל."</string>
+ <string name="httpErrorProxyAuth" msgid="7229662162030113406">"‏לא ניתן לבצע את האימות דרך שרת ה-Proxy."</string>
<string name="httpErrorConnect" msgid="3295081579893205617">"לא ניתן להתחבר לשרת."</string>
<string name="httpErrorIO" msgid="3860318696166314490">"לא ניתן לתקשר עם השרת. אפשר לנסות שוב מאוחר יותר."</string>
<string name="httpErrorTimeout" msgid="7446272815190334204">"חלף הזמן הקצוב של החיבור לשרת."</string>
@@ -192,7 +192,7 @@
<string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"על ידי המנהל של פרופיל העבודה שלך"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"על ידי <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5891181538182009328">"פרופיל העבודה נמחק"</string>
- <string name="work_profile_deleted_details" msgid="3773706828364418016">"אפליקציית הניהול של פרופיל העבודה חסרה או פגומה. כתוצאה מכך, פרופיל העבודה שלך נמחק, כולל כל הנתונים הקשורים אליו. לקבלת עזרה, פנה למנהל המערכת."</string>
+ <string name="work_profile_deleted_details" msgid="3773706828364418016">"אפליקציית הניהול של פרופיל העבודה חסרה או פגומה. כתוצאה מכך, פרופיל העבודה שלך נמחק, כולל כל הנתונים הקשורים אליו. לקבלת עזרה, יש לפנות למנהל המערכת."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"פרופיל העבודה שלך אינו זמין עוד במכשיר הזה"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"בוצעו ניסיונות רבים מדי להזנת סיסמה"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"מנהל המערכת ביטל את האפשרות לשימוש במכשיר לצרכים אישיים"</string>
@@ -221,16 +221,16 @@
<string name="power_dialog" product="tv" msgid="7792839006640933763">"‏אפשרויות Android TV"</string>
<string name="power_dialog" product="default" msgid="1107775420270203046">"אפשרויות טלפון"</string>
<string name="silent_mode" msgid="8796112363642579333">"מצב שקט"</string>
- <string name="turn_on_radio" msgid="2961717788170634233">"הפעל חיבור אלחוטי"</string>
+ <string name="turn_on_radio" msgid="2961717788170634233">"הפעלת חיבור אלחוטי"</string>
<string name="turn_off_radio" msgid="7222573978109933360">"כיבוי אלחוטי"</string>
<string name="screen_lock" msgid="2072642720826409809">"נעילת מסך"</string>
<string name="power_off" msgid="4111692782492232778">"כיבוי"</string>
<string name="silent_mode_silent" msgid="5079789070221150912">"צלצול כבוי"</string>
<string name="silent_mode_vibrate" msgid="8821830448369552678">"צלצול ורטט"</string>
- <string name="silent_mode_ring" msgid="6039011004781526678">"צלצול מופעל"</string>
+ <string name="silent_mode_ring" msgid="6039011004781526678">"הצלצול מופעל"</string>
<string name="reboot_to_update_title" msgid="2125818841916373708">"‏עדכון מערכת Android"</string>
- <string name="reboot_to_update_prepare" msgid="6978842143587422365">"מתכונן לעדכון…"</string>
- <string name="reboot_to_update_package" msgid="4644104795527534811">"מעבד את חבילת העדכון…"</string>
+ <string name="reboot_to_update_prepare" msgid="6978842143587422365">"בהכנה לתהליך עדכון…"</string>
+ <string name="reboot_to_update_package" msgid="4644104795527534811">"מתבצע עיבוד של חבילת העדכון…"</string>
<string name="reboot_to_update_reboot" msgid="4474726009984452312">"מתבצע אתחול…"</string>
<string name="reboot_to_reset_title" msgid="2226229680017882787">"איפוס לנתוני היצרן"</string>
<string name="reboot_to_reset_message" msgid="3347690497972074356">"מתבצע אתחול…"</string>
@@ -239,11 +239,11 @@
<string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"‏מכשיר ה-Android TV יכבה."</string>
<string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"השעון יכבה."</string>
<string name="shutdown_confirm" product="default" msgid="136816458966692315">"הטלפון שלך ייכבה."</string>
- <string name="shutdown_confirm_question" msgid="796151167261608447">"האם ברצונך לבצע כיבוי?"</string>
+ <string name="shutdown_confirm_question" msgid="796151167261608447">"לכבות את הטלפון?"</string>
<string name="reboot_safemode_title" msgid="5853949122655346734">"אתחול למצב בטוח"</string>
<string name="reboot_safemode_confirm" msgid="1658357874737219624">"האם לבצע אתחול ולעבור למצב בטוח? הפעולה הזו תשבית את כל האפליקציות של צד שלישי שהתקנת. הן ישוחזרו לאחר הפעלה מחדש של המכשיר."</string>
<string name="recent_tasks_title" msgid="8183172372995396653">"נוצרו לאחרונה"</string>
- <string name="no_recent_tasks" msgid="9063946524312275906">"אין אפליקציות אחרונות"</string>
+ <string name="no_recent_tasks" msgid="9063946524312275906">"אין אפליקציות שהיו בשימוש לאחרונה"</string>
<string name="global_actions" product="tablet" msgid="4412132498517933867">"אפשרויות טאבלט"</string>
<string name="global_actions" product="tv" msgid="3871763739487450369">"‏אפשרויות Android TV"</string>
<string name="global_actions" product="default" msgid="6410072189971495460">"אפשרויות טלפון"</string>
@@ -260,12 +260,12 @@
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"דוח אינטראקטיבי"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"כדאי להשתמש באפשרות הזו ברוב המקרים. היא מאפשרת לך לעקוב אחר התקדמות הדוח, להזין פרטים נוספים על הבעיה ולצלם את המסך. היא עשויה להשמיט כמה קטעים שנמצאים פחות בשימוש ושיצירת הדיווח עליהם נמשכת זמן רב."</string>
<string name="bugreport_option_full_title" msgid="7681035745950045690">"דוח מלא"</string>
- <string name="bugreport_option_full_summary" msgid="1975130009258435885">"השתמש באפשרות זו כדי שההפרעה למערכת תהיה מזערית, כשהמכשיר אינו מגיב או איטי מדי, או כשאתה זקוק לכל קטעי הדוח. לא ניתן להזין פרטים נוספים או ליצור צילומי מסך נוספים."</string>
+ <string name="bugreport_option_full_summary" msgid="1975130009258435885">"כדאי להשתמש באפשרות הזו כדי שההפרעה למערכת תהיה מזערית כשהמכשיר אינו מגיב או איטי מדי, או כשצריך את כל קטעי הדוח. לא ניתן להזין פרטים נוספים או ליצור צילומי מסך נוספים."</string>
<plurals name="bugreport_countdown" formatted="false" msgid="3906120379260059206">
- <item quantity="two">יוצר צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
- <item quantity="many">יוצר צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
- <item quantity="other">יוצר צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
- <item quantity="one">יוצר צילום מסך לדוח על באג בעוד שנייה <xliff:g id="NUMBER_0">%d</xliff:g>.</item>
+ <item quantity="two">המערכת יוצרת צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
+ <item quantity="many">המערכת יוצרת צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
+ <item quantity="other">המערכת יוצרת צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
+ <item quantity="one">המערכת יוצרת צילום מסך לדוח על באג בעוד שנייה (<xliff:g id="NUMBER_0">%d</xliff:g>‏).</item>
</plurals>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"בוצע צילום מסך של דוח על באג"</string>
<string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"הניסיון לצילום המסך של דוח על באג נכשל"</string>
@@ -274,7 +274,7 @@
<string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"קול מופעל"</string>
<string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"מצב טיסה"</string>
<string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"מצב טיסה מופעל"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"מצב טיסה כבוי"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"מצב הטיסה כבוי"</string>
<string name="global_action_settings" msgid="4671878836947494217">"הגדרות"</string>
<string name="global_action_assist" msgid="2517047220311505805">"סיוע"</string>
<string name="global_action_voice_assist" msgid="6655788068555086695">"האסיסטנט"</string>
@@ -304,7 +304,7 @@
<skip />
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> משתמשת בסוללה"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> אפליקציות משתמשות בסוללה"</string>
- <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"הקש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
+ <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"אפשר להקיש כדי לקבל פרטים על צריכה של נתונים וסוללה"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>, <xliff:g id="LEFT_SIDE">%1$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"מצב בטוח"</string>
<string name="android_system_label" msgid="5974767339591067210">"‏מערכת Android"</string>
@@ -331,17 +331,17 @@
<string name="permgrouplab_calllog" msgid="7926834372073550288">"יומני שיחות"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"קריאה וכתיבה של יומן השיחות של הטלפון"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"טלפון"</string>
- <string name="permgroupdesc_phone" msgid="270048070781478204">"התקשרות וניהול של שיחות טלפון"</string>
+ <string name="permgroupdesc_phone" msgid="270048070781478204">"ביצוע וניהול של שיחות טלפון"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"חיישנים לבישים"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"גישה אל נתוני חיישנים של הסימנים החיוניים שלך"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"אחזור תוכן של חלון"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"בדיקת התוכן של חלון שאיתו מתבצעת אינטראקציה."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"הפעלה של \'גילוי באמצעות מגע\'"</string>
- <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"פריטים שעליהם תקיש יוקראו בקול, ותוכל לנווט במסך באמצעות תנועות."</string>
+ <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"פריטים שמקישים עליהם יוקראו בקול, וניתן לנווט במסך באמצעות תנועות."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"הצגת טקסט בזמן הקלדה"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"כולל נתונים אישיים כמו מספרי כרטיס אשראי וסיסמאות."</string>
<string name="capability_title_canControlMagnification" msgid="7701572187333415795">"שליטה בהגדלת התצוגה"</string>
- <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"קבע את המרחק מהתצוגה ואת מיקום התצוגה."</string>
+ <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"קביעת המרחק מהתצוגה ומיקום התצוגה."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"ביצוע תנועות"</string>
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"יכול להקיש, להחליק, לעשות תנועת צביטה ולבצע תנועות אחרות."</string>
<string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"תנועות של טביעות אצבעות"</string>
@@ -353,10 +353,10 @@
<string name="permlab_statusBarService" msgid="2523421018081437981">"להיות שורת הסטטוס"</string>
<string name="permdesc_statusBarService" msgid="6652917399085712557">"מאפשרת לאפליקציה להופיע בשורת הסטטוס."</string>
<string name="permlab_expandStatusBar" msgid="1184232794782141698">"הרחב/כווץ את שורת המצב"</string>
- <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"מאפשר לאפליקציה להרחיב או לכווץ את שורת המצב."</string>
+ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"מאפשרת לאפליקציה להרחיב או לכווץ את שורת הסטטוס."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"הצגת התראות כפעילויות במסך מלא במכשיר נעול"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"מאפשרת לאפליקציה להציג התראות כפעילויות במסך מלא במכשיר נעול"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"התקן קיצורי דרך"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"התקנה של קיצורי דרך"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"מאפשרת לאפליקציה להוסיף קיצורי דרך במסך דף הבית ללא התערבות המשתמש."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"הסרת התקנה של קיצורי דרך"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"מאפשרת לאפליקציה להסיר קיצורי דרך במסך דף הבית ללא התערבות המשתמש."</string>
@@ -365,7 +365,7 @@
<string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"מענה לשיחות טלפון"</string>
<string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"מתירה לאפליקציה לענות לשיחות טלפון נכנסות"</string>
<string name="permlab_receiveSms" msgid="505961632050451881">"‏קבלת הודעות טקסט (SMS)"</string>
- <string name="permdesc_receiveSms" msgid="1797345626687832285">"‏מאפשר לאפליקציה לקבל ולעבד הודעות SMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
+ <string name="permdesc_receiveSms" msgid="1797345626687832285">"‏מאפשרת לאפליקציה לקבל ולעבד הודעות SMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
<string name="permlab_receiveMms" msgid="4000650116674380275">"‏קבלת הודעות טקסט (MMS)"</string>
<string name="permdesc_receiveMms" msgid="958102423732219710">"‏מאפשרת לאפליקציה לקבל ולעבד הודעות MMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
<string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"העברת הודעות של שידור סלולרי"</string>
@@ -373,15 +373,15 @@
<string name="permlab_manageOngoingCalls" msgid="281244770664231782">"ניהול שיחות שנערכות"</string>
<string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"לאפליקציה תהיה אפשרות לראות פרטים על שיחות שנערכות במכשיר ולשלוט בשיחות האלה."</string>
<string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"קריאת הודעות שידור סלולרי"</string>
- <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"מאפשר לאפליקציה לקרוא הודעות שידור סלולרי שהתקבלו במכשיר שלך. התראות שידור סלולרי נשלחות במקומות מסוימים על מנת להזהיר אותך מפני מצבי חירום. אפליקציות זדוניות עשויות להפריע לביצועים או לפעולה של המכשיר שלך כאשר מתקבל שידור חירום סלולרי."</string>
+ <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"מאפשרת לאפליקציה לקרוא הודעות שידור סלולרי שהתקבלו במכשיר שלך. התראות שידור סלולרי נשלחות במקומות מסוימים כדי להזהיר אותך מפני מצבי חירום. אפליקציות זדוניות עשויות להפריע לביצועים או לפעולה של המכשיר שלך כאשר מתקבל שידור חירום סלולרי."</string>
<string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"קריאת עדכוני מינויים"</string>
- <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"מאפשר לאפליקציה לקבל פרטים על ההזנות הנוכחיות שמסונכרנות."</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"מאפשרת לאפליקציה לקבל פרטים על הפידים שמסונכרנים כרגע."</string>
<string name="permlab_sendSms" msgid="7757368721742014252">"‏שליחה והצגה של הודעות SMS"</string>
<string name="permdesc_sendSms" msgid="6757089798435130769">"‏מאפשר לאפליקציה לשלוח הודעות SMS. הדבר עשוי לגרום לחיובים בלתי צפויים. אפליקציות זדוניות עלולות לגרום לעלויות על ידי שליחת הודעות ללא אישורך."</string>
<string name="permlab_readSms" msgid="5164176626258800297">"‏קריאת הודעות הטקסט שלך (SMS או MMS)"</string>
- <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"‏אפליקציה זו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות בטאבלט."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"‏האפליקציה הזו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות בטאבלט."</string>
<string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"‏האפליקציה הזו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות במכשיר ה-Android TV."</string>
- <string name="permdesc_readSms" product="default" msgid="774753371111699782">"‏אפליקציה זו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות בטלפון."</string>
+ <string name="permdesc_readSms" product="default" msgid="774753371111699782">"‏האפליקציה הזו יכולה לקרוא את כל הודעות הטקסט (SMS) המאוחסנות בטלפון."</string>
<string name="permlab_receiveWapPush" msgid="4223747702856929056">"‏קבלת הודעות טקסט (WAP)"</string>
<string name="permdesc_receiveWapPush" msgid="1638677888301778457">"‏מאפשרת לאפליקציה לקבל ולעבד הודעות WAP. ההרשאה הזו כוללת את היכולת לעקוב אחר הודעות שנשלחו אליך ולמחוק אותן מבלי להציג לך אותן."</string>
<string name="permlab_getTasks" msgid="7460048811831750262">"אחזור אפליקציות פעילות"</string>
@@ -389,45 +389,45 @@
<string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"ניהול בעלים של פרופיל ומכשיר"</string>
<string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"מאפשרת לאפליקציות להגדיר את הבעלים של הפרופיל ושל המכשיר."</string>
<string name="permlab_reorderTasks" msgid="7598562301992923804">"סידור מחדש של אפליקציות פעילות"</string>
- <string name="permdesc_reorderTasks" msgid="8796089937352344183">"מאפשר לאפליקציה להעביר משימות לחזית ולרקע. האפליקציה עשוי לעשות זאת ללא התערבותך."</string>
- <string name="permlab_enableCarMode" msgid="893019409519325311">"הפוך מצב מכונית לפעיל"</string>
+ <string name="permdesc_reorderTasks" msgid="8796089937352344183">"מאפשרת לאפליקציה להעביר משימות לחזית ולרקע. האפליקציה עשויה לעשות זאת ללא התערבות שלך."</string>
+ <string name="permlab_enableCarMode" msgid="893019409519325311">"הפעלה של מצב מכונית"</string>
<string name="permdesc_enableCarMode" msgid="56419168820473508">"מאפשרת לאפליקציה להפעיל את מצב מכונית."</string>
<string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"סגירת אפליקציות אחרות"</string>
- <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"מאפשר לאפליקציה להפסיק תהליכים ברקע המבוצעים על ידי אפליקציות אחרות. הדבר עשוי לגרום להפסקת פעולתם של אפליקציות אחרות."</string>
- <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"אפליקציה זו יכולה להופיע מעל אפליקציות אחרות."</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"מאפשרת לאפליקציה להפסיק תהליכים ברקע שמבצעות אפליקציות אחרות. הדבר עשוי לגרום להפסקת הפעולה של אפליקציות אחרות."</string>
+ <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"האפליקציה הזו יכולה להופיע מעל אפליקציות אחרות."</string>
<string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"האפליקציה הזו יכולה להופיע מעל אפליקציות אחרות או בחלקים אחרים של המסך. ייתכן שהדבר יפריע לך להשתמש באפליקציות וישנה את האופן שבו הן מופיעות."</string>
<string name="permlab_runInBackground" msgid="541863968571682785">"פעולה ברקע"</string>
<string name="permdesc_runInBackground" msgid="4344539472115495141">"האפליקציה הזו יכולה לפעול ברקע. ייתכן שהסוללה תתרוקן מהר יותר במצב הזה."</string>
<string name="permlab_useDataInBackground" msgid="783415807623038947">"שימוש בנתונים ברקע"</string>
<string name="permdesc_useDataInBackground" msgid="1230753883865891987">"האפליקציה הזו יכולה להשתמש בנתונים ברקע. ייתכן שצריכת הנתונים תגדל במצב הזה."</string>
<string name="permlab_persistentActivity" msgid="464970041740567970">"הגדרת האפליקציה לפעול תמיד"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"מאפשר לאפליקציה להפוך חלקים ממנו לקבועים בזיכרון. פעולה זו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרים ולהאט את פעולת הטאבלט."</string>
- <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"‏מאפשרת לאפליקציה לאחסן חלקים שלה בזיכרון באופן קבוע. פעולה זו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרות ולהאט את הפעולה של מכשיר ה-Android TV."</string>
- <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"מאפשר לאפליקציה להפוך חלקים ממנו לקבועים בזיכרון. פעולה זו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרים ולהאט את פעולת הטלפון."</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"מאפשרת לאפליקציה להפוך חלקים ממנה לקבועים בזיכרון. הפעולה הזו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרות ולהאט את פעולת הטאבלט."</string>
+ <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"‏מאפשרת לאפליקציה לאחסן חלקים שלה בזיכרון באופן קבוע. הפעולה הזו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרות ולהאט את הפעולה של מכשיר ה-Android TV."</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"מאפשרת לאפליקציה להפוך חלקים ממנה לקבועים בזיכרון. הפעולה הזו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרות ולהאט את פעולת הטלפון."</string>
<string name="permlab_foregroundService" msgid="1768855976818467491">"הרצת שירות קדמה"</string>
<string name="permdesc_foregroundService" msgid="8720071450020922795">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית."</string>
<string name="permlab_getPackageSize" msgid="375391550792886641">"מדידת נפח האחסון של אפליקציות"</string>
- <string name="permdesc_getPackageSize" msgid="742743530909966782">"מאפשר לאפליקציה לאחזר את הקוד, הנתונים, וגודלי קובצי המטמון שלו"</string>
+ <string name="permdesc_getPackageSize" msgid="742743530909966782">"מאפשרת לאפליקציה לאחזר את הקוד, הנתונים, ואת גודל קובצי המטמון שלה"</string>
<string name="permlab_writeSettings" msgid="8057285063719277394">"שינוי הגדרות מערכת"</string>
<string name="permdesc_writeSettings" msgid="8293047411196067188">"מאפשרת לאפליקציה לשנות את נתוני הגדרות המערכת. אפליקציות זדוניות עלולות לשבש את תצורת המערכת שלך."</string>
- <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"הפעלה בעת אתחול"</string>
+ <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"הפעלה בזמן האתחול"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"מאפשר לאפליקציה להפעיל את עצמו מיד עם סיום תהליך האתחול של המערכת. משום כך הפעלת הטאבלט עשויה להתארך והאפליקציה עלולה להאט את הפעילות הכללית של הטאבלט, בשל פעילותה התמידית."</string>
<string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"‏מאפשרת לאפליקציה להפעיל את עצמה ברגע שהמערכת מסיימת את ההפעלה. הפעולה הזו עשויה להאריך את הזמן שדרוש כדי להפעיל את מכשיר ה-Android TV, והיא מאפשרת לאפליקציה להאט את המכשיר כולו כי האפליקציה פועלת כל הזמן."</string>
- <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"מאפשר לאפליקציה להפעיל את עצמו מיד עם השלמת תהליך האתחול של המערכת. משום כך הפעלת הטלפון עשויה להתארך והאפליקציה עלולה להאט את הפעילות הכללית של הטלפון, בשל פעילותה התמידית."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"מאפשרת לאפליקציה להפעיל את עצמה מיד עם השלמת תהליך האתחול של המערכת. כתוצאה מכך, הפעלת הטלפון עשויה לארוך יותר זמן והאפליקציה עלולה להאט את הפעילות הכללית של הטלפון כי היא פועלת תמיד."</string>
<string name="permlab_broadcastSticky" msgid="4552241916400572230">"שליחת שידור במיקום קבוע"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"מאפשרת לאפליקציה לשלוח שידורים במיקום קבוע, אשר נותרים לאחר סיום השידור. אפליקציות זדוניות עלולות להאט את פעילות הטאבלט או להפוך אותה לבלתי יציבה על ידי אילוץ המכשיר להשתמש ביותר מדי זיכרון."</string>
- <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"‏מאפשרת לאפליקציה לשלוח שידורים \"דביקים\" (sticky), שנותרים לאחר שהשידור מסתיים. בעקבות שימוש מופרז באפשרות זו, שיעור ניצול הזיכרון יהיה גבוה מדי ומכשיר ה-Android TV עלול לפעול בצורה איטית או בלתי יציבה."</string>
+ <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"‏מאפשרת לאפליקציה לשלוח שידורים במיקום קבוע, שנותרים לאחר שהשידור מסתיים. בעקבות שימוש מופרז באפשרות הזו, שיעור ניצול הזיכרון יהיה גבוה מדי ומכשיר ה-Android TV עלול לפעול בצורה איטית או בלתי יציבה."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"מאפשרת לאפליקציה לשלוח שידורים במיקום קבוע, אשר נותרים לאחר סיום השידור. אפליקציות זדוניות עלולות להאט את פעילות הטלפון או להפוך אותה לבלתי יציבה על ידי אילוץ המכשיר להשתמש ביותר מדי זיכרון."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"קריאת אנשי הקשר שלך"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים בטאבלט שלך. לאפליקציות תהיה גם גישה לחשבונות בטאבלט שיצרו אנשי קשר. פעולה זו עשויה לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת. הרשאה זו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
- <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"‏מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים במכשיר ה-Android TV שלך. לאפליקציות תהיה גם גישה לחשבונות במכשיר ה-Android TV שיצרו אנשי קשר. פעולה זו עשויה לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת. הרשאה זו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים בטאבלט שלך. לאפליקציות תהיה גם גישה לחשבונות בטאבלט שיצרו אנשי קשר, כולל חשבונות שנוצרו על ידי אפליקציות שהתקנת. ההרשאה הזו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"‏מאפשרת לאפליקציה לקרוא נתונים לגבי אנשי הקשר השמורים במכשיר ה-Android TV שלך. לאפליקציות תהיה גם גישה לחשבונות שיצרו אנשי קשר במכשיר ה-Android TV. הפעולה הזו עשויה לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת. ההרשאה מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
<string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים בטלפון שלך. לאפליקציות תהיה גם גישה לחשבונות בטלפון שדרכם נוצרו אנשי קשר. הפעולה הזו עשויה לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת. ההרשאה הזו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"שינוי אנשי הקשר שלך"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים בטאבלט שלך. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים בטאבלט שלך. ההרשאה הזו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
<string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"‏מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים במכשיר ה-Android TV שלך. ההרשאה הזו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
- <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים בטלפון שלך. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים בטלפון שלך. ההרשאה הזו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"קריאת יומן שיחות"</string>
- <string name="permdesc_readCallLog" msgid="8964770895425873433">"אפליקציה זו יכולה לקרוא את היסטוריית השיחות שלך."</string>
+ <string name="permdesc_readCallLog" msgid="8964770895425873433">"האפליקציה הזו יכולה לקרוא את היסטוריית השיחות שלך."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"כתיבת יומן שיחות"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"מאפשרת לאפליקציה לשנות את יומן השיחות של הטאבלט, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות לעשות בכך שימוש כדי למחוק או לשנות את יומן השיחות שלך."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"‏מאפשרת לאפליקציה לשנות את יומן השיחות של מכשיר ה-Android TV, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות להשתמש בכך כדי למחוק או לשנות את יומן השיחות."</string>
@@ -436,23 +436,23 @@
<string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"מאפשרת לאפליקציה לגשת אל נתוני חיישנים העוקבים אחר מצבך הגופני, כמו קצב הלב."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"קריאה של אירועי יומן והפרטים שלהם"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים בטאבלט, ולשתף או לשמור את נתוני היומן."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"‏אפליקציה זו יכולה לקרוא את כל אירועי היומן המאוחסנים במכשיר ה-Android TV, ולשתף או לשמור את נתוני היומן."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"‏האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים במכשיר ה-Android TV, ולשתף או לשמור את נתוני היומן."</string>
<string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים בטלפון, ולשתף או לשמור את נתוני היומן."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"הוספה ושינוי של אירועי יומן ושליחת אימייל לאורחים ללא ידיעת הבעלים"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"אפליקציה זו יכולה להוסיף, להסיר ולשנות אירועי יומן בטאבלט. האפליקציה יכולה לשנות אירועים בלי להודיע לבעליהם ולשלוח הודעות שעשויות להיראות כאילו נשלחו מבעלי יומנים."</string>
- <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"‏אפליקציה זו יכולה להוסיף, להסיר ולשנות אירועי יומן במכשיר ה-Android TV. האפליקציה יכולה לשלוח הודעות שעשויות להיראות כאילו נשלחו מבעלי יומנים ולשנות אירועים בלי להודיע על כך לבעליהם."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"האפליקציה הזו יכולה להוסיף, להסיר ולשנות אירועי יומן בטאבלט. האפליקציה יכולה לשנות אירועים בלי להודיע לבעלים ולשלוח הודעות שעשויות להיראות כאילו נשלחו מבעלי יומנים."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"‏האפליקציה הזו יכולה להוסיף, להסיר ולשנות אירועי יומן במכשיר ה-Android TV. האפליקציה יכולה לשלוח הודעות שעשויות להיראות כאילו נשלחו מבעלי יומנים ולשנות אירועים בלי להודיע על כך לבעלים."</string>
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"אפליקציה זו יכולה להוסיף, להסיר ולשנות אירועי יומן בטלפון. האפליקציה יכולה לשנות אירועים בלי להודיע לבעליהם ולשלוח הודעות שעשויות להיראות כאילו נשלחו מבעלי יומנים."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"גישה לפקודות ספק מיקום נוספות"</string>
- <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"‏מאפשרת לאפליקציה לגשת לפקודות נוספות של ספק המיקום. הרשאה זו עשויה לאפשר לאפליקציה לשבש את פעולת ה-GPS או מקורות מיקום אחרים."</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"‏מאפשרת לאפליקציה לגשת לפקודות נוספות של ספק המיקום. ההרשאה הזו עשויה לאפשר לאפליקציה לשבש את פעולת ה-GPS או מקורות מיקום אחרים."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"קבלת גישה למיקום מדויק בחזית בלבד"</string>
<string name="permdesc_accessFineLocation" msgid="6732174080240016335">"האפליקציה הזו יכולה לקבל את המיקום המדויק שלך משירותי המיקום כאשר היא בשימוש. האפליקציה תקבל את המיקום רק אם הפעלת את שירותי המיקום במכשיר. פעולה זו עלולה להגביר את השימוש בסוללה."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"קבלת גישה למיקום משוער לאפליקציות בחזית בלבד"</string>
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"כאשר האפליקציה בשימוש היא יכולה לקבל משירותי המיקום את המיקום המשוער שלך. האפליקציה תקבל את המיקום רק אם הפעלת את שירותי המיקום במכשיר."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"גישה למיקום ברקע"</string>
<string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"לאפליקציה תמיד יש גישה למיקום, גם כשאינה בשימוש."</string>
- <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"שנה את הגדרות האודיו שלך"</string>
- <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"מאפשר לאפליקציה לשנות הגדרות אודיו גלובליות כמו עוצמת קול ובחירת הרמקול המשמש לפלט."</string>
- <string name="permlab_recordAudio" msgid="1208457423054219147">"הקלט אודיו"</string>
+ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"שינוי הגדרות האודיו שלך"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"מאפשרת לאפליקציה לשנות הגדרות אודיו גלובליות כמו עוצמת קול ובחירת הרמקול המשמש לפלט."</string>
+ <string name="permlab_recordAudio" msgid="1208457423054219147">"הקלטה של אודיו"</string>
<string name="permdesc_recordAudio" msgid="5857246765327514062">"האפליקציה הזו יכולה להשתמש במיקרופון כדי להקליט אודיו כאשר היא בשימוש."</string>
<string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"הקלטת אודיו ברקע"</string>
<string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"האפליקציה הזו יכולה להשתמש במיקרופון כדי להקליט אודיו בכל זמן."</string>
@@ -461,20 +461,20 @@
<string name="permlab_activityRecognition" msgid="1782303296053990884">"זיהוי הפעילות הגופנית"</string>
<string name="permdesc_activityRecognition" msgid="8667484762991357519">"האפליקציה מזהה את הפעילות הגופנית שלך."</string>
<string name="permlab_camera" msgid="6320282492904119413">"צילום תמונות וסרטונים"</string>
- <string name="permdesc_camera" msgid="5240801376168647151">"האפליקציה הזו יכולה להשתמש במצלמה כדי לצלם תמונות ולהקליט סרטונים כאשר היא בשימוש."</string>
+ <string name="permdesc_camera" msgid="5240801376168647151">"האפליקציה הזו יכולה להשתמש במצלמה כדי לצלם תמונות וסרטונים כאשר היא בשימוש."</string>
<string name="permlab_backgroundCamera" msgid="7549917926079731681">"צילום תמונות וסרטונים ברקע"</string>
- <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"האפליקציה הזו יכולה להשתמש במצלמה כדי לצלם תמונות ולהקליט סרטונים בכל זמן."</string>
- <string name="permlab_systemCamera" msgid="3642917457796210580">"הרשאת גישה לאפליקציה או לשירות למצלמות המערכת כדי לצלם תמונות וסרטונים"</string>
+ <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"האפליקציה הזו יכולה להשתמש במצלמה כדי לצלם תמונות וסרטונים בכל זמן."</string>
+ <string name="permlab_systemCamera" msgid="3642917457796210580">"הרשאת גישה למצלמות המערכת עבור אפליקציה או שירות כדי לצלם תמונות וסרטונים"</string>
<string name="permdesc_systemCamera" msgid="5938360914419175986">"‏האפליקציה הזו בעלת ההרשאות, או אפליקציית המערכת הזו, יכולה לצלם תמונות ולהקליט סרטונים באמצעות מצלמת מערכת בכל זמן. בנוסף, לאפליקציה נדרשת ההרשאה android.permission.CAMERA"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"‏אפליקציה או שירות יוכלו לקבל קריאות חוזרות (callback) כשמכשירי מצלמה ייפתחו או ייסגרו."</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"‏האפליקציה הזו יכולה לקבל קריאות חוזרות (callback) כשמכשיר מצלמה כלשהו נפתח (באמצעות אפליקציה) או נסגר."</string>
<string name="permlab_vibrate" msgid="8596800035791962017">"שליטה ברטט"</string>
- <string name="permdesc_vibrate" msgid="8733343234582083721">"מאפשר לאפליקציה לשלוט ברטט."</string>
+ <string name="permdesc_vibrate" msgid="8733343234582083721">"מאפשרת לאפליקציה לשלוט ברטט."</string>
<string name="permdesc_vibrator_state" msgid="7050024956594170724">"מאפשרת לאפליקציה לקבל גישה למצב רטט."</string>
<string name="permlab_callPhone" msgid="1798582257194643320">"חיוג ישירות למספרי טלפון"</string>
- <string name="permdesc_callPhone" msgid="5439809516131609109">"מאפשר לאפליקציה להתקשר למספרי טלפון ללא התערבותך. פעולה זו עשויה לגרום לשיחות או לחיובים לא צפויים. שים לב שהדבר לא מאפשר לאפליקציה להתקשר למספרי חירום. אפליקציות זדוניות עשויות לגרום לעלויות על ידי ביצוע שיחות ללא התערבותך."</string>
+ <string name="permdesc_callPhone" msgid="5439809516131609109">"מאפשרת לאפליקציה להתקשר למספרי טלפון ללא התערבות המשתמש. הפעולה הזו עשויה לגרום לשיחות או לחיובים לא צפויים. ההרשאה הזו לא מאפשרת לאפליקציה להתקשר למספרי חירום. אפליקציות זדוניות עשויות לגרום לחיובים על ידי ביצוע שיחות ללא האישור שלך."</string>
<string name="permlab_accessImsCallService" msgid="442192920714863782">"‏גישה אל שירות שיחות IMS"</string>
- <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"‏מאפשר לאפליקציה להשתמש בשירות ה-IMS לביצוע שיחות ללא התערבותך."</string>
+ <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"‏מאפשרת לאפליקציה להשתמש בשירות ה-IMS לביצוע שיחות ללא התערבות שלך."</string>
<string name="permlab_readPhoneState" msgid="8138526903259297969">"קריאת הסטטוס והזהות של הטלפון"</string>
<string name="permdesc_readPhoneState" msgid="7229063553502788058">"מאפשרת לאפליקציה לגשת לתכונות הטלפון של המכשיר. ההרשאה הזו מתירה לאפליקציה לגלות את מספר הטלפון ואת מזהי המכשיר, אם השיחה פעילה ואת המספר המרוחק המחובר באמצעות שיחה."</string>
<string name="permlab_manageOwnCalls" msgid="9033349060307561370">"ניתוב שיחות דרך המערכת"</string>
@@ -484,17 +484,17 @@
<string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"פטור מהגבלות של הקלטת אודיו"</string>
<string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"פוטרת את האפליקציה מהגבלות של הקלטת אודיו."</string>
<string name="permlab_acceptHandover" msgid="2925523073573116523">"המשך שיחה מאפליקציה אחרת"</string>
- <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"הרשאה זו מתירה לאפליקציה להמשיך שיחה שהחלה באפליקציה אחרת."</string>
+ <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"ההרשאה הזו מאפשרת לאפליקציה להמשיך שיחה שהתחילה באפליקציה אחרת."</string>
<string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"גישה למספרי הטלפון"</string>
<string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"מתירה לאפליקציה גישה למספרי הטלפון במכשיר."</string>
<string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"מסך המכונית יישאר דלוק"</string>
<string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"מניעה מהטאבלט לעבור למצב שינה"</string>
<string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"‏מונעת ממכשיר ה-Android TV להיכנס למצב שינה"</string>
- <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"מניעת מעבר הטלפון למצב שינה"</string>
+ <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"מניעה מהטלפון לעבור למצב שינה"</string>
<string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"מסך המכונית יישאר דלוק כשהאפליקציה פועלת."</string>
- <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"מאפשר לאפליקציה למנוע מהטאבלט לעבור למצב שינה."</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"מאפשרת לאפליקציה למנוע מהטאבלט לעבור למצב שינה."</string>
<string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"‏מאפשרת לאפליקציה למנוע ממכשיר ה-Android TV לעבור למצב שינה."</string>
- <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"מאפשר לאפליקציה למנוע מהטלפון לעבור למצב שינה."</string>
+ <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"מאפשרת לאפליקציה למנוע מהטלפון לעבור למצב שינה."</string>
<string name="permlab_transmitIr" msgid="8077196086358004010">"שידור באינפרה-אדום"</string>
<string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"מאפשרת לאפליקציה להשתמש במשדר האינפרה-אדום של הטאבלט."</string>
<string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"‏מאפשרת לאפליקציה להשתמש במשדר האינפרה-אדום של מכשיר ה-Android TV."</string>
@@ -502,7 +502,7 @@
<string name="permlab_setWallpaper" msgid="6959514622698794511">"הגדרת טפט"</string>
<string name="permdesc_setWallpaper" msgid="2973996714129021397">"מאפשרת לאפליקציה להגדיר את טפט המערכת."</string>
<string name="permlab_setWallpaperHints" msgid="1153485176642032714">"התאמת גודל הטפט שלך"</string>
- <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"מאפשר לאפליקציה להגדיר את סמני הגודל של טפט המערכת."</string>
+ <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"מאפשרת לאפליקציה להגדיר את סמני הגודל של טפט המערכת."</string>
<string name="permlab_setTimeZone" msgid="7922618798611542432">"הגדרת אזור זמן"</string>
<string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"מאפשרת לאפליקציה לשנות את אזור הזמן של הטאבלט."</string>
<string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"‏מאפשרת לאפליקציה לשנות את אזור הזמן של מכשיר ה-Android TV."</string>
@@ -510,33 +510,33 @@
<string name="permlab_getAccounts" msgid="5304317160463582791">"חיפוש חשבונות במכשיר"</string>
<string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"מאפשרת לאפליקציה לקבל רשימה של חשבונות המוכרים לטאבלט. הדבר עשוי לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת."</string>
<string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"‏מאפשרת לאפליקציה לקבל את רשימת החשבונות המוכרים למכשיר ה-Android TV. הפרטים עשויים לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת."</string>
- <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"מאפשר לאפליקציה לקבל רשימה של חשבונות המוכרים לטלפון. הדבר עשוי לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"מאפשרת לאפליקציה לקבל רשימה של חשבונות המוכרים לטלפון. הדבר עשוי לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת."</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"הצגת חיבורי רשת"</string>
<string name="permdesc_accessNetworkState" msgid="4394564702881662849">"מאפשרת לאפליקציה להציג מידע לגבי חיבורי רשת, למשל, אילו רשתות קיימות ומחוברות."</string>
<string name="permlab_createNetworkSockets" msgid="3224420491603590541">"קבלת גישת רשת מלאה"</string>
<string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"‏מאפשרת לאפליקציה ליצור Sockets ולהשתמש בפרוטוקולי רשת מותאמים אישית. הדפדפן, כמו אפליקציות אחרות, מספק אמצעים לשליחת נתונים לאינטרנט, כך שאישור זה אינו נחוץ לשליחת נתונים לאינטרנט."</string>
<string name="permlab_changeNetworkState" msgid="8945711637530425586">"שינוי של קישוריות הרשת"</string>
- <string name="permdesc_changeNetworkState" msgid="649341947816898736">"מאפשר לאפליקציה לשנות את מצב הקישוריות של הרשת."</string>
+ <string name="permdesc_changeNetworkState" msgid="649341947816898736">"מאפשרת לאפליקציה לשנות את מצב הקישוריות של הרשת."</string>
<string name="permlab_changeTetherState" msgid="9079611809931863861">"שינוי של קישוריות קשורה"</string>
- <string name="permdesc_changeTetherState" msgid="3025129606422533085">"מאפשר לאפליקציה לשנות את מצב הקישוריות של רשת קשורה."</string>
- <string name="permlab_accessWifiState" msgid="5552488500317911052">"‏הצג חיבורי Wi-Fi"</string>
- <string name="permdesc_accessWifiState" msgid="6913641669259483363">"‏מאפשר לאפליקציה להציג מידע על רשתות Wi-Fi, למשל, האם Wi-Fi מופעל, כמו גם שם מכשירי ה-Wi-Fi המחוברים."</string>
+ <string name="permdesc_changeTetherState" msgid="3025129606422533085">"מאפשרת לאפליקציה לשנות את מצב הקישוריות של רשת משותפת."</string>
+ <string name="permlab_accessWifiState" msgid="5552488500317911052">"‏הצגת חיבורי Wi-Fi"</string>
+ <string name="permdesc_accessWifiState" msgid="6913641669259483363">"‏מאפשרת לאפליקציה להציג מידע על רשתות Wi-Fi. למשל, אם ה-Wi-Fi מופעל ומה השמות של מכשירי ה-Wi-Fi המחוברים."</string>
<string name="permlab_changeWifiState" msgid="7947824109713181554">"‏התחברות והתנתקות מ-Wi-Fi"</string>
<string name="permdesc_changeWifiState" msgid="7170350070554505384">"‏מאפשר לאפליקציה להתחבר לנקודות גישת Wi-Fi ולהתנתק מהן, וכן לבצע שינויים בתצורת המכשיר עבור רשתות Wi-Fi."</string>
<string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"‏מאפשרת לקבל שידורים מרובים ב-Wi-Fi"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"‏מאפשר לאפליקציה לקבל חבילות שנשלחו לכל המכשירים ברשת Wi-Fi באמצעות כתובות שידור לקבוצה, ולא רק בטאבלט שלך. צריכת החשמל גבוהה יותר מאשר במצב שאינו שידור לקבוצה."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"‏מאפשרת לאפליקציה לקבל חבילות שנשלחו לכל המכשירים ברשת Wi-Fi באמצעות כתובות שידור לקבוצה, ולא רק בטאבלט שלך. צריכת הסוללה גבוהה יותר מאשר במצב שאינו שידור לקבוצה."</string>
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"‏מאפשרת לאפליקציה לקבל חבילות שנשלחו לכל המכשירים ברשת Wi-Fi באמצעות כתובות מולטיקאסט, ולא רק למכשיר ה-Android TV. צריכת החשמל תהיה גבוהה יותר מאשר במצב שאינו מולטיקאסט."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"‏מאפשרת לאפליקציה לקבל חבילות שנשלחו לכל המכשירים ברשת Wi-Fi באמצעות כתובות שידור לקבוצה, ולא רק בטלפון שלך. צריכת החשמל גבוהה יותר מאשר במצב שאינו שידור לקבוצה."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"‏גישה להגדרות Bluetooth"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"‏מאפשר לאפליקציה להגדיר את תצורתו של הטאבלט המקומי מסוג Bluetooth וכן לגלות מכשירים מרוחקים ולבצע התאמה איתם."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"‏מאפשרת לאפליקציה להגדיר את התצורה של הטאבלט המקומי מסוג Bluetooth וכן לגלות מכשירים מרוחקים ולבצע התאמה איתם."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"‏מאפשרת לאפליקציה להגדיר Bluetooth במכשיר ה-Android TV, ולגלות מכשירים מרוחקים ולבצע איתם התאמה."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"‏מאפשר לאפליקציה להגדיר את תצורתו של הטלפון המקומי מסוג Bluetooth וכן לגלות מכשירים מרוחקים ולבצע התאמה איתם."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"‏מאפשרת לאפליקציה להגדיר את התצורה של הטלפון המקומי מסוג Bluetooth וכן לגלות מכשירים מרוחקים ולבצע התאמה איתם."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"‏התחברות והתנתקות מ-WiMAX"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"‏מאפשרת לאפליקציה לדעת האם WiNMAX מופעל, ולקבל מידע לגבי רשתות WiNMAX מחוברות."</string>
- <string name="permlab_changeWimaxState" msgid="6223305780806267462">"‏שנה את מצב WiMAX"</string>
+ <string name="permlab_changeWimaxState" msgid="6223305780806267462">"‏שינוי של מצב WiMAX"</string>
<string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"‏מאפשרת לאפליקציה לחבר את הטאבלט לרשתות WiMAX ולהתנתק מהן."</string>
<string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"‏מאפשרת לאפליקציה לחבר את מכשיר ה-Android TV לרשתות WiMAX ולהתנתק מהן."</string>
- <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"‏מאפשר לאפליקציה לחבר את הטלפון לרשתות WiMAX ולהתנתק מהן."</string>
+ <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"‏מאפשרת לאפליקציה לחבר את הטלפון לרשתות WiMAX ולהתנתק מהן."</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"‏התאמה למכשירי Bluetooth"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"‏מאפשר לאפליקציה להציג את תצורת ה-Bluetooth בטאבלט, וכן ליצור ולקבל חיבורים עם מכשירים מותאמים."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"‏מאפשרת לאפליקציה להציג את הגדרת ה-Bluetooth במכשיר ה-Android TV, וליצור ולקבל חיבורים עם מכשירים מותאמים."</string>
@@ -545,25 +545,29 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"‏מאפשרת לאפליקציה לגלות מכשירי Bluetooth בקרבת מקום ולבצע התאמה איתם"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"‏התחברות למכשירי Bluetooth מתאימים"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"‏מאפשרת לאפליקציה להתחבר למכשירי Bluetooth מותאמים"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏פרטים על שירות תשלום מועדף ב-NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏מאפשרת לאפליקציה לקבל פרטים על שירות תשלום מועדף ב-NFC, כמו עזרים רשומים ויעד של נתיב."</string>
- <string name="permlab_nfc" msgid="1904455246837674977">"‏שלוט ב-Near Field Communication"</string>
+ <string name="permlab_nfc" msgid="1904455246837674977">"שליטה בתקשורת מטווח קצר"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"‏מאפשרת לאפליקציה נהל תקשורת עם תגים, כרטיסים וקוראים מסוג \'תקשורת מטווח קצר\' (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ביטול נעילת המסך שלך"</string>
- <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"מאפשר לאפליקציה להשבית את נעילת המקשים וכל אמצעי אבטחה משויך המבוסס על סיסמה. לדוגמה, הטלפון משבית את נעילת המקשים בעת קבלה של שיחת טלפון נכנסת, ולאחר מכן מפעיל מחדש את נעילת המקשים עם סיום השיחה."</string>
+ <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"מאפשרת לאפליקציה להשבית את נעילת המקשים וכל אמצעי אבטחה משויך המבוסס על סיסמה. לדוגמה, הטלפון ישבית את נעילת המקשים במהלך שיחת טלפון נכנסת, ויפעיל מחדש את נעילת המקשים עם סיום השיחה."</string>
<string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"בקשת מידע לגבי מידת המורכבות של נעילת המסך"</string>
- <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"מאפשרת לאפליקציה ללמוד את רמת המורכבות של נעילת המסך (גבוהה, בינונית, נמוכה או לא מורכבת). רמה זו מציינת את הטווח האפשרי של אורך וסוג נעילת המסך. האפליקציה יכולה גם להציע למשתמשים לעדכן את נעילת המסך לרמה מסוימת, אבל המשתמשים יכולים להתעלם מההצעה ולנווט לפריט אחר. לתשומת ליבך, נעילת המסך לא מאוחסנת כטקסט פשוט, ולכן האפליקציה לא יודעת מה הסיסמה המדויקת."</string>
+ <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"מאפשרת לאפליקציה ללמוד את רמת המורכבות של נעילת המסך (גבוהה, בינונית, נמוכה או לא מורכבת). הרמה הזו מציינת את הטווח האפשרי של אורך וסוג נעילת המסך. האפליקציה יכולה גם להציע למשתמשים לעדכן את נעילת המסך לרמה מסוימת, אבל המשתמשים יכולים להתעלם מההצעה ולנווט לפריט אחר. לתשומת ליבך, נעילת המסך לא מאוחסנת כטקסט פשוט, ולכן האפליקציה לא יודעת מה הסיסמה המדויקת."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"שימוש בחומרה ביומטרית"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"מאפשרת לאפליקציה להשתמש בחומרה ביומטרית לצורך אימות"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ניהול חומרה של טביעות אצבעות"</string>
- <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"מאפשר לאפליקציה להפעיל שיטות להוספה ומחיקה של תבניות טביעות אצבעות שבהן ייעשה שימוש."</string>
+ <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"מאפשרת לאפליקציה להפעיל שיטות להוספה ומחיקה של תבניות טביעות אצבעות שבהן ייעשה שימוש."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"שימוש בחומרה של טביעות אצבעות"</string>
<string name="permdesc_useFingerprint" msgid="412463055059323742">"מאפשרת לאפליקציה להשתמש בחומרה של טביעות אצבעות לצורך אימות"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"לשנות את אוסף המוזיקה שלך"</string>
<string name="permdesc_audioWrite" msgid="8057399517013412431">"מאפשרת לאפליקציה לשנות את אוסף המוזיקה שלך."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"לשנות את אוסף הסרטונים שלך"</string>
<string name="permdesc_videoWrite" msgid="6124731210613317051">"מאפשרת לאפליקציה לשנות את אוסף הסרטונים שלך."</string>
- <string name="permlab_imagesWrite" msgid="1774555086984985578">"לשנות את אוסף התמונות שלך"</string>
+ <string name="permlab_imagesWrite" msgid="1774555086984985578">"שינוי אוסף התמונות שלך"</string>
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"מאפשרת לאפליקציה לשנות את אוסף התמונות שלך."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"לקרוא מיקומים מאוסף המדיה שלך"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"מאפשרת לאפליקציה לקרוא מיקומים מאוסף המדיה שלך."</string>
@@ -583,7 +587,7 @@
<skip />
<!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
<skip />
- <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"לא ניתן היה לעבד את טביעת האצבע. נסה שוב."</string>
+ <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"לא ניתן היה לעבד את טביעת האצבע. אפשר לנסות שוב."</string>
<!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
<skip />
<!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
@@ -627,16 +631,12 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"שחרור נעילה על ידי זיהוי פנים"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"יש לבצע סריקה חוזרת של הפנים שלך"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"לשיפור הזיהוי יש לבצע רישום מחדש של הפנים שלך"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"הגדרת שחרור נעילה על ידי זיהוי פנים"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"יש להביט בטלפון כדי לבטל את נעילתו"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"אפשר להגדיר דרכים נוספות לביטול נעילה"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"יש להקיש כדי להוסיף טביעת אצבע"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"לא ניתן היה לקלוט את הפנים במדויק. יש לנסות שוב."</string>
- <string name="face_acquired_too_bright" msgid="8070756048978079164">"בהיר מדי. צריך תאורה עדינה יותר."</string>
+ <string name="face_acquired_too_bright" msgid="8070756048978079164">"בהירה מדי. צריך תאורה עדינה יותר."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"התמונה חשוכה מדי. צריך תאורה חזקה יותר."</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"יש להרחיק את הטלפון."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"צריך לקרב את הטלפון."</string>
@@ -652,9 +652,9 @@
<string name="face_acquired_too_similar" msgid="7684650785108399370">"דומה מדי, יש לשנות תנוחה."</string>
<string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"עליך ליישר קצת את הראש."</string>
<string name="face_acquired_tilt_too_extreme" msgid="8618210742620248049">"יש ליישר קצת את הראש."</string>
- <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"עליך ליישר קצת את הראש."</string>
+ <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"צריך ליישר קצת את הראש."</string>
<string name="face_acquired_obscured" msgid="4917643294953326639">"יש להסיר כל דבר שמסתיר את הפנים."</string>
- <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"עליך לנקות את החלק העליון של המסך, כולל הסרגל השחור"</string>
+ <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"צריך לנקות את החלק העליון של המסך, כולל הסרגל השחור"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"לא ניתן לאמת את הפנים. החומרה לא זמינה."</string>
@@ -677,38 +677,38 @@
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"סמל הפנים"</string>
- <string name="permlab_readSyncSettings" msgid="6250532864893156277">"קרא את הגדרות הסינכרון"</string>
+ <string name="permlab_readSyncSettings" msgid="6250532864893156277">"קריאת הגדרות הסנכרון"</string>
<string name="permdesc_readSyncSettings" msgid="1325658466358779298">"מאפשר לאפליקציה לקרוא את הגדרות הסנכרון של חשבון. לדוגמה, ניתן לגלות כך האם האפליקציה \'אנשים\' מסונכרן עם חשבון כלשהו."</string>
- <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"הפעלת וכיבוי סנכרון"</string>
+ <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"הפעלה וכיבוי של הסנכרון"</string>
<string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"מאפשרת לאפליקציה לשנות את הגדרות הסנכרון של חשבונות. לדוגמה, אפשר להשתמש בהרשאה הזו כדי להפעיל סנכרון של האפליקציה \'אנשים\' עם חשבון כלשהו."</string>
<string name="permlab_readSyncStats" msgid="3747407238320105332">"קריאת הנתונים הסטטיסטיים של הסנכרון"</string>
<string name="permdesc_readSyncStats" msgid="3867809926567379434">"מאפשרת לאפליקציה לקרוא את סטטיסטיקת הסנכרון של חשבון, כולל היסטוריית אירועי הסנכרון וכמות הנתונים שסונכרנה."</string>
<string name="permlab_sdcardRead" msgid="5791467020950064920">"קריאת התוכן של האחסון המשותף שלך"</string>
- <string name="permdesc_sdcardRead" msgid="6872973242228240382">"מאפשר לאפליקציה לקרוא את התוכן של האחסון המשותף."</string>
+ <string name="permdesc_sdcardRead" msgid="6872973242228240382">"מאפשרת לאפליקציה לקרוא את התוכן של האחסון המשותף."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"שינוי או מחיקה של תוכן האחסון המשותף שלך"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"מאפשר לאפליקציה לכתוב את התוכן של האחסון המשותף."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"‏ביצוע/קבלה של שיחות SIP"</string>
- <string name="permdesc_use_sip" msgid="3590270893253204451">"‏אפשר לאפליקציה לבצע ולקבל שיחות SIP."</string>
+ <string name="permdesc_use_sip" msgid="3590270893253204451">"‏מאפשרת לאפליקציה לבצע ולקבל שיחות SIP."</string>
<string name="permlab_register_sim_subscription" msgid="1653054249287576161">"‏רישום חיבורי Telecom SIM חדשים"</string>
- <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"‏מאפשר לאפליקציה לרשום חיבורי Telecom SIM חדשים."</string>
+ <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"‏מאפשרת לאפליקציה לרשום חיבורי Telecom SIM חדשים."</string>
<string name="permlab_register_call_provider" msgid="6135073566140050702">"‏רשום חיבורי Telecom חדשים"</string>
<string name="permdesc_register_call_provider" msgid="4201429251459068613">"מאפשרת לאפליקציה לרשום חיבורי תקשורת חדשים."</string>
<string name="permlab_connection_manager" msgid="3179365584691166915">"ניהול חיבורי תקשורת"</string>
- <string name="permdesc_connection_manager" msgid="1426093604238937733">"מאפשר לאפליקציה לנהל חיבורי תקשורת."</string>
- <string name="permlab_bind_incall_service" msgid="5990625112603493016">"צור אינטראקציה עם מסך שיחה נכנסת"</string>
- <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"מאפשר לאפליקציה לקבוע מתי ואיך המשתמש יראה את מסך השיחה הנכנסת."</string>
- <string name="permlab_bind_connection_service" msgid="5409268245525024736">"צור אינטראקציה עם שירותי טלפוניה"</string>
+ <string name="permdesc_connection_manager" msgid="1426093604238937733">"מאפשרת לאפליקציה לנהל חיבורי תקשורת."</string>
+ <string name="permlab_bind_incall_service" msgid="5990625112603493016">"יצירת אינטראקציה עם מסך של שיחה נכנסת"</string>
+ <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"מאפשרת לאפליקציה לקבוע מתי ואיך המשתמש יראה את מסך השיחה הנכנסת."</string>
+ <string name="permlab_bind_connection_service" msgid="5409268245525024736">"יצירת אינטראקציה עם שירותי טלפוניה"</string>
<string name="permdesc_bind_connection_service" msgid="6261796725253264518">"מאפשרת לאפליקציה ליצור אינטראקציה עם שירותי טלפוניה כדי לבצע ולקבל שיחות."</string>
<string name="permlab_control_incall_experience" msgid="6436863486094352987">"סיפוק חווית שימוש של שיחה נכנסת"</string>
<string name="permdesc_control_incall_experience" msgid="5896723643771737534">"מאפשרת לאפליקציה לספק חוויית שימוש של שיחה נכנסת."</string>
<string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"קריאת נתוני שימוש היסטוריים ברשת"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"מאפשר לאפליקציה לקרוא נתוני שימוש היסטוריים ברשת עבור רשתות ואפליקציות ספציפיות."</string>
- <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"נהל מדיניות רשת"</string>
+ <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"ניהול מדיניות רשת"</string>
<string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"מאפשרת לאפליקציה לנהל את מדיניות הרשת ולהגדיר כללים ספציפיים-לאפליקציה."</string>
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"שינוי ניהול החשבונות של שימוש ברשת"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"ההרשאה הזו מאפשרת לאפליקציה לשנות את אופן החישוב של נתוני שימוש ברשת מול כל אפליקציה. לא מיועדת לשימוש באפליקציות רגילות."</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"גישה להתראות"</string>
- <string name="permdesc_accessNotifications" msgid="761730149268789668">"מאפשר לאפליקציה לאחזר, לבדוק ולמחוק התראות, כולל כאלה שפורסמו על ידי אפליקציות אחרות."</string>
+ <string name="permdesc_accessNotifications" msgid="761730149268789668">"מאפשרת לאפליקציה לאחזר, לבדוק ולמחוק התראות, כולל כאלה שפורסמו על ידי אפליקציות אחרות."</string>
<string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"איגוד לשירות של מאזין להתראות"</string>
<string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"מאפשרת למשתמש לבצע איגוד לממשק הרמה העליונה של שירות האזנה להתראות. ההרשאה הזו אינה נחוצה לאפליקציות רגילות."</string>
<string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"איגוד לשירות ספק תנאי"</string>
@@ -724,9 +724,9 @@
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"‏גישה אל אישורי DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"‏מאפשרת לאפליקציה לנהל תצורה של אישורי DRM ולהשתמש בהם. לעולם לא אמורה להיות נחוצה עבור אפליקציה רגילה."</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"‏קבלת סטטוס העברה של Android Beam"</string>
- <string name="permdesc_handoverStatus" msgid="3842269451732571070">"‏מאפשר לאפליקציה הזו לקבל מידע על העברות Android Beam נוכחיות"</string>
+ <string name="permdesc_handoverStatus" msgid="3842269451732571070">"‏מאפשרת לאפליקציה הזו לקבל מידע על העברות Android Beam נוכחיות"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"‏הסרת אישורי DRM"</string>
- <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"‏הרשאה זו מאפשרת לאפליקציה להסיר אישורי DRM. באפליקציות רגילות אף פעם לא אמור להיות בה צורך."</string>
+ <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"‏ההרשאה הזו מאפשרת לאפליקציה להסיר אישורי DRM. אף פעם לא אמורה להיות נחוצה לאפליקציות רגילות."</string>
<string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"איגוד לשירות העברת הודעות של ספק"</string>
<string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"מאפשרת לבעלים לאגד לממשק ברמה העליונה של שירות העברת הודעות של ספק. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"איגוד לשירותי ספק"</string>
@@ -737,14 +737,14 @@
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"מאפשרת לבעלים להפעיל את השימוש בהרשאות עבור אפליקציה מסוימת. הרשאה זו אף פעם לא נדרשת עבור אפליקציות רגילות."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"גישה לנתוני חיישנים בתדירות דגימה גבוהה"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"האפליקציה תוכל לדגום נתוני חיישנים בתדירות של מעל 200 הרץ"</string>
- <string name="policylab_limitPassword" msgid="4851829918814422199">"הגדר כללי סיסמה"</string>
+ <string name="policylab_limitPassword" msgid="4851829918814422199">"הגדרת כללי סיסמה"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"קביעת האורך הנדרש והתווים המותרים בסיסמאות ובקודי האימות של מסך הנעילה."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"מעקב אחר ניסיונות לביטול של נעילת המסך"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ניהול מעקב אחר מספר הסיסמאות השגויות שמוקלדות בעת ביטול נעילת המסך, וביצוע נעילה של הטאבלט, או מחיקה של כל נתוני הטאבלט, אם מוקלדות יותר מדי סיסמאות שגויות."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"‏מעקב אחר מספר הסיסמאות השגויות שהוזנו בעת ביטול נעילת המסך, כמו גם נעילה של מכשיר ה-Android TV או מחיקה של כל נתוני מכשיר ה-Android TV אם הוזנו יותר מדי סיסמאות שגויות."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ניהול מעקב אחר מספר הסיסמאות השגויות שהוקלדו בעת ביטול נעילה המסך, וביצוע נעילה של הטלפון או מחיקה של כל נתוני הטלפון אם הוקלדו יותר מדי סיסמאות שגויות."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"מעקב אחר מספר הסיסמאות השגויות שהוקלדו במהלך ביטול נעילת המסך, וביצוע נעילה של הטלפון או מחיקה של כל נתוני הטלפון אם הוקלדו יותר מדי סיסמאות שגויות."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"מעקב אחר מספר הסיסמאות השגויות שהוזנו בעת ביטול נעילת המסך, כמו גם נעילת הטאבלט או מחיקה של כל נתוני המשתמש הזה אם הוזנו יותר מדי סיסמאות שגויות."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"‏מעקב אחר מספר הסיסמאות השגויות שהוזנו בעת ביטול נעילת המסך, כמו גם נעילה של מכשיר ה-Android TV או מחיקה של כל נתוני המשתמש הזה אם הוזנו יותר מדי סיסמאות שגויות."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"‏מעקב אחר מספר הסיסמאות השגויות שהוזנו במהלך ביטול נעילת המסך, כמו גם נעילה של מכשיר ה-Android TV או מחיקה של כל נתוני המשתמש הזה אם הוזנו יותר מדי סיסמאות שגויות."</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"מעקב אחר מספר הסיסמאות השגויות שהוזנו בעת ביטול נעילת המסך, כמו גם נעילת הטלפון או מחיקה של כל נתוני המשתמש הזה אם הוזנו יותר מדי סיסמאות שגויות."</string>
<string name="policylab_resetPassword" msgid="214556238645096520">"שינוי נעילת המסך"</string>
<string name="policydesc_resetPassword" msgid="4626419138439341851">"שינוי של נעילת המסך."</string>
@@ -755,17 +755,17 @@
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"‏מחיקה ללא אזהרה של נתוני מכשיר ה-Android TV באמצעות איפוס לנתוני היצרן."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"מחיקה של נתוני הטלפון, ללא אזהרה, על ידי ביצוע איפוס לנתוני היצרן."</string>
<string name="policylab_wipeData_secondaryUser" msgid="413813645323433166">"מחיקת נתוני משתמש"</string>
- <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"מחיקה ללא אזהרה של נתוני המשתמש הזה בטאבלט הזה."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"מחיקה של נתוני המשתמש הזה בטאבלט, ללא אזהרה."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"‏מחיקה של נתוני המשתמש הזה במכשיר ה-Android TV, ללא אזהרה."</string>
- <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"מחיקה ללא אזהרה של נתוני המשתמש הזה בטלפון הזה."</string>
- <string name="policylab_setGlobalProxy" msgid="215332221188670221">"‏הגדר את שרת ה-Proxy הכללי של המכשיר"</string>
- <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"‏הגדרה של שרת ה-proxy הגלובלי שבו ייעשה שימוש כשהמדיניות פועלת. רק הבעלים של המכשיר יכול להגדיר את שרת ה-proxy הגלובלי."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"מחיקה של נתוני המשתמש הזה בטלפון, ללא אזהרה."</string>
+ <string name="policylab_setGlobalProxy" msgid="215332221188670221">"‏הגדרה של שרת ה-Proxy הכללי של המכשיר"</string>
+ <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"‏הגדרה של שרת ה-proxy הגלובלי שבו ייעשה שימוש כשהמדיניות פועלת. רק לבעלים של המכשיר יש אפשרות להגדיר את שרת ה-proxy הגלובלי."</string>
<string name="policylab_expirePassword" msgid="6015404400532459169">"הגדרת תפוגה לסיסמת מסך הנעילה"</string>
<string name="policydesc_expirePassword" msgid="9136524319325960675">"שינוי התדירות לדרישת השינוי של הסיסמה, קוד הגישה או קו ביטול הנעילה של מסך הנעילה."</string>
<string name="policylab_encryptedStorage" msgid="9012936958126670110">"הגדרת הצפנה של אחסון"</string>
<string name="policydesc_encryptedStorage" msgid="1102516950740375617">"נדרש שנתונים של אפליקציות מאוחסנות יהיו מוצפנים."</string>
<string name="policylab_disableCamera" msgid="5749486347810162018">"השבתת מצלמות"</string>
- <string name="policydesc_disableCamera" msgid="3204405908799676104">"מנע שימוש בכל המצלמות שבמכשיר."</string>
+ <string name="policydesc_disableCamera" msgid="3204405908799676104">"מניעת שימוש בכל המצלמות שבמכשיר."</string>
<string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"השבתת חלק מהתכונות של נעילת המסך"</string>
<string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"מניעת שימוש בחלק מהתכונות של נעילת המסך."</string>
<string-array name="phoneTypes">
@@ -862,8 +862,8 @@
<string name="orgTypeWork" msgid="8684458700669564172">"עבודה"</string>
<string name="orgTypeOther" msgid="5450675258408005553">"אחר"</string>
<string name="orgTypeCustom" msgid="1126322047677329218">"בהתאמה אישית"</string>
- <string name="relationTypeCustom" msgid="282938315217441351">"מותאם אישית"</string>
- <string name="relationTypeAssistant" msgid="4057605157116589315">"עוזר"</string>
+ <string name="relationTypeCustom" msgid="282938315217441351">"בהתאמה אישית"</string>
+ <string name="relationTypeAssistant" msgid="4057605157116589315">"אסיסטנט"</string>
<string name="relationTypeBrother" msgid="7141662427379247820">"אח"</string>
<string name="relationTypeChild" msgid="9076258911292693601">"ילד"</string>
<string name="relationTypeDomesticPartner" msgid="7825306887697559238">"שותף לחיים"</string>
@@ -887,7 +887,7 @@
<string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"‏קוד PUK"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"קוד אימות חדש"</string>
<string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"יש להקיש כדי להקליד את הסיסמה"</font></string>
- <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"הקלד סיסמה לביטול הנעילה"</string>
+ <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"יש להקליד סיסמה לביטול הנעילה"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"יש להקליד קוד אימות לביטול הנעילה"</string>
<string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"קוד אימות שגוי"</string>
<string name="keyguard_label_text" msgid="3841953694564168384">"כדי לבטל את הנעילה, לחץ על \'תפריט\' ולאחר מכן על 0."</string>
@@ -902,7 +902,7 @@
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"נכון!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"כדאי לנסות שוב"</string>
<string name="lockscreen_password_wrong" msgid="8605355913868947490">"כדאי לנסות שוב"</string>
- <string name="lockscreen_storage_locked" msgid="634993789186443380">"בטל את הנעילה לכל התכונות והנתונים"</string>
+ <string name="lockscreen_storage_locked" msgid="634993789186443380">"צריך לבטל את הנעילה כדי שכל התכונות והנתונים יהיו זמינים"</string>
<string name="faceunlock_multiple_failures" msgid="681991538434031708">"חרגת ממספר הניסיונות המרבי לשחרור נעילה על ידי זיהוי פנים"</string>
<string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"‏אין כרטיס SIM"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"‏אין כרטיס SIM בטאבלט."</string>
@@ -912,32 +912,32 @@
<string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"‏כרטיס ה-SIM חסר או שלא ניתן לקרוא אותו. יש להכניס כרטיס SIM."</string>
<string name="lockscreen_permanent_disabled_sim_message_short" msgid="3812893366715730539">"‏לא ניתן להשתמש בכרטיס ה-SIM הזה."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="4358929052509450807">"‏כרטיס ה-SIM שלך הושבת באופן סופי.\nיש לפנות לספק השירות האלחוטי שלך לקבלת כרטיס SIM אחר."</string>
- <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"הרצועה הקודמת"</string>
+ <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"הטראק הקודם"</string>
<string name="lockscreen_transport_next_description" msgid="2931509904881099919">"הטראק הבא"</string>
<string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"השהה"</string>
<string name="lockscreen_transport_play_description" msgid="106868788691652733">"הפעלה"</string>
<string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"הפסקה"</string>
- <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"הרץ אחורה"</string>
+ <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"הרצה אחורה"</string>
<string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"הרצה קדימה"</string>
<string name="emergency_calls_only" msgid="3057351206678279851">"שיחות חירום בלבד"</string>
<string name="lockscreen_network_locked_message" msgid="2814046965899249635">"רשת נעולה"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"‏כרטיס SIM נעול באמצעות PUK."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"יש לעיין במדריך למשתמש או לפנות לשירות הלקוחות."</string>
<string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"‏כרטיס ה-SIM נעול."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"‏מבטל נעילה של כרטיס SIM…"</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"‏מתבצע ביטול נעילה של כרטיס SIM…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nיש לנסות שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים.\n\nיש לנסות שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"הקלדת קוד גישה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"‏שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, יהיה צורך לבטל את נעילת הטאבלט באמצעות פרטי הכניסה שלך ל-Google.\n\nיש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"‏שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את הנעילה של מכשיר ה-Android TV באמצעות כניסה לחשבון Google שלך.\n\n נסה שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"‏שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, יהיה צורך לבטל את הנעילה של מכשיר ה-Android TV באמצעות כניסה לחשבון Google שלך.\n\n אפשר לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"‏שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, יהיה צורך לבטל את נעילת הטלפון באמצעות פרטי הכניסה שלך ל-Google‏.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"ביצעת <xliff:g id="NUMBER_0">%1$d</xliff:g> ניסיונות שגויים לביטול נעילת הטאבלט. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, הטאבלט יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"‏ניסית לבטל בצורה שגויה את הנעילה של מכשיר ה-Android TV <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, מכשיר ה-Android TV יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"ביצעת <xliff:g id="NUMBER_0">%1$d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, הטלפון יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטאבלט. הטאבלט יעבור כעת איפוס לברירת המחדל של היצרן."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"‏ניסית לבטל בצורה שגויה את הנעילה של מכשיר ה-Android TV <xliff:g id="NUMBER">%d</xliff:g> פעמים. מכשיר ה-Android TV יעבור כעת איפוס לברירת המחדל של היצרן."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"‏ניסית לבטל בצורה שגויה את הנעילה של מכשיר ה-Android TV‏ <xliff:g id="NUMBER">%d</xliff:g> פעמים. מכשיר ה-Android TV יעבור עכשיו איפוס לברירת המחדל של היצרן."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. הטלפון יעבור כעת איפוס לברירת המחדל של היצרן."</string>
- <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"נסה שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"אפשר לנסות שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"שכחת את קו ביטול הנעילה?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"ביטול נעילת החשבון"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"בוצעו ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string>
@@ -948,10 +948,10 @@
<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_unlock_label" msgid="4648257878373307582">"בטל נעילה"</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>
- <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"יצירת הקו לביטול נעילה החלה"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"בתהליך שרטוט הקו לביטול נעילה"</string>
<string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"הקו לביטול נעילה נמחק"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"התא נוסף"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"תא <xliff:g id="CELL_INDEX">%1$s</xliff:g> נוסף"</string>
@@ -969,12 +969,12 @@
<string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"פקדי מדיה"</string>
<string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"‏סידור מחדש של Widgets התחיל."</string>
<string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"‏סידור מחדש של Widgets הסתיים."</string>
- <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"‏Widget ‏<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> נמחק."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"הווידג\'ט ‏<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> נמחק."</string>
<string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"הרחבה של אזור ביטול הנעילה."</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"ביטול נעילה באמצעות הסטה."</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"ביטול נעילה על ידי שרטוט קו."</string>
<string name="keyguard_accessibility_face_unlock" msgid="632407612842329815">"שחרור נעילה על ידי זיהוי פנים."</string>
- <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"ביטול נעילה באמצעות קוד גישה."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"ביטול נעילה באמצעות קוד אימות."</string>
<string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"‏ביטול הנעילה של קוד האימות ל-SIM."</string>
<string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"‏ביטול נעילה של PUK ל-SIM."</string>
<string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"ביטול נעילה באמצעות סיסמה."</string>
@@ -990,17 +990,17 @@
<string name="factorytest_failed" msgid="3190979160945298006">"בדיקת היצרן נכשלה"</string>
<string name="factorytest_not_system" msgid="5658160199925519869">"‏הפעולה FACTORY_TEST נתמכת רק עבור חבילות שהותקנו ב-‎/system/app."</string>
<string name="factorytest_no_action" msgid="339252838115675515">"‏לא נמצאה חבילה המספקת את הפעולה FACTORY_TEST."</string>
- <string name="factorytest_reboot" msgid="2050147445567257365">"אתחל מחדש"</string>
+ <string name="factorytest_reboot" msgid="2050147445567257365">"הפעלה מחדש"</string>
<string name="js_dialog_title" msgid="7464775045615023241">"בדף שבכתובת \'<xliff:g id="TITLE">%s</xliff:g>\' כתוב:"</string>
<string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="7012587995876771246">"אישור ניווט"</string>
- <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"צא מדף זה"</string>
+ <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"יציאה מהדף"</string>
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"להישאר בדף הזה"</string>
<string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nבטוח שברצונך לנווט אל מחוץ לדף הזה?"</string>
<string name="save_password_label" msgid="9161712335355510035">"אישור"</string>
- <string name="double_tap_toast" msgid="7065519579174882778">"טיפ: הקש פעמיים כדי להגדיל ולהקטין."</string>
+ <string name="double_tap_toast" msgid="7065519579174882778">"טיפ: אפשר להקיש פעמיים כדי להגדיל או להקטין את התצוגה."</string>
<string name="autofill_this_form" msgid="3187132440451621492">"מילוי אוטומטי"</string>
- <string name="setup_autofill" msgid="5431369130866618567">"הגדר מילוי אוטומטי"</string>
+ <string name="setup_autofill" msgid="5431369130866618567">"הגדרת מילוי אוטומטי"</string>
<string name="autofill_window_title" msgid="4379134104008111961">"מילוי אוטומטי באמצעות <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
<string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
<string name="autofill_address_summary_name_format" msgid="3402882515222673691">"$1$2$3"</string>
@@ -1019,32 +1019,29 @@
<string name="autofill_area" msgid="8289022370678448983">"אזור"</string>
<string name="autofill_emirate" msgid="2544082046790551168">"אמירות"</string>
<string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"קריאת סימניות והיסטוריית האינטרנט שלך"</string>
- <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"‏מאפשר לאפליקציה לקרוא את ההיסטוריה של כל כתובות האתרים שבהן הדפדפן ביקר, ואת כל ה-Bookmarks של הדפדפן. שים לב: דפדפני צד שלישי או אפליקציות אחרות עם יכולות לדפדוף באינטרנט אינם יכולים לאכוף אישור זה."</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"‏מאפשרת לאפליקציה לקרוא את ההיסטוריה של כל כתובות ה-URL שאליהן נכנסת באמצעות הדפדפן, ואת כל הסימניות בדפדפן. הערה: אפליקציות אחרות או דפדפני צד שלישי עם יכולות גלישה באינטרנט לא יכולים לאכוף את האישור הזה."</string>
<string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"כתיבת סימניות והיסטורייה של אתרים"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"‏מאפשר לאפליקציה לשנות את ההיסטוריה או ה-Bookmarks של הדפדפן המאוחסנים בטאבלט. הדבר עשוי לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. שים לב: אישור זה אינו ניתן לאכיפה על ידי דפדפני צד שלישי או אפליקציות אחרות בעלות יכולות גלישה באינטרנט."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"מאפשרת לאפליקציה לשנות את ההיסטוריה או את הסימניות של הדפדפן אשר מאוחסנות בטאבלט. ההרשאה עשויה לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. הערה: ההרשאה הזו לא ניתנת לאכיפה על ידי דפדפני צד שלישי או אפליקציות אחרות בעלות יכולות גלישה באינטרנט."</string>
<string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"‏מאפשרת לאפליקציה לשנות את הסימניות או את היסטוריית הדפדפן השמורות במכשיר ה-Android TV. הרשאה זו עשויה לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. הערה: ייתכן שההרשאה לא תיושם על ידי דפדפנים של צד שלישי או על ידי אפליקציות אחרות עם יכולות גלישה באינטרנט."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"‏מאפשר לאפליקציה לשנות את ההיסטוריה או ה-Bookmarks של הדפדפן המאוחסנים בטלפון. הדבר עשוי לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. שים לב: אישור זה אינו ניתן לאכיפה על ידי דפדפני צד שלישי או אפליקציות אחרות בעלות יכולות גלישה באינטרנט."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"מאפשרת לאפליקציה לשנות את ההיסטוריה או את הסימניות של הדפדפן אשר מאוחסנות בטלפון. ההרשאה הזו עשויה לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. הערה: אפליקציות אחרות או דפדפני צד שלישי עם יכולות גלישה באינטרנט לא יכולים לאכוף את האישור הזה."</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"הגדרת התראה"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"מאפשרת לאפליקציה להגדיר התראה באפליקציה מותקנת של שעון מעורר. אפליקציות מסוימות של שעון מעורר אינן מיישמות את התכונה הזו."</string>
<string name="permlab_addVoicemail" msgid="4770245808840814471">"הוספה של דואר קולי"</string>
<string name="permdesc_addVoicemail" msgid="5470312139820074324">"מאפשרת לאפליקציה להוסיף הודעות לתיבת הדואר הקולי."</string>
<string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"שינוי הרשאות המיקום הגיאוגרפי של הדפדפן"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"מאפשר לאפליקציה לשנות את הרשאות המיקום הגיאוגרפי של הדפדפן. אפליקציות זדוניות עלולות להשתמש בכך כדי לאפשר משלוח של פרטי מיקום לאתרים זדוניים אחרים."</string>
- <string name="save_password_message" msgid="2146409467245462965">"האם ברצונך שהדפדפן יזכור סיסמה זו?"</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"מאפשרת לאפליקציה לשנות את הרשאות המיקום הגיאוגרפי של הדפדפן. אפליקציות זדוניות עלולות להשתמש בכך כדי לאפשר שליחה של פרטי מיקום לאתרים זדוניים אחרים."</string>
+ <string name="save_password_message" msgid="2146409467245462965">"רוצה שהדפדפן יזכור את הסיסמה?"</string>
<string name="save_password_notnow" msgid="2878327088951240061">"לא עכשיו"</string>
<string name="save_password_remember" msgid="6490888932657708341">"כן, לשמור"</string>
<string name="save_password_never" msgid="6776808375903410659">"אף פעם"</string>
- <string name="open_permission_deny" msgid="5136793905306987251">"אין לך הרשאה לפתוח דף זה."</string>
+ <string name="open_permission_deny" msgid="5136793905306987251">"אין לך הרשאה לפתוח את הדף הזה."</string>
<string name="text_copied" msgid="2531420577879738860">"הטקסט הועתק ללוח."</string>
<string name="copied" msgid="4675902854553014676">"ההעתקה בוצעה"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"האפליקציה <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> הודבקה מ-<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"האפליקציה <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> הודבקה מהלוח"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"טקסט שהעתקת הודבק על ידי <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"תמונה שהעתקת הודבקה על ידי <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="pasted_content" msgid="646276353060777131">"התוכן שהעתקת הודבק על ידי <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
<string name="more_item_label" msgid="7419249600215749115">"עוד"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"תפריט+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1065,8 +1062,8 @@
<string name="searchview_description_voice" msgid="42360159504884679">"חיפוש קולי"</string>
<string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"האם להפעיל את התכונה \'גילוי באמצעות מגע\'?"</string>
<string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> רוצה להפעיל את התכונה \'גילוי באמצעות מגע\'. כאשר התכונה הזו מופעלת, אפשר לשמוע או לראות תיאורים של הפריטים שעליהם הנחת את האצבע או לקיים אינטראקציה עם הטאבלט באמצעות תנועות."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> רוצה להפעיל את התכונה \'חקור על ידי מגע\'. כאשר התכונה \'חקור על ידי מגע\' מופעלת, אתה יכול לשמוע או לראות תיאורים של הפריטים שעליהם אצבעך מונחת או לקיים אינטראקציה עם הטלפון באמצעות תנועות אצבע."</string>
- <string name="oneMonthDurationPast" msgid="4538030857114635777">"לפני חודש אחד"</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"השירות <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> רוצה להפעיל את התכונה \'גילוי באמצעות מגע\'. כשהתכונה \'גילוי באמצעות מגע\' מופעלת, אפשר לשמוע או לראות תיאורים של הפריטים שעליהם האצבע מונחת או לקיים אינטראקציה עם הטלפון באמצעות תנועות אצבע."</string>
+ <string name="oneMonthDurationPast" msgid="4538030857114635777">"לפני חודש"</string>
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"לפני חודש אחד"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
<item quantity="two"><xliff:g id="COUNT_1">%d</xliff:g> הימים האחרונים</item>
@@ -1102,7 +1099,7 @@
<item quantity="two"><xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
<item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
- <item quantity="one">שעה <xliff:g id="COUNT_0">%d</xliff:g></item>
+ <item quantity="one">שעה (<xliff:g id="COUNT_0">%d</xliff:g>)‏</item>
</plurals>
<plurals name="duration_days_shortest" formatted="false" msgid="3686058472983158496">
<item quantity="two"><xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
@@ -1180,7 +1177,7 @@
<item quantity="two">בעוד <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
<item quantity="many">בעוד <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
<item quantity="other">בעוד <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
- <item quantity="one">בעוד <xliff:g id="COUNT_0">%d</xliff:g> יום</item>
+ <item quantity="one">בעוד יום אחד (<xliff:g id="COUNT_0">%d</xliff:g>)</item>
</plurals>
<plurals name="duration_years_relative_future" formatted="false" msgid="3985129025134896371">
<item quantity="two">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
@@ -1188,7 +1185,7 @@
<item quantity="other">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
<item quantity="one">בעוד שנה <xliff:g id="COUNT_0">%d</xliff:g></item>
</plurals>
- <string name="VideoView_error_title" msgid="5750686717225068016">"בעיה בווידאו"</string>
+ <string name="VideoView_error_title" msgid="5750686717225068016">"בעיה בסרטון"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"לא ניתן להעביר את הסרטון הזה בסטרימינג למכשיר."</string>
<string name="VideoView_error_text_unknown" msgid="7658683339707607138">"לא ניתן להפעיל את הסרטון הזה."</string>
<string name="VideoView_error_button" msgid="5138809446603764272">"אישור"</string>
@@ -1202,18 +1199,18 @@
<string name="selectAll" msgid="1532369154488982046">"בחירת הכול"</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="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="replace" msgid="7842675434546657444">"החלפה..."</string>
<string name="delete" msgid="1514113991712129054">"מחיקה"</string>
<string name="copyUrl" msgid="6229645005987260230">"‏העתקת כתובת URL"</string>
- <string name="selectTextMode" msgid="3225108910999318778">"בחר טקסט"</string>
+ <string name="selectTextMode" msgid="3225108910999318778">"בחירת טקסט"</string>
<string name="undo" msgid="3175318090002654673">"ביטול"</string>
- <string name="redo" msgid="7231448494008532233">"בצע מחדש"</string>
+ <string name="redo" msgid="7231448494008532233">"ביצוע מחדש"</string>
<string name="autofill" msgid="511224882647795296">"מילוי אוטומטי"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"בחירת טקסט"</string>
- <string name="addToDictionary" msgid="8041821113480950096">"הוסף למילון"</string>
+ <string name="addToDictionary" msgid="8041821113480950096">"הוספה למילון"</string>
<string name="deleteText" msgid="4200807474529938112">"מחיקה"</string>
<string name="inputMethod" msgid="1784759500516314751">"שיטת קלט"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"פעולות טקסט"</string>
@@ -1221,7 +1218,7 @@
<string name="low_internal_storage_view_text" msgid="8172166728369697835">"ייתכן שפונקציות מערכת מסוימות לא יפעלו"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"‏אין מספיק מקום אחסון עבור המערכת. עליך לוודא שיש לך מקום פנוי בנפח של 250MB ולהתחיל שוב."</string>
<string name="app_running_notification_title" msgid="8985999749231486569">"אפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g> פועלת"</string>
- <string name="app_running_notification_text" msgid="5120815883400228566">"הקש לקבלת מידע נוסף או כדי לעצור את האפליקציה."</string>
+ <string name="app_running_notification_text" msgid="5120815883400228566">"יש להקיש לקבלת מידע נוסף או כדי לעצור את האפליקציה."</string>
<string name="ok" msgid="2646370155170753815">"אישור"</string>
<string name="cancel" msgid="6908697720451760115">"ביטול"</string>
<string name="yes" msgid="9069828999585032361">"אישור"</string>
@@ -1234,11 +1231,11 @@
<string name="not_checked" msgid="7972320087569023342">"לא מסומן"</string>
<string name="selected" msgid="6614607926197755875">"נבחר"</string>
<string name="not_selected" msgid="410652016565864475">"לא נבחר"</string>
- <string name="whichApplication" msgid="5432266899591255759">"השלמת פעולה באמצעות"</string>
- <string name="whichApplicationNamed" msgid="6969946041713975681">"‏להשלמת הפעולה באמצעות %1$s"</string>
- <string name="whichApplicationLabel" msgid="7852182961472531728">"השלם פעולה"</string>
+ <string name="whichApplication" msgid="5432266899591255759">"השלמת הפעולה באמצעות"</string>
+ <string name="whichApplicationNamed" msgid="6969946041713975681">"‏השלמת הפעולה באמצעות %1$s"</string>
+ <string name="whichApplicationLabel" msgid="7852182961472531728">"להשלמת הפעולה"</string>
<string name="whichViewApplication" msgid="5733194231473132945">"פתיחה באמצעות"</string>
- <string name="whichViewApplicationNamed" msgid="415164730629690105">"‏פתח באמצעות %1$s"</string>
+ <string name="whichViewApplicationNamed" msgid="415164730629690105">"‏פתיחה באמצעות %1$s"</string>
<string name="whichViewApplicationLabel" msgid="7367556735684742409">"פתיחה"</string>
<string name="whichOpenHostLinksWith" msgid="7645631470199397485">"פתיחת קישורים של <xliff:g id="HOST">%1$s</xliff:g> באמצעות"</string>
<string name="whichOpenLinksWith" msgid="1120936181362907258">"פתיחת קישורים באמצעות"</string>
@@ -1254,15 +1251,15 @@
<string name="whichSendToApplication" msgid="77101541959464018">"שליחה באמצעות"</string>
<string name="whichSendToApplicationNamed" msgid="3385686512014670003">"‏שליחה באמצעות %1$s"</string>
<string name="whichSendToApplicationLabel" msgid="3543240188816513303">"שליחה"</string>
- <string name="whichHomeApplication" msgid="8276350727038396616">"בחר אפליקציה שתשמש כדף הבית"</string>
+ <string name="whichHomeApplication" msgid="8276350727038396616">"בחירת אפליקציה שתשמש כדף הבית"</string>
<string name="whichHomeApplicationNamed" msgid="5855990024847433794">"‏השתמש ב-%1$s כדף הבית"</string>
<string name="whichHomeApplicationLabel" msgid="8907334282202933959">"צילום תמונה"</string>
<string name="whichImageCaptureApplication" msgid="2737413019463215284">"צלם תמונה באמצעות"</string>
<string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"‏צילום תמונה באמצעות %1$s"</string>
- <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"צלם תמונה"</string>
+ <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">"‏נקה את הגדרת המחדל ב\'הגדרות מערכת\' &lt;‏ Google Apps‏ &lt; \'הורדות\'."</string>
+ <string name="use_a_different_app" msgid="4987790276170972776">"שימוש באפליקציה אחרת"</string>
+ <string name="clearDefaultHintMsg" msgid="1325866337702524936">"‏צריך לנקות את הגדרת המחדל ב\'הגדרות מערכת\' &lt;‏ \'אפליקציות של Google‏\' &lt; \'הורדות\'."</string>
<string name="chooseActivity" msgid="8563390197659779956">"בחירת פעולה"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"‏בחירת אפליקציה עבור התקן ה-USB"</string>
<string name="noApplications" msgid="1186909265235544019">"אין אפליקציות שיכולות לבצע את הפעולה הזו."</string>
@@ -1273,30 +1270,30 @@
<string name="aerr_restart" msgid="2789618625210505419">"פתיחת האפליקציה מחדש"</string>
<string name="aerr_report" msgid="3095644466849299308">"שליחת משוב"</string>
<string name="aerr_close" msgid="3398336821267021852">"סגירה"</string>
- <string name="aerr_mute" msgid="2304972923480211376">"השתק עד הפעלה מחדש של המכשיר"</string>
+ <string name="aerr_mute" msgid="2304972923480211376">"השתקה עד להפעלה מחדש של המכשיר"</string>
<string name="aerr_wait" msgid="3198677780474548217">"להמתין"</string>
- <string name="aerr_close_app" msgid="8318883106083050970">"סגור את האפליקציה"</string>
+ <string name="aerr_close_app" msgid="8318883106083050970">"סגירת האפליקציה"</string>
<string name="anr_title" msgid="7290329487067300120"></string>
<string name="anr_activity_application" msgid="8121716632960340680">"האפליקציה <xliff:g id="APPLICATION">%2$s</xliff:g> לא מגיבה"</string>
<string name="anr_activity_process" msgid="3477362583767128667">"האפליקציה <xliff:g id="ACTIVITY">%1$s</xliff:g> אינה מגיבה"</string>
- <string name="anr_application_process" msgid="4978772139461676184">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> אינה מגיבה"</string>
+ <string name="anr_application_process" msgid="4978772139461676184">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> לא מגיבה"</string>
<string name="anr_process" msgid="1664277165911816067">"התהליך <xliff:g id="PROCESS">%1$s</xliff:g> אינו מגיב."</string>
<string name="force_close" msgid="9035203496368973803">"אישור"</string>
- <string name="report" msgid="2149194372340349521">"שלח דוח"</string>
- <string name="wait" msgid="7765985809494033348">"המתן"</string>
- <string name="webpage_unresponsive" msgid="7850879412195273433">"הדף אינו מגיב.\n\nהאם אתה רוצה לסגור אותו?"</string>
+ <string name="report" msgid="2149194372340349521">"שליחת דוח"</string>
+ <string name="wait" msgid="7765985809494033348">"להמתין"</string>
+ <string name="webpage_unresponsive" msgid="7850879412195273433">"הדף לא מגיב.\n\nלסגור אותו?"</string>
<string name="launch_warning_title" msgid="6725456009564953595">"הפנייה מחדש של אפליקציה"</string>
<string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> פועל כעת."</string>
<string name="launch_warning_original" msgid="3332206576800169626">"אפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g> הופעלה במקור."</string>
<string name="screen_compat_mode_scale" msgid="8627359598437527726">"שינוי קנה-מידה"</string>
<string name="screen_compat_mode_show" msgid="5080361367584709857">"להציג תמיד"</string>
<string name="screen_compat_mode_hint" msgid="4032272159093750908">"‏אפשר להפעיל מחדש את התכונה הזו ב\'הגדרות מערכת\' &lt;‏ Google Apps‏ &lt; \'הורדות\'."</string>
- <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> אינו תומך בהגדרת הגודל הנוכחית של התצוגה, והתנהגותו עשויה להיות בלתי צפויה."</string>
- <string name="unsupported_display_size_show" msgid="980129850974919375">"הצג תמיד"</string>
+ <string name="unsupported_display_size_message" msgid="7265211375269394699">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא תומכת בהגדרת הגודל הנוכחית של התצוגה, והיא עשויה לא לפעול כראוי."</string>
+ <string name="unsupported_display_size_show" msgid="980129850974919375">"להציג תמיד"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"‏<xliff:g id="APP_NAME">%1$s</xliff:g> נבנתה לגרסה לא תואמת של מערכת ההפעלה של Android ועלולה להתנהג באופן לא צפוי. ייתכן שקיימת גרסה מעודכנת של האפליקציה."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"להציג תמיד"</string>
<string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"האם יש עדכון חדש?"</string>
- <string name="smv_application" msgid="3775183542777792638">"‏האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> (תהליך <xliff:g id="PROCESS">%2$s</xliff:g>) הפר את מדיניות StrictMode באכיפה עצמית שלו."</string>
+ <string name="smv_application" msgid="3775183542777792638">"‏האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> (תהליך <xliff:g id="PROCESS">%2$s</xliff:g>) הפרה את מדיניות StrictMode באכיפה עצמית שלה."</string>
<string name="smv_process" msgid="1398801497130695446">"‏התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הפר את מדיניות StrictMode באכיפה עצמית."</string>
<string name="android_upgrading_title" product="default" msgid="7279077384220829683">"הטלפון מתעדכן…"</string>
<string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"הטאבלט מתעדכן…"</string>
@@ -1307,12 +1304,12 @@
<string name="android_start_title" product="device" msgid="6967413819673299309">"הפעלת המכשיר מתחילה…"</string>
<string name="android_upgrading_fstrim" msgid="3259087575528515329">"מתבצעת אופטימיזציה של האחסון."</string>
<string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"עדכון המערכת לקראת סיום…"</string>
- <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> מבצעת שדרוג…"</string>
+ <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> בתהליך שדרוג…"</string>
<string name="android_upgrading_apk" msgid="1339564803894466737">"מתבצעת אופטימיזציה של אפליקציה <xliff:g id="NUMBER_0">%1$d</xliff:g> מתוך <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_preparing_apk" msgid="589736917792300956">"המערכת מכינה את <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
- <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"מפעיל אפליקציות."</string>
+ <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"מתבצעת הפעלה של אפליקציות."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"תהליך האתחול בשלבי סיום."</string>
- <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> פועל"</string>
+ <string name="heavy_weight_notification" msgid="8382784283600329576">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> פועלת"</string>
<string name="heavy_weight_notification_detail" msgid="6802247239468404078">"יש להקיש כדי לחזור למשחק"</string>
<string name="heavy_weight_switcher_title" msgid="3861984210040100886">"בחירת משחק"</string>
<string name="heavy_weight_switcher_text" msgid="6814316627367160126">"לקבלת ביצועים טובים יותר, רק אחד מבין המשחקים האלה יכול להיות פתוח בכל פעם."</string>
@@ -1320,12 +1317,12 @@
<string name="new_app_action" msgid="547772182913269801">"פתיחת <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
<string name="new_app_description" msgid="1958903080400806644">"אפליקציית <xliff:g id="OLD_APP">%1$s</xliff:g> תיסגר ללא שמירה"</string>
<string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> חורג ממגבלת הזיכרון"</string>
- <string name="dump_heap_ready_notification" msgid="2302452262927390268">"‏Dump של ערימה בשביל <xliff:g id="PROC">%1$s</xliff:g> מוכן"</string>
+ <string name="dump_heap_ready_notification" msgid="2302452262927390268">"תמונת מצב של הזיכרון מוכנה עבור <xliff:g id="PROC">%1$s</xliff:g>"</string>
<string name="dump_heap_notification_detail" msgid="8431586843001054050">"‏Dump של ערימה נאסף. יש להקיש כדי לשתף."</string>
- <string name="dump_heap_title" msgid="4367128917229233901">"‏האם לשתף את נתוני ה-Dump של הערימה?"</string>
+ <string name="dump_heap_title" msgid="4367128917229233901">"לשתף את תמונת המצב של הזיכרון?"</string>
<string name="dump_heap_text" msgid="1692649033835719336">"התהליך <xliff:g id="PROC">%1$s</xliff:g> חרג ממגבלת הזיכרון בגודל <xliff:g id="SIZE">%2$s</xliff:g>‏. תמונת מצב של הזיכרון זמינה לשיתוף עם המפתח. חשוב לנקוט זהירות: תמונת המצב של הזיכרון עשויה לכלול מידע אישי שאליו יש לאפליקציה גישה."</string>
<string name="dump_heap_system_text" msgid="6805155514925350849">"‏התהליך <xliff:g id="PROC">%1$s</xliff:g> חרג ממגבלת הזיכרון בגודל <xliff:g id="SIZE">%2$s</xliff:g>. יש Dump של ערימה זמין לשיתוף. חשוב לנקוט זהירות: ה-Dump של הערימה עשוי לכלול מידע אישי רגיש שאליו יש לתהליך גישה. ייתכן שמידע זה כולל נתונים שהקלדת."</string>
- <string name="dump_heap_ready_text" msgid="5849618132123045516">"‏Dump של ערימה עבור התהליך <xliff:g id="PROC">%1$s</xliff:g> זמין לשיתוף. חשוב לנקוט זהירות: ה-Dump של הערימה עשוי לכלול מידע אישי רגיש שאליו יש לתהליך גישה. ייתכן שמידע זה כולל נתונים שהקלדת."</string>
+ <string name="dump_heap_ready_text" msgid="5849618132123045516">"תמונת מצב של הזיכרון עבור התהליך <xliff:g id="PROC">%1$s</xliff:g> זמינה לשיתוף. זהירות: תמונת המצב של הזיכרון עשויה לכלול מידע אישי רגיש שאליו יש לתהליך גישה. ייתכן שהמידע הזה כולל נתונים שהקלדת."</string>
<string name="sendText" msgid="493003724401350724">"בחירת פעולה לביצוע עם טקסט"</string>
<string name="volume_ringtone" msgid="134784084629229029">"עוצמת קול של צלצול"</string>
<string name="volume_music" msgid="7727274216734955095">"עוצמת קול של מדיה"</string>
@@ -1371,29 +1368,29 @@
</string-array>
<string name="network_switch_type_name_unknown" msgid="3665696841646851068">"סוג רשת לא מזוהה"</string>
<string name="accept" msgid="5447154347815825107">"אישור"</string>
- <string name="decline" msgid="6490507610282145874">"דחה"</string>
- <string name="select_character" msgid="3352797107930786979">"הוסף תו"</string>
+ <string name="decline" msgid="6490507610282145874">"דחייה"</string>
+ <string name="select_character" msgid="3352797107930786979">"הוספת תו"</string>
<string name="sms_control_title" msgid="4748684259903148341">"‏מתבצעת שליחה של הודעות SMS"</string>
<string name="sms_control_message" msgid="6574313876316388239">"‏האפליקציה &lt;b&gt; <xliff:g id="APP_NAME">%1$s</xliff:g> &lt;/ b&gt; שולחת מספר רב של הודעות SMS. האם לאפשר לאפליקציה הזו להמשיך לשלוח הודעות?"</string>
<string name="sms_control_yes" msgid="4858845109269524622">"כן, זה בסדר"</string>
<string name="sms_control_no" msgid="4845717880040355570">"עדיף שלא"</string>
<string name="sms_short_code_confirm_message" msgid="1385416688897538724">"‏אפליקציית &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; רוצה לשלוח הודעה אל &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
<string name="sms_short_code_details" msgid="2723725738333388351">"הדבר "<b>"עלול לגרום לחיובים"</b>" בחשבון המכשיר הנייד שלך."</string>
- <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"הדבר יגרום לחיובים בחשבון המכשיר הנייד שלך."</b></string>
+ <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"הפעולה הזו תגרום לחיובים בחשבון המכשיר הנייד שלך."</b></string>
<string name="sms_short_code_confirm_allow" msgid="920477594325526691">"שלח"</string>
<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_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_never_allow" msgid="2688828813521652079">"לעולם אל תאפשר"</string>
+ <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"לא לאפשר אף פעם"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"‏כרטיס ה-SIM הוסר"</string>
<string name="sim_removed_message" msgid="9051174064474904617">"‏הרשת הסלולרית לא תהיה זמינה עד שתבוצע הפעלה מחדש לאחר הכנסת כרטיס SIM חוקי."</string>
<string name="sim_done_button" msgid="6464250841528410598">"סיום"</string>
<string name="sim_added_title" msgid="7930779986759414595">"‏כרטיס ה-SIM נוסף"</string>
- <string name="sim_added_message" msgid="6602906609509958680">"הפעל מחדש את המכשיר כדי לגשת אל הרשת הסלולרית."</string>
+ <string name="sim_added_message" msgid="6602906609509958680">"צריך להפעיל מחדש את המכשיר כדי לקבל גישה אל הרשת הסלולרית."</string>
<string name="sim_restart_button" msgid="8481803851341190038">"הפעלה מחדש"</string>
<string name="install_carrier_app_notification_title" msgid="5712723402213090102">"הפעלה של השירות הסלולרי"</string>
- <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"‏הורדה של אפליקציית הספק כדי להפעיל את כרטיס ה-SIM החדש"</string>
+ <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"‏צריך להוריד את אפליקציית הספק כדי להפעיל את כרטיס ה-SIM החדש"</string>
<string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"‏ניתן להוריד את האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> כדי להפעיל את כרטיס ה-SIM החדש"</string>
<string name="install_carrier_app_notification_button" msgid="6257740533102594290">"להורדת האפליקציה"</string>
<string name="carrier_app_notification_title" msgid="5815477368072060250">"‏ה-SIM החדש הוכנס"</string>
@@ -1405,22 +1402,22 @@
<string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"חדש: "</font></string>
<string name="perms_description_app" msgid="2747752389870161996">"מאת <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="no_permissions" msgid="5729199278862516390">"לא נדרשות הרשאות"</string>
- <string name="perm_costs_money" msgid="749054595022779685">"פעולה זו עשויה לחייב אותך בכסף:"</string>
+ <string name="perm_costs_money" msgid="749054595022779685">"הפעולה הזו עשויה לגרום לחיוב כספי"</string>
<string name="dlg_ok" msgid="5103447663504839312">"אישור"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"‏טעינת המכשיר הזה באמצעות USB"</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"‏המכשיר בטעינה דרך USB"</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"‏טעינת המכשיר המחובר באמצעות USB"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"‏האפשרות להעברת קבצים ב-USB מופעלת"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"‏PTP באמצעות USB מופעל"</string>
<string name="usb_tether_notification_title" msgid="8828527870612663771">"‏שיתוף אינטרנט בין מכשירים באמצעות USB מופעל"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"‏MIDI באמצעות USB מופעל"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"‏אביזר USB מחובר"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"הקש לקבלת אפשרויות נוספות."</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"יש להקיש להצגת אפשרויות נוספות."</string>
<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="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ההתקן שחיברת לא תואם לטלפון הזה. יש להקיש לקבלת מידע נוסף."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"‏ניפוי באגים של USB מחובר"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"‏יש להקיש כדי לכבות את ניפוי הבאגים ב-USB"</string>
- <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"‏בחר להשבית ניפוי באגים ב-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>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"יש לבחור כדי להשבית ניפוי באגים אלחוטי."</string>
@@ -1436,19 +1433,19 @@
<string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"האם לשתף דוח על באג?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"שיתוף דוח על באג…"</string>
<string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"מנהל המערכת ביקש דוח על באג כדי לסייע בפתרון בעיות במכשיר הזה. ייתכן שאפליקציות ונתונים ישותפו."</string>
- <string name="share_remote_bugreport_action" msgid="7630880678785123682">"שתף"</string>
+ <string name="share_remote_bugreport_action" msgid="7630880678785123682">"שיתוף"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"עדיף שלא"</string>
<string name="select_input_method" msgid="3971267998568587025">"בחר שיטת הזנה"</string>
<string name="show_ime" msgid="6406112007347443383">"להשאיר במסך בזמן שהמקלדת הפיזית פעילה"</string>
<string name="hardware" msgid="1800597768237606953">"הצגת מקלדת וירטואלית"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"הגדרת מקלדת פיזית"</string>
- <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"הקש כדי לבחור שפה ופריסה"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"יש להקיש כדי לבחור שפה ופריסה"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"הצגה מעל אפליקציות אחרות"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"תצוגה של <xliff:g id="NAME">%s</xliff:g> מעל אפליקציות אחרות"</string>
<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_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_message" msgid="2231566971425375542">"מתבצעת בדיקה של התוכן הנוכחי"</string>
@@ -1462,8 +1459,8 @@
<string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"עיון בקובצי המדיה"</string>
<string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"בעיה עם <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"המדיה <xliff:g id="NAME">%s</xliff:g> לא פועלת"</string>
- <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"יש להקיש כדי לתקן את הבעיה"</string>
- <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"<xliff:g id="NAME">%s</xliff:g> פגום. בחר כדי לטפל בבעיה."</string>
+ <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"יש להקיש כדי לפתור את הבעיה"</string>
+ <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"<xliff:g id="NAME">%s</xliff:g> פגום. יש ללחוץ כדי לפתור את הבעיה."</string>
<string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"ייתכן שיהיה צורך לפרמט מחדש את המכשיר. יש להקיש כדי להוציא את המדיה."</string>
<string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> לא נתמך"</string>
<string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"המדיה <xliff:g id="NAME">%s</xliff:g> לא פועלת"</string>
@@ -1482,7 +1479,7 @@
<string name="ext_media_seamless_action" msgid="8837030226009268080">"החלפת פלט"</string>
<string name="ext_media_missing_title" msgid="3209472091220515046">"חסר: <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_missing_message" msgid="4408988706227922909">"יש להכניס שוב את ההתקן"</string>
- <string name="ext_media_move_specific_title" msgid="8492118544775964250">"מעביר את <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_move_specific_title" msgid="8492118544775964250">"מתבצעת העברה של <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_move_title" msgid="2682741525619033637">"מתבצעת העברה של נתונים"</string>
<string name="ext_media_move_success_title" msgid="4901763082647316767">"העברת התוכן הסתיימה"</string>
<string name="ext_media_move_success_message" msgid="9159542002276982979">"התוכן הועבר אל <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1490,27 +1487,27 @@
<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>
<string name="ext_media_status_unmountable" msgid="7043574843541087748">"פגום"</string>
<string name="ext_media_status_unsupported" msgid="5460509911660539317">"לא נתמך"</string>
<string name="ext_media_status_ejecting" msgid="7532403368044013797">"מתבצעת הוצאה…"</string>
- <string name="ext_media_status_formatting" msgid="774148701503179906">"מפרמט…"</string>
+ <string name="ext_media_status_formatting" msgid="774148701503179906">"מתבצע פרמוט…"</string>
<string name="ext_media_status_missing" msgid="6520746443048867314">"לא הוכנס"</string>
<string name="activity_list_empty" msgid="4219430010716034252">"לא נמצאו פעילויות תואמות."</string>
<string name="permlab_route_media_output" msgid="8048124531439513118">"ניתוב פלט מדיה"</string>
- <string name="permdesc_route_media_output" msgid="1759683269387729675">"מאפשר לאפליקציה לנתב פלט מדיה למכשירים חיצוניים אחרים."</string>
- <string name="permlab_readInstallSessions" msgid="7279049337895583621">"קריאת פעילות התקנה"</string>
+ <string name="permdesc_route_media_output" msgid="1759683269387729675">"מאפשרת לאפליקציה לנתב פלט מדיה למכשירים חיצוניים אחרים."</string>
+ <string name="permlab_readInstallSessions" msgid="7279049337895583621">"קריאת סשנים של התקנה"</string>
<string name="permdesc_readInstallSessions" msgid="4012608316610763473">"מאפשרת לאפליקציה לקרוא פעילויות התקנה. ההרשאה הזו מאפשרת לה לראות פרטים על התקנות פעילות של חבילות."</string>
<string name="permlab_requestInstallPackages" msgid="7600020863445351154">"בקשה להתקנת חבילות"</string>
- <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"מתיר לאפליקציה לבקש התקנה של חבילות."</string>
+ <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"מאפשרת לאפליקציה לבקש התקנה של חבילות."</string>
<string name="permlab_requestDeletePackages" msgid="2541172829260106795">"בקשה למחוק חבילות"</string>
- <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"מתיר לאפליקציה לבקש מחיקה של חבילות."</string>
+ <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"מאפשרת לאפליקציה לבקש מחיקה של חבילות."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"בקשה להתעלם מאופטימיזציות של הסוללה"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"מאפשרת לאפליקציה לבקש רשות להתעלם מאופטימיזציות של הסוללה לאפליקציה הזו."</string>
- <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"הקש פעמיים לבקרת מרחק מתצוגה"</string>
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"יש להקיש פעמיים לשינוי המרחק מהתצוגה"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"‏לא ניתן להוסיף widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"התחלה"</string>
<string name="ime_action_search" msgid="4501435960587287668">"חיפוש"</string>
@@ -1518,7 +1515,7 @@
<string name="ime_action_next" msgid="4169702997635728543">"הבא"</string>
<string name="ime_action_done" msgid="6299921014822891569">"סיום"</string>
<string name="ime_action_previous" msgid="6548799326860401611">"הקודם"</string>
- <string name="ime_action_default" msgid="8265027027659800121">"בצע"</string>
+ <string name="ime_action_default" msgid="8265027027659800121">"ביצוע"</string>
<string name="dial_number_using" msgid="6060769078933953531">"חיוג למספר\nבאמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="create_contact_using" msgid="6200708808003692594">"צור איש קשר\nבאמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"האפליקציות הבאות מבקשות אישור לגשת לחשבון שלך, עכשיו ובעתיד."</string>
@@ -1528,8 +1525,8 @@
<string name="deny" msgid="6632259981847676572">"עדיף שלא"</string>
<string name="permission_request_notification_title" msgid="1810025922441048273">"בקשת הרשאה"</string>
<string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"נדרשת הרשאה\nלחשבון <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
- <string name="forward_intent_to_owner" msgid="4620359037192871015">"אתה משתמש באפליקציה זו מחוץ לפרופיל העבודה שלך"</string>
- <string name="forward_intent_to_work" msgid="3620262405636021151">"אתה משתמש באפליקציה זו בפרופיל העבודה שלך"</string>
+ <string name="forward_intent_to_owner" msgid="4620359037192871015">"בחרת להשתמש באפליקציה הזאת מחוץ לפרופיל העבודה שלך"</string>
+ <string name="forward_intent_to_work" msgid="3620262405636021151">"נעשה שימוש באפליקציה הזו בפרופיל העבודה שלך"</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"שיטת קלט"</string>
<string name="sync_binding_label" msgid="469249309424662147">"סנכרון"</string>
<string name="accessibility_binding_label" msgid="1974602776545801715">"נגישות"</string>
@@ -1541,7 +1538,7 @@
<string name="notification_ranker_binding_label" msgid="432708245635563763">"שירות של דירוג התראות"</string>
<string name="vpn_title" msgid="5906991595291514182">"‏VPN מופעל"</string>
<string name="vpn_title_long" msgid="6834144390504619998">"‏VPN מופעל על ידי <xliff:g id="APP">%s</xliff:g>"</string>
- <string name="vpn_text" msgid="2275388920267251078">"הקש כדי לנהל את הרשת."</string>
+ <string name="vpn_text" msgid="2275388920267251078">"יש להקיש כדי לנהל את הרשת."</string>
<string name="vpn_text_long" msgid="278540576806169831">"בוצע חיבור אל <xliff:g id="SESSION">%s</xliff:g>. יש להקיש כדי לנהל את הרשת."</string>
<string name="vpn_lockdown_connecting" msgid="6096725311950342607">"‏ה-VPN שמופעל תמיד, מתחבר..."</string>
<string name="vpn_lockdown_connected" msgid="2853127976590658469">"‏ה-VPN שפועל תמיד, מחובר"</string>
@@ -1567,8 +1564,8 @@
</plurals>
<string name="action_mode_done" msgid="2536182504764803222">"סיום"</string>
<string name="progress_erasing" msgid="6891435992721028004">"בתהליך מחיקה של אחסון משותף…"</string>
- <string name="share" msgid="4157615043345227321">"שתף"</string>
- <string name="find" msgid="5015737188624767706">"מצא"</string>
+ <string name="share" msgid="4157615043345227321">"שיתוף"</string>
+ <string name="find" msgid="5015737188624767706">"חיפוש"</string>
<string name="websearch" msgid="5624340204512793290">"חיפוש באינטרנט"</string>
<string name="find_next" msgid="5341217051549648153">"מציאת ההתאמה הבאה"</string>
<string name="find_previous" msgid="4405898398141275532">"חיפוש של הקודם"</string>
@@ -1579,14 +1576,14 @@
<string name="gpsVerifNo" msgid="1671201856091564741">"לא"</string>
<string name="sync_too_many_deletes" msgid="6999440774578705300">"חרגת ממגבלת המחיקה"</string>
<string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"יש <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> פריטים שנמחקו עבור <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> , בחשבון <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. איזו פעולה ברצונך לבצע?"</string>
- <string name="sync_really_delete" msgid="5657871730315579051">"מחק את הפריטים"</string>
- <string name="sync_undo_deletes" msgid="5786033331266418896">"בטל את פעולות המחיקה"</string>
+ <string name="sync_really_delete" msgid="5657871730315579051">"מחיקת הפריטים"</string>
+ <string name="sync_undo_deletes" msgid="5786033331266418896">"ביטול פעולות המחיקה"</string>
<string name="sync_do_nothing" msgid="4528734662446469646">"לא לבצע שום פעולה כרגע"</string>
<string name="choose_account_label" msgid="5557833752759831548">"בחירת חשבון"</string>
<string name="add_account_label" msgid="4067610644298737417">"הוספת חשבון"</string>
<string name="add_account_button_label" msgid="322390749416414097">"הוספת חשבון"</string>
<string name="number_picker_increment_button" msgid="7621013714795186298">"הוסף"</string>
- <string name="number_picker_decrement_button" msgid="5116948444762708204">"הפחת"</string>
+ <string name="number_picker_decrement_button" msgid="5116948444762708204">"הפחתה"</string>
<string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> לחיצה ארוכה."</string>
<string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"צריך להסיט למעלה כדי להוסיף ולמטה כדי להפחית."</string>
<string name="time_picker_increment_minute_button" msgid="7195870222945784300">"הוספת דקה"</string>
@@ -1595,10 +1592,10 @@
<string name="time_picker_decrement_hour_button" msgid="584101766855054412">"הפחתת שעה"</string>
<string name="time_picker_increment_set_pm_button" msgid="5889149366900376419">"‏הגדרת PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"‏הגדרת AM"</string>
- <string name="date_picker_increment_month_button" msgid="3447263316096060309">"הוסף חודש"</string>
+ <string name="date_picker_increment_month_button" msgid="3447263316096060309">"הוספת חודש"</string>
<string name="date_picker_decrement_month_button" msgid="6531888937036883014">"הפחתת חודש"</string>
- <string name="date_picker_increment_day_button" msgid="4349336637188534259">"הוסף יום"</string>
- <string name="date_picker_decrement_day_button" msgid="6840253837656637248">"הפחת יום"</string>
+ <string name="date_picker_increment_day_button" msgid="4349336637188534259">"הוספת יום"</string>
+ <string name="date_picker_decrement_day_button" msgid="6840253837656637248">"הפחתת יום"</string>
<string name="date_picker_increment_year_button" msgid="7608128783435372594">"הוסף שנה"</string>
<string name="date_picker_decrement_year_button" msgid="4102586521754172684">"הפחת שנה"</string>
<string name="date_picker_prev_month_button" msgid="3418694374017868369">"החודש הקודם"</string>
@@ -1610,13 +1607,13 @@
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"שינוי מצב"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
- <string name="activitychooserview_choose_application" msgid="3500574466367891463">"בחר אפליקציה"</string>
+ <string name="activitychooserview_choose_application" msgid="3500574466367891463">"צריך לבחור אפליקציה"</string>
<string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"לא ניתן היה להפעיל את <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="shareactionprovider_share_with" msgid="2753089758467748982">"שיתוף עם"</string>
<string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"שיתוף עם <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="982510275422590757">"נקודת אחיזה להחלקה. לחיצה ארוכה."</string>
- <string name="description_target_unlock_tablet" msgid="7431571180065859551">"החלק לביטול נעילה."</string>
- <string name="action_bar_home_description" msgid="1501655419158631974">"נווט לדף הבית"</string>
+ <string name="description_target_unlock_tablet" msgid="7431571180065859551">"יש להחליק לביטול הנעילה."</string>
+ <string name="action_bar_home_description" msgid="1501655419158631974">"ניווט לדף הבית"</string>
<string name="action_bar_up_description" msgid="6611579697195026932">"ניווט למעלה"</string>
<string name="action_menu_overflow_description" msgid="4579536843510088170">"אפשרויות נוספות"</string>
<string name="action_bar_home_description_format" msgid="5087107531331621803">"‏%1$s‏, %2$s"</string>
@@ -1629,7 +1626,7 @@
<string name="storage_usb" msgid="2391213347883616886">"‏אחסון USB"</string>
<string name="extract_edit_menu_button" msgid="63954536535863040">"עריכה"</string>
<string name="data_usage_warning_title" msgid="9034893717078325845">"אזהרה לגבי שימוש בנתונים"</string>
- <string name="data_usage_warning_body" msgid="1669325367188029454">"השתמשת ב-<xliff:g id="APP">%s</xliff:g> נתונים"</string>
+ <string name="data_usage_warning_body" msgid="1669325367188029454">"השתמשת ב-<xliff:g id="APP">%s</xliff:g> של נתונים"</string>
<string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"הגעת למגבלה של חבילת הגלישה"</string>
<string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"‏הגעת למגבלת נתוני Wi-Fi"</string>
<string name="data_usage_limit_body" msgid="3567699582000085710">"הנתונים הושהו להמשך המחזור"</string>
@@ -1637,12 +1634,12 @@
<string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"‏חריגה ממגבלת נתוני ה-Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"חרגת ב-<xliff:g id="SIZE">%s</xliff:g> מעבר למגבלה המוגדרת"</string>
<string name="data_usage_restricted_title" msgid="126711424380051268">"נתוני הרקע מוגבלים"</string>
- <string name="data_usage_restricted_body" msgid="5338694433686077733">"הקש כדי להסיר את ההגבלה."</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="ssl_certificate" msgid="5690020361307261997">"אישור אבטחה"</string>
- <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"אישור זה תקף."</string>
+ <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"האישור הזה תקף."</string>
<string name="issued_to" msgid="5975877665505297662">"הוקצה ל:"</string>
<string name="common_name" msgid="1486334593631798443">"שם משותף:"</string>
<string name="org_name" msgid="7526331696464255245">"ארגון:"</string>
@@ -1655,12 +1652,12 @@
<string name="fingerprints" msgid="148690767172613723">"טביעות אצבע:"</string>
<string name="sha256_fingerprint" msgid="7103976380961964600">"‏טביעת אצבע SHA-256:"</string>
<string name="sha1_fingerprint" msgid="2339915142825390774">"‏טביעת אצבע SHA-1:"</string>
- <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"הצג הכל"</string>
+ <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"הצגת כל הפעילויות"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"בחירת פעילות"</string>
<string name="share_action_provider_share_with" msgid="1904096863622941880">"שיתוף עם"</string>
- <string name="sending" msgid="206925243621664438">"שולח…"</string>
+ <string name="sending" msgid="206925243621664438">"מתבצעת שליחה…"</string>
<string name="launchBrowserDefault" msgid="6328349989932924119">"להפעיל את הדפדפן?"</string>
- <string name="SetupCallDefault" msgid="5581740063237175247">"האם לקבל את השיחה?"</string>
+ <string name="SetupCallDefault" msgid="5581740063237175247">"לקבל את השיחה?"</string>
<string name="activity_resolver_use_always" msgid="5575222334666843269">"תמיד"</string>
<string name="activity_resolver_use_once" msgid="948462794469672658">"רק פעם אחת"</string>
<string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"‏%1$s אינו תומך בפרופיל עבודה"</string>
@@ -1680,7 +1677,7 @@
<string name="media_route_chooser_searching" msgid="6119673534251329535">"המערכת מחפשת מכשירים…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"הגדרות"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"ניתוק"</string>
- <string name="media_route_status_scanning" msgid="8045156315309594482">"סורק..."</string>
+ <string name="media_route_status_scanning" msgid="8045156315309594482">"מתבצעת סריקה..."</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"מתבצע חיבור..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"זמין"</string>
<string name="media_route_status_not_available" msgid="480912417977515261">"לא זמין"</string>
@@ -1700,39 +1697,39 @@
<item quantity="other">אפשר יהיה לנסות שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות.</item>
<item quantity="one">אפשר יהיה לנסות שוב בעוד שנייה אחת.</item>
</plurals>
- <string name="kg_pattern_instructions" msgid="8366024510502517748">"שרטט את קו ביטול הנעילה"</string>
- <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"‏הזן קוד גישה ל-SIM"</string>
- <string name="kg_pin_instructions" msgid="7355933174673539021">"הזן קוד גישה"</string>
- <string name="kg_password_instructions" msgid="7179782578809398050">"הזן את הסיסמה"</string>
+ <string name="kg_pattern_instructions" msgid="8366024510502517748">"צריך לשרטט את קו ביטול הנעילה"</string>
+ <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"‏יש להזין את קוד האימות של ה-SIM"</string>
+ <string name="kg_pin_instructions" msgid="7355933174673539021">"יש להזין קוד אימות"</string>
+ <string name="kg_password_instructions" msgid="7179782578809398050">"יש להזין את הסיסמה"</string>
<string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"‏כרטיס ה-SIM מושבת כעת. הזן קוד PUK כדי להמשיך. פנה אל הספק לפרטים."</string>
- <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"הזן את קוד הגישה הרצוי"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"אשר את קוד הגישה הרצוי"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"צריך להזין את קוד האימות הרצוי"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"יש לאשר את קוד האימות הרצוי"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"‏מתבצע ביטול נעילה של כרטיס SIM…"</string>
- <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"קוד גישה שגוי."</string>
- <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"הקלד קוד גישה שאורכו 4 עד 8 ספרות."</string>
+ <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"קוד אימות שגוי."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"יש להקליד קוד אימות שאורכו 4 עד 8 ספרות."</string>
<string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"‏קוד PUK צריך להיות בן 8 ספרות."</string>
<string name="kg_invalid_puk" msgid="4809502818518963344">"‏יש להזין שוב את קוד ה-PUK הנכון. ניסיונות חוזרים ישביתו את כרטיס ה-SIM באופן סופי."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"קודי הגישה אינם תואמים"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"קודי האימות לא תואמים"</string>
<string name="kg_login_too_many_attempts" msgid="699292728290654121">"ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string>
<string name="kg_login_instructions" msgid="3619844310339066827">"‏כדי לבטל את הנעילה, עליך להיכנס באמצעות חשבון Google שלך."</string>
<string name="kg_login_username_hint" msgid="1765453775467133251">"שם משתמש (אימייל)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"סיסמה"</string>
<string name="kg_login_submit_button" msgid="893611277617096870">"כניסה"</string>
<string name="kg_login_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_account_recovery_hint" msgid="4892466171043541248">"‏שכחת את שם המשתמש או הסיסמה?\nאפשר להיכנס לכתובת "<b>"google.com/accounts/recovery"</b></string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"מתבצעת בדיקה של החשבון…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"הקלדת קוד גישה שגוי <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_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>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"ביצעת <xliff:g id="NUMBER_0">%1$d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, הטאבלט יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"‏ניסית לבטל בצורה שגויה את הנעילה של מכשיר ה-Android TV‏ <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, מכשיר ה-Android TV יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"ביצעת <xliff:g id="NUMBER_0">%1$d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, הטלפון יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטאבלט. הטאבלט יעבור כעת איפוס לברירת המחדל של היצרן."</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"‏ניסית לבטל בצורה שגויה את הנעילה של מכשיר ה-Android TV <xliff:g id="NUMBER">%d</xliff:g> פעמים. מכשיר ה-Android TV יעבור כעת איפוס לברירת המחדל של היצרן."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. הטלפון יעבור כעת איפוס לברירת המחדל של היצרן."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. הטלפון יעבור עכשיו איפוס לברירת המחדל של היצרן."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"שרטטת את קו ביטול הנעילה באופן שגוי <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_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_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="safe_media_volume_warning" product="default" msgid="3751676824423049994">"האם להעלות את עוצמת הקול מעל לרמה המומלצת?\n\nהאזנה בעוצמת קול גבוהה למשכי זמן ממושכים עלולה לפגוע בשמיעה."</string>
@@ -1759,10 +1756,10 @@
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"יש להקיש על תכונה כדי להתחיל להשתמש בה:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"בחירת תכונה לשימוש עם לחצן הנגישות"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"בחירת תכונות לשימוש עם מקש הקיצור לעוצמת הקול"</string>
- <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> כובה"</string>
+ <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"שירות <xliff:g id="SERVICE_NAME">%s</xliff:g> כבוי"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"עריכת קיצורי הדרך"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"סיום"</string>
- <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"כבה את קיצור הדרך"</string>
+ <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"השבתת קיצור הדרך"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"שימוש בקיצור הדרך"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"היפוך צבעים"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"תיקון צבעים"</string>
@@ -1782,7 +1779,7 @@
<string name="user_logging_out_message" msgid="7216437629179710359">"מתבצע ניתוק של <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"בעלים"</string>
<string name="error_message_title" msgid="4082495589294631966">"שגיאה"</string>
- <string name="error_message_change_not_allowed" msgid="843159705042381454">"מנהל המערכת שלך אינו מתיר שינוי זה"</string>
+ <string name="error_message_change_not_allowed" msgid="843159705042381454">"מנהל המערכת שלך לא מאפשר את השינוי הזה"</string>
<string name="app_not_found" msgid="3429506115332341800">"לא נמצאה אפליקציה שתומכת בפעולה הזו"</string>
<string name="revoke" msgid="5526857743819590458">"ביטול"</string>
<string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string>
@@ -1875,12 +1872,12 @@
<string name="print_service_installed_title" msgid="6134880817336942482">"שירות <xliff:g id="NAME">%s</xliff:g> מותקן"</string>
<string name="print_service_installed_message" msgid="7005672469916968131">"יש להקיש כדי להפעיל את השירות"</string>
<string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"יש להזין את קוד האימות של מנהל המכשיר"</string>
- <string name="restr_pin_enter_pin" msgid="373139384161304555">"הזן קוד גישה"</string>
+ <string name="restr_pin_enter_pin" msgid="373139384161304555">"יש להזין קוד אימות"</string>
<string name="restr_pin_incorrect" msgid="3861383632940852496">"שגוי"</string>
<string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"קוד אימות נוכחי"</string>
<string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"קוד אימות חדש"</string>
- <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"אשר את קוד הגישה החדש"</string>
- <string name="restr_pin_create_pin" msgid="917067613896366033">"צור קוד גישה לשינוי הגבלות"</string>
+ <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"אישור קוד האימות החדש"</string>
+ <string name="restr_pin_create_pin" msgid="917067613896366033">"יש ליצור קוד אימות לשינוי הגבלות"</string>
<string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"קודי האימות לא תואמים. יש לנסות שוב."</string>
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"קוד הגישה קצר מדי. חייב להיות באורך 4 ספרות לפחות."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
@@ -1896,22 +1893,22 @@
<string name="done_label" msgid="7283767013231718521">"סיום"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"מחוון שעות מעגלי"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"מחוון דקות מעגלי"</string>
- <string name="select_hours" msgid="5982889657313147347">"בחר שעות"</string>
+ <string name="select_hours" msgid="5982889657313147347">"בחירת שעות"</string>
<string name="select_minutes" msgid="9157401137441014032">"בחירת דקות"</string>
- <string name="select_day" msgid="2060371240117403147">"בחר חודש ויום"</string>
+ <string name="select_day" msgid="2060371240117403147">"בחירת חודש ויום"</string>
<string name="select_year" msgid="1868350712095595393">"בחירת שנה"</string>
<string name="deleted_key" msgid="9130083334943364001">"<xliff:g id="KEY">%1$s</xliff:g> נמחק"</string>
<string name="managed_profile_label_badge" msgid="6762559569999499495">"עבודה <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> שני בעבודה"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> שלישי בעבודה"</string>
- <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"בקש קוד גישה לפני ביטול הצמדה"</string>
+ <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"יש לבקש קוד אימות לפני ביטול הצמדה"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"צריך לבקש קו ביטול נעילה לפני ביטול הצמדה"</string>
- <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"בקש סיסמה לפני ביטול הצמדה"</string>
+ <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"יש לבקש סיסמה לפני ביטול הצמדה"</string>
<string name="package_installed_device_owner" msgid="7035926868974878525">"הותקנה על ידי מנהל המערכת"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"עודכנה על ידי מנהל המערכת"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"נמחקה על ידי מנהל המערכת"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"אישור"</string>
- <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"‏כדי להאריך את חיי הסוללה, התכונה \'חיסכון בסוללה\':\n\n• מפעילה עיצוב כהה\n• מכבה או מגבילה פעילות ברקע, חלק מהאפקטים החזותיים ותכונות אחרות כמו Ok Google\n\n"<annotation id="url">"למידע נוסף"</annotation></string>
+ <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"‏כדי להאריך את חיי הסוללה, התכונה \'חיסכון בסוללה\':\n\n• מפעילה עיצוב כהה\n• מכבה או מגבילה פעילות ברקע, חלק מהאפקטים החזותיים ותכונות אחרות כמו Hey Google\n\n"<annotation id="url">"למידע נוסף"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"‏כדי להאריך את חיי הסוללה, התכונה \'חיסכון בסוללה\':\n\n• מפעילה עיצוב כהה\n• משביתה או מגבילה פעילות ברקע, חלק מהאפקטים החזותיים ותכונות אחרות כמו Hey Google"</string>
<string name="data_saver_description" msgid="4995164271550590517">"‏כדי לסייע בהפחתת השימוש בנתונים, חוסך הנתונים (Data Saver) מונע מאפליקציות מסוימות שליחה או קבלה של נתונים ברקע. אפליקציה שבה נעשה שימוש כרגע יכולה לגשת לנתונים, אבל בתדירות נמוכה יותר. המשמעות היא, למשל, שתמונות יוצגו רק לאחר שמקישים עליהן."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"להפעיל את חוסך הנתונים?"</string>
@@ -1968,18 +1965,18 @@
<string name="zen_mode_until" msgid="2250286190237669079">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="7046911727540499275">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ההתראה הבאה)"</string>
<string name="zen_mode_forever" msgid="740585666364912448">"עד הכיבוי"</string>
- <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"עד שתכבה את \'נא לא להפריע\'"</string>
+ <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"עד להשבתת התכונה \'נא לא להפריע\'"</string>
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
- <string name="toolbar_collapse_description" msgid="8009920446193610996">"כווץ"</string>
+ <string name="toolbar_collapse_description" msgid="8009920446193610996">"כיווץ"</string>
<string name="zen_mode_feature_name" msgid="3785547207263754500">"נא לא להפריע"</string>
<string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"זמן השבתה"</string>
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ערב ביום חול"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"סוף השבוע"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"אירוע"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"שינה"</string>
- <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> משתיק חלק מהצלילים"</string>
+ <string name="muted_by" msgid="91464083490094950">"חלק מהצלילים מושתקים על ידי <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"קיימת בעיה פנימית במכשיר שלך, וייתכן שהוא לא יתפקד כראוי עד שיבוצע איפוס לנתוני היצרן."</string>
- <string name="system_error_manufacturer" msgid="703545241070116315">"קיימת בעיה פנימית במכשיר שלך. לקבלת פרטים, צור קשר עם היצרן."</string>
+ <string name="system_error_manufacturer" msgid="703545241070116315">"קיימת בעיה פנימית במכשיר שלך. לקבלת פרטים, יש ליצור קשר עם היצרן."</string>
<string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"‏בקשת USSD שונתה לשיחה רגילה"</string>
<string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"‏בקשת USSD שונתה לבקשת SS"</string>
<string name="stk_cc_ussd_to_ussd" msgid="8343001461299302472">"‏היה שינוי לבקשת USSD חדשה"</string>
@@ -1992,8 +1989,8 @@
<string name="notification_work_profile_content_description" msgid="5296477955677725799">"פרופיל עבודה"</string>
<string name="notification_alerted_content_description" msgid="6139691253611265992">"נשלחה התראה"</string>
<string name="notification_verified_content_description" msgid="6401483602782359391">"מאומת"</string>
- <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"הרחב"</string>
- <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"כווץ"</string>
+ <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"הרחבה"</string>
+ <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"כיווץ"</string>
<string name="expand_action_accessibility" msgid="1947657036871746627">"החלפת מצב הרחבה"</string>
<string name="usb_midi_peripheral_name" msgid="490523464968655741">"‏יציאת USB בציוד היקפי של Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string>
@@ -2023,13 +2020,13 @@
<string name="user_creation_adding" msgid="7305185499667958364">"לאפשר לאפליקציה <xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש באמצעות <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="52674936078683285">"הוספת שפה"</string>
<string name="country_selection_title" msgid="5221495687299014379">"העדפת אזור"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"הקלד שם שפה"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"צריך להקליד את שם השפה"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"הצעות"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"כל השפות"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"כל האזורים"</string>
<string name="locale_search_menu" msgid="6258090710176422934">"חיפוש"</string>
<string name="app_suspended_title" msgid="888873445010322650">"האפליקציה לא זמינה"</string>
- <string name="app_suspended_default_message" msgid="6451215678552004172">"האפליקציה <xliff:g id="APP_NAME_0">%1$s</xliff:g> לא זמינה כרגע. את הזמינות שלה אפשר לנהל באפליקציה <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
+ <string name="app_suspended_default_message" msgid="6451215678552004172">"האפליקציה <xliff:g id="APP_NAME_0">%1$s</xliff:g> לא זמינה כרגע. אפשר לנהל זאת באפליקציה <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"מידע נוסף"</string>
<string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"ביטול ההשהיה של האפליקציה"</string>
<string name="work_mode_off_title" msgid="5503291976647976560">"להפעיל את פרופיל העבודה?"</string>
@@ -2038,7 +2035,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"האפליקציה לא זמינה"</string>
<string name="app_blocked_message" msgid="542972921087873023">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא זמינה בשלב זה."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏האפליקציה הזו עוצבה לגרסה ישנה יותר של Android וייתכן שלא תפעל כראוי. ניתן לבדוק אם יש עדכונים או ליצור קשר עם המפתח."</string>
- <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"האם יש עדכון חדש?"</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>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ייתכן שחלק מהפונקציונליות תהיה מוגבלת"</string>
@@ -2048,12 +2045,12 @@
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"הקש כדי להציג קבצים"</string>
<string name="pin_target" msgid="8036028973110156895">"הצמדה"</string>
<string name="pin_specific_target" msgid="7824671240625957415">"הצמדה של‏ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="unpin_target" msgid="3963318576590204447">"בטל הצמדה"</string>
+ <string name="unpin_target" msgid="3963318576590204447">"ביטול הצמדה"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"ביטול ההצמדה של <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"פרטי אפליקציה"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="demo_starting_message" msgid="6577581216125805905">"מתחיל בהדגמה…"</string>
- <string name="demo_restarting_message" msgid="1160053183701746766">"מאפס את המכשיר…"</string>
+ <string name="demo_starting_message" msgid="6577581216125805905">"תהליך ההדגמה מתחיל…"</string>
+ <string name="demo_restarting_message" msgid="1160053183701746766">"מתבצע איפוס של המכשיר…"</string>
<string name="suspended_widget_accessibility" msgid="6331451091851326101">"<xliff:g id="LABEL">%1$s</xliff:g> הושבת"</string>
<string name="conference_call" msgid="5731633152336490471">"שיחת ועידה"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"הסבר קצר"</string>
@@ -2073,7 +2070,7 @@
<string name="time_picker_header_text" msgid="9073802285051516688">"הגדרת שעה"</string>
<string name="time_picker_input_error" msgid="8386271930742451034">"יש להזין שעה חוקית"</string>
<string name="time_picker_prompt_label" msgid="303588544656363889">"מהי השעה הנכונה"</string>
- <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"העבר למצב קלט טקסט לצורך הזנת השעה"</string>
+ <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"מעבר לשיטת קלט טקסט כדי להזין את השעה"</string>
<string name="time_picker_radial_mode_description" msgid="1222342577115016953">"מעבר למצב שעון לצורך הזנת השעה"</string>
<string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"אפשרויות מילוי אוטומטי"</string>
<string name="autofill_save_accessibility_title" msgid="1523225776218450005">"שמירה לצורך מילוי אוטומטי"</string>
@@ -2085,12 +2082,12 @@
<item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> הצעות של מילוי אוטומטי</item>
<item quantity="one">הצעה אחת של מילוי אוטומטי</item>
</plurals>
- <string name="autofill_save_title" msgid="7719802414283739775">"לשמור ב-"<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title" msgid="7719802414283739775">"לשמור בשירות "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_type" msgid="3002460014579799605">"האם לשמור את <xliff:g id="TYPE">%1$s</xliff:g> ב-"<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_2types" msgid="3783270967447869241">"האם לשמור את <xliff:g id="TYPE_0">%1$s</xliff:g> ואת <xliff:g id="TYPE_1">%2$s</xliff:g> ב-"<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
- <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"האם לשמור את <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ו-<xliff:g id="TYPE_2">%3$s</xliff:g> ב-"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
- <string name="autofill_update_title" msgid="3630695947047069136">"האם לעדכן ב-"<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
- <string name="autofill_update_title_with_type" msgid="5264152633488495704">"האם לעדכן את <xliff:g id="TYPE">%1$s</xliff:g> ב-"<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"לשמור את <xliff:g id="TYPE_0">%1$s</xliff:g>,‏ <xliff:g id="TYPE_1">%2$s</xliff:g> ואת <xliff:g id="TYPE_2">%3$s</xliff:g> בשירות "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_update_title" msgid="3630695947047069136">"לעדכן בשירות "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_update_title_with_type" msgid="5264152633488495704">"לעדכן <xliff:g id="TYPE">%1$s</xliff:g> בשירות "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
<string name="autofill_update_title_with_2types" msgid="1797514386321086273">"האם לעדכן את <xliff:g id="TYPE_0">%1$s</xliff:g> ואת <xliff:g id="TYPE_1">%2$s</xliff:g> ב-"<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"האם לעדכן פריטים אלה ב-"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ו-<xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"שמירה"</string>
@@ -2109,7 +2106,7 @@
<string name="autofill_save_type_email_address" msgid="1303262336895591924">"כתובת אימייל"</string>
<string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"חשוב להישאר רגועים ולחפש מחסה בקרבת מקום."</string>
<string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"יש להתפנות מיידית מאזורים הסמוכים לחופים ולנהרות למקום בטוח יותר, כגון שטח גבוה יותר."</string>
- <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"הישאר רגוע וחפש מחסה בקרבת מקום."</string>
+ <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"חשוב להישאר רגועים ולחפש מחסה בקרבת מקום."</string>
<string name="etws_primary_default_message_test" msgid="4583367373909549421">"בדיקה של הודעות חירום"</string>
<string name="notification_reply_button_accessibility" msgid="5235776156579456126">"תשובה"</string>
<string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
@@ -2120,10 +2117,10 @@
<string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"‏SIM <xliff:g id="SIMNUMBER">%d</xliff:g> אינו מאושר לשימוש ברשת"</string>
<string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"‏אין ניהול תצורה עבור SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"‏SIM‏ <xliff:g id="SIMNUMBER">%d</xliff:g> אינו מאושר לשימוש ברשת"</string>
- <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"‏SIM <xliff:g id="SIMNUMBER">%d</xliff:g> אינו מאושר לשימוש ברשת"</string>
+ <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"‏SIM‏ <xliff:g id="SIMNUMBER">%d</xliff:g> אינו מאושר לשימוש ברשת"</string>
<string name="popup_window_default_title" msgid="6907717596694826919">"חלון קופץ"</string>
<string name="slice_more_content" msgid="3377367737876888459">"ועוד <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"גרסת האפליקציה שודרגה לאחור או שאינה תואמת לקיצור דרך זה"</string>
+ <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"גרסת האפליקציה שודרגה לאחור או שהיא לא תואמת לקיצור הדרך הזה"</string>
<string name="shortcut_restore_not_supported" msgid="4763198938588468400">"לא ניתן היה לשחזר את קיצור הדרך מפני שהאפליקציה אינה תומכת בגיבוי ובשחזור"</string>
<string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"לא ניתן היה לשחזר את קיצור הדרך עקב חוסר התאמה בחתימה על האפליקציות"</string>
<string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"לא ניתן היה לשחזר את קיצור הדרך"</string>
@@ -2135,7 +2132,7 @@
<string name="screenshot_edit" msgid="7408934887203689207">"עריכה"</string>
<string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"שיחות והודעות ירטטו"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"שיחות והתראות יושתקו"</string>
- <string name="notification_channel_system_changes" msgid="2462010596920209678">"שינויי מערכת"</string>
+ <string name="notification_channel_system_changes" msgid="2462010596920209678">"שינויים במערכת"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"נא לא להפריע"</string>
<string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"חדש: מצב \'נא לא להפריע\' מסתיר התראות"</string>
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"אפשר להקיש כדי לקבל מידע נוסף ולבצע שינויים."</string>
@@ -2150,12 +2147,12 @@
<string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"ההתראה הזו שודרגה ל\'ברירת מחדל\'. יש להקיש כדי לשלוח משוב."</string>
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ההתראה הזו הורדה בדרגה ל\'שקטה\'. יש להקיש כדי לשלוח משוב."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"דירוג ההתראה הזו הוגבה. יש להקיש כדי לשלוח משוב."</string>
- <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"דירוג ההתראה הזו הונמך. יש להקיש כדי לשלוח משוב."</string>
+ <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ההתראה הזו דורגה נמוך יותר. יש להקיש כדי לשלוח משוב."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"התראת מידע לגבי מצב שגרתי"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"הסוללה עלולה להתרוקן לפני המועד הרגיל של הטעינה"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"תכונת החיסכון בסוללה הופעלה כדי להאריך את חיי הסוללה"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"חיסכון בסוללה"</string>
- <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"\'חיסכון בסוללה\' כבוי"</string>
+ <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"מצב \'חיסכון בסוללה\' כבוי"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"הטלפון טעון מספיק. התכונות כבר לא מוגבלות."</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"הטאבלט טעון מספיק. התכונות כבר לא מוגבלות."</string>
<string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"המכשיר טעון מספיק. התכונות כבר לא מוגבלות."</string>
@@ -2180,10 +2177,10 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"‏Bluetooth יישאר מופעל במהלך מצב טיסה"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"בטעינה"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
- <item quantity="two"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> קבצים</item>
- <item quantity="many"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> קבצים</item>
- <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> קבצים</item>
- <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> + קובץ אחד (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="two"><xliff:g id="FILE_NAME_2">%s</xliff:g> ועוד <xliff:g id="COUNT_3">%d</xliff:g> קבצים</item>
+ <item quantity="many"><xliff:g id="FILE_NAME_2">%s</xliff:g> ועוד <xliff:g id="COUNT_3">%d</xliff:g> קבצים</item>
+ <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> ועוד <xliff:g id="COUNT_3">%d</xliff:g> קבצים</item>
+ <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> ועוד קובץ אחד (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
</plurals>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"אין אנשים שניתן לשתף איתם"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"רשימת האפליקציות"</string>
@@ -2211,31 +2208,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"עבודה"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"תצוגה אישית"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"תצוגת עבודה"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"‏נחסם על ידי מנהל ה-IT"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"אי אפשר לשתף את התוכן הזה עם אפליקציות לעבודה"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"אי אפשר לפתוח את התוכן הזה באמצעות אפליקציות לעבודה"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"אי אפשר לשתף את התוכן הזה עם אפליקציות לשימוש אישי"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"אי אפשר לפתוח את התוכן הזה באמצעות אפליקציות לשימוש אישי"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"פרופיל העבודה מושהה"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"יש להקיש כדי להפעיל"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"אין אפליקציות לעבודה"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"אין אפליקציות לשימוש אישי"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"לפתוח באפליקציה <xliff:g id="APP">%s</xliff:g> בפרופיל האישי?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"לפתוח באפליקציה <xliff:g id="APP">%s</xliff:g> בפרופיל העבודה?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"בדפדפן האישי"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"בדפדפן של העבודה"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏קוד אימות לביטול הנעילה של רשת SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"‏קוד אימות לביטול הנעילה של תת-קבוצה ברשת SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"‏קוד אימות לביטול הנעילה של כרטיס SIM עסקי"</string>
@@ -2293,12 +2278,12 @@
<string name="PERSOSUBSTATE_SIM_NETWORK_ERROR" msgid="1924844017037151535">"‏לא ניתן היה לבטל את הנעילה של רשת SIM."</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ERROR" msgid="3372797822292089708">"‏לא ניתן היה לבטל את הנעילה של תת-קבוצה ברשת SIM."</string>
<string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR" msgid="1878443146720411381">"‏נכשלה הבקשה לביטול הנעילה של ספק שירות SIM."</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR" msgid="7664778312218023192">"‏נכשלה הבקשה לביטול הנעילה של כרטיס SIM עסקי."</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR" msgid="7664778312218023192">"‏לא ניתן היה לבטל את הנעילה של כרטיס SIM עסקי."</string>
<string name="PERSOSUBSTATE_SIM_SIM_ERROR" msgid="2472944311643350302">"‏נכשלה הבקשה לביטול נעילת SIM."</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK1_ERROR" msgid="828089694480999120">"‏נכשלה הבקשה לביטול הנעילה של RUIM network1."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR" msgid="17619001007092511">"‏נכשלה הבקשה לביטול הנעילה של RUIM network2."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR" msgid="17619001007092511">"‏לא ניתן היה לבטל את הנעילה של RUIM network2."</string>
<string name="PERSOSUBSTATE_RUIM_HRPD_ERROR" msgid="807214229604353614">"‏נכשלה הבקשה לביטול נעילה של RUIM hrpd."</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR" msgid="8644184447744175747">"‏נכשלה הבקשה לביטול הנעילה של כרטיס RUIM עסקי."</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR" msgid="8644184447744175747">"‏לא ניתן היה לבטל את הנעילה של כרטיס RUIM עסקי."</string>
<string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR" msgid="3801002648649640407">"‏לא ניתן היה לבטל את הנעילה של ספק שירות RUIM."</string>
<string name="PERSOSUBSTATE_RUIM_RUIM_ERROR" msgid="707397021218680753">"‏לא ניתן היה לבטל את הנעילה של כרטיס RUIM."</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ERROR" msgid="894358680773257820">"‏נכשל ביטול נעילה של PUK."</string>
@@ -2311,7 +2296,7 @@
<string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ERROR" msgid="817542684437829139">"‏לא ניתן היה לבטל את הנעילה של PUK."</string>
<string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ERROR" msgid="5178635064113393143">"‏לא ניתן היה לבטל את הנעילה של PUK."</string>
<string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ERROR" msgid="5391587926974531008">"‏לא ניתן היה לבטל נעילה של PUK."</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ERROR" msgid="4895494864493315868">"‏נכשל ביטול נעילה של PUK."</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ERROR" msgid="4895494864493315868">"‏לא ניתן היה לבטל את הנעילה של PUK."</string>
<string name="PERSOSUBSTATE_SIM_SPN_ERROR" msgid="9017576601595353649">"‏לא ניתן היה לבטל את נעילת SPN."</string>
<string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ERROR" msgid="1116993930995545742">"‏לא ניתן היה לבטל את הנעילה של PLMN לבית כשווה-ערך ל-SP."</string>
<string name="PERSOSUBSTATE_SIM_ICCID_ERROR" msgid="7559167306794441462">"‏נכשלה הבקשה לביטול נעילה של ICCID."</string>
@@ -2348,8 +2333,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"הגדרות חדשות להגדלה"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"עכשיו אפשר להגדיל חלק מהמסך"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"הפעלה בהגדרות"</string>
<string name="dismiss_action" msgid="1728820550388704784">"סגירה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6be065139e3d..deaeaab46bb3 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"実行中のアプリ"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"電池を消費しているアプリ"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"拡大"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ユーザー補助の使用"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」が電池を使用しています"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリが電池を使用しています"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"タップして電池やデータの使用量を確認"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"付近の Bluetooth デバイスの検出とペア設定をアプリに許可します"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ペア設定された Bluetooth デバイスへの接続"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ペア設定された Bluetooth デバイスへの接続をアプリに許可します"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"優先される NFC お支払いサービスの情報"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"登録されている支援やルートの目的地など、優先される NFC お支払いサービスの情報を取得することをアプリに許可します。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFCの管理"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"画面ロックの使用"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"指紋の一部しか検出できません"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"指紋を処理できませんでした。もう一度お試しください。"</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"センサーの汚れを取り除いてください"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"指を離すのが早すぎました"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"指の動きが遅すぎました。もう一度お試しください。"</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"別の指紋をお試しください"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"明るすぎます"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"調整してみてください"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋認証を完了しました"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"顔を認証しました"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"顔を認証しました。[確認] を押してください"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指紋認証ハードウェアは使用できません。"</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"指紋を設定できません"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"指紋の読み取りがタイムアウトになりました。もう一度お試しください。"</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋の操作をキャンセルしました。"</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"指紋の操作がユーザーによりキャンセルされました。"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 2c1a016c629e..c767bcdadde1 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"საშუალებას აძლევს აპს, აღმოაჩინოს ახლომახლო Bluetooth მოწყობილობები დასაწყვილებლად"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"დაწყვილებულ Bluetooth მოწყობილობებთან დაკავშირება"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"საშუალებას აძლევს აპს, დაუკავშირდეს დაწყვილებულ Bluetooth მოწყობილობებს"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"უპირატესი NFC გადახდის სერვისის ინფორმაცია"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"საშუალებას აძლევს აპს, მიიღოს უპირატესი NFC გადახდის სერვისის ინფორმაცია, მაგალითად, რეგისტრირებული დახმარება და დანიშნულება."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ახლო მოქმედების რადიოკავშირი (NFC) მართვა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 4a6548238db1..61d06d2253c9 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Қолданбаға маңайдағы Bluetooth құрылғыларын анықтап, жұптауға рұқсат береді."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"жұпталған Bluetooth құрылғыларына қосылу"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Қолданбаға жұпталған Bluetooth құрылғыларына қосылуға рұқсат береді."</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Таңдаулы NFC төлеу қызметі туралы ақпарат"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Қолданба тіркелген көмектер және баратын жер маршруты сияқты таңдаулы NFC төлеу қызметі туралы ақпаратты ала алатын болады."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC функциясын басқару"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index c8e183882a0b..2cdf658bd5cf 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"អនុញ្ញាតឱ្យកម្មវិធី​ស្វែងរក និងផ្គូផ្គង​ឧបករណ៍​ប៊្លូធូសដែលនៅជិត"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ភ្ជាប់ទៅឧបករណ៍​ប៊្លូធូសដែលបានផ្គូផ្គង"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"អនុញ្ញាតឱ្យ​កម្មវិធីភ្ជាប់ទៅ​ឧបករណ៍​ប៊្លូធូសដែលបានផ្គូផ្គង"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ព័ត៌មានអំពី​សេវាបង់ប្រាក់តាម NFC ជាអាទិភាព"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"អនុញ្ញាតឱ្យ​កម្មវិធី​ទទួលបាន​ព័ត៌មានអំពី​សេវាបង់ប្រាក់តាម nfc ជាអាទិភាព​ដូចជា គោលដៅផ្លូវ និង​ព័ត៌មាន​កំណត់អត្តសញ្ញាណ​កម្មវិធី ដែលបានចុះឈ្មោះ​ជាដើម។"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ពិនិត្យ​ការ​ទាក់ទង​នៅ​ក្បែរ (NFC)"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"ការដោះសោ​តាមទម្រង់មុខ"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ស្កេន​បញ្ចូល​មុខរបស់អ្នក​ម្ដងទៀត"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"ដើម្បី​ធ្វើឱ្យ​ការសម្គាល់មុខ​ប្រសើរជាងមុន សូមស្កេន​បញ្ចូល​មុខរបស់អ្នក​ម្ដងទៀត"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"រៀបចំ​ការដោះសោ​តាម​ទម្រង់​មុខ"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"ដោះសោទូរសព្ទ​របស់អ្នកដោយសម្លឹងមើលវា"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"រៀបចំ​វិធីច្រើនទៀត​ដើម្បី​ដោះសោ"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ចុច​ដើម្បីបញ្ចូល​ស្នាមម្រាមដៃ"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"មិនអាច​ថត​ទិន្នន័យទម្រង់មុខ​បាន​ត្រឹមត្រូវទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ភ្លឺពេក។ សូមសាកល្បង​ប្រើ​ពន្លឺស្រាលជាងនេះ។"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"ងងឹតជ្រុល។ សូមសាកល្បង​ប្រើ​ពន្លឺភ្លឺជាងនេះ។"</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"បា​នចម្លង"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូលពី <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូលពីឃ្លីបបត"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូល​អត្ថបទ​ដែលអ្នក​បានចម្លង"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូល​រូបភាព​ដែលអ្នក​បានចម្លង"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូល​ខ្លឹមសារ​ដែលអ្នក​បានចម្លង"</string>
<string name="more_item_label" msgid="7419249600215749115">"ច្រើន​ទៀត"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"ម៉ឺនុយ +"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"ការងារ"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"ទិដ្ឋភាពផ្ទាល់ខ្លួន"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"ទិដ្ឋភាព​ការងារ"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"បានទប់ស្កាត់ដោយ​អ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"ខ្លឹមសារនេះ​មិនអាចចែករំលែក​តាមរយៈ​កម្មវិធី​ការងារ​បានទេ"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ខ្លឹមសារនេះ​មិនអាចបើក​តាមរយៈ​កម្មវិធី​ការងារ​បានទេ"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ខ្លឹមសារនេះ​មិនអាចចែករំលែក​តាមរយៈ​កម្មវិធី​ផ្ទាល់ខ្លួន​បានទេ"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ខ្លឹមសារនេះ​មិនអាចបើក​តាមរយៈ​កម្មវិធី​ផ្ទាល់ខ្លួន​បានទេ"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"កម្រងព័ត៌មានការងារត្រូវបាន​ផ្អាក"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"ចុច​ដើម្បី​បើក"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"គ្មាន​កម្មវិធី​ការងារ​ទេ"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"គ្មាន​កម្មវិធី​ផ្ទាល់ខ្លួន​ទេ"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"បើក​នៅក្នុង <xliff:g id="APP">%s</xliff:g> ក្នុង​កម្រងព័ត៌មាន​ផ្ទាល់ខ្លួន​ឬ?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"បើក​នៅក្នុង <xliff:g id="APP">%s</xliff:g> ក្នុង​កម្រងព័ត៌មាន​ការងារឬ?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ប្រើ​កម្មវិធីរុករក​តាមអ៊ីនធឺណិត​ផ្ទាល់ខ្លួន"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ប្រើ​កម្មវិធីរុករក​តាមអ៊ីនធឺណិត​សម្រាប់​ការងារ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"កូដ PIN ដោះ​សោ​បណ្ដាញ​ស៊ីម"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"កូដ PIN ដោះសោ​សំណុំរង​នៃ​បណ្ដាញស៊ីម"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"កូដ PIN ដោះសោ​ក្រុមហ៊ុនស៊ីម"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"ការកំណត់​ការពង្រីក​ថ្មី"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ឥឡូវនេះ អ្នកអាចពង្រីក​ផ្នែកនៃអេក្រង់​របស់អ្នកបានហើយ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"បើកនៅក្នុងការកំណត់"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ច្រានចោល"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 1a450add12f6..9460a5516a40 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ಸಮೀಪದಲ್ಲಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಅನ್ವೇಷಿಸಲು ಮತ್ತು ಅವುಗಳಿಗೆ ಜೋಡಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ಜೋಡಿಸಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ಜೋಡಿಸಲಾಗಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವಾ ಮಾಹಿತಿ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ನೋಂದಾಯಿತ ಅಪ್ಲಿಕೇಶನ್ ಗುರುತಿಸುವಿಕೆಗಳು ಮತ್ತು ಮಾರ್ಗ ಗಮ್ಯಸ್ಥಾನಗಳಂತಹ ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವೆಗಳ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ಸಮೀಪ ಕ್ಷೇತ್ರ ಸಂವಹನವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"ಫೇಸ್ ಅನ್‌ಲಾಕ್"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ನಿಮ್ಮ ಮುಖವನ್ನು ಮರುನೋಂದಣಿ ಮಾಡಿ"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"ಗುರುತಿಸುವಿಕೆಯನ್ನು ಹೆಚ್ಚಿಸಲು ನಿಮ್ಮ ಮುಖವನ್ನು ಮರುನೋಂದಣಿ ಮಾಡಿ"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಸೆಟಪ್ ಮಾಡಿ"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"ಫೋನ್ ಅನ್ನು ನೋಡುವ ಮೂಲಕ ಅನ್‌ಲಾಕ್‌ ಮಾಡಿ"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಹೆಚ್ಚಿನ ಮಾರ್ಗಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಸೇರಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"ಸರಿಯಾಗಿ ಮುಖ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಲಾಗಲಿಲ್ಲ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ ಮಂದ ಪ್ರಕಾಶಮಾನವಿರುವ ಲೈಟ್ ಬಳಸಿ"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"ತುಂಬಾ ಕಪ್ಪು ಛಾಯೆಯಿದೆ. ಪ್ರಕಾಶಮಾನವಾದ ಲೈಟಿಂಗ್ ಬಳಸಿ."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"ನಕಲಿಸಲಾಗಿದೆ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ಅನ್ನು <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ಅನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"ನೀವು ನಕಲಿಸಿರುವ ಪಠ್ಯವನ್ನು <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"ನೀವು ನಕಲಿಸಿರುವ ಚಿತ್ರವನ್ನು <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
+ <string name="pasted_content" msgid="646276353060777131">"ನೀವು ನಕಲಿಸಿರುವ ವಿಷಯವನ್ನು <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
<string name="more_item_label" msgid="7419249600215749115">"ಇನ್ನಷ್ಟು"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"ಮೆನು+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"ಕೆಲಸ"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"ವೈಯಕ್ತಿಕ ವೀಕ್ಷಣೆ"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"ಕೆಲಸದ ವೀಕ್ಷಣೆ"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರಿಂದ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳ ಈ ವಿಷಯವನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುವುದಿಲ್ಲ"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳ ಈ ವಿಷಯವನ್ನು ತೆರೆಯಲಾಗುವುದಿಲ್ಲ"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ಗಳ ಮೂಲಕ ಈ ವಿಷಯವನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುವುದಿಲ್ಲ"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ಗಳ ಮೂಲಕ ಈ ವಿಷಯವನ್ನು ತೆರೆಯಲಾಗುವುದಿಲ್ಲ"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"ಆನ್‌‌‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ಯಾವುದೇ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"<xliff:g id="APP">%s</xliff:g> ನ ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್‌ನಲ್ಲಿ ತೆರೆಯುವುದೇ?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"<xliff:g id="APP">%s</xliff:g> ನ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ನಲ್ಲಿ ತೆರೆಯುವುದೇ?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ವೈಯಕ್ತಿಕ ಬ್ರೌಸರ್ ಬಳಸಿ"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ಉದ್ಯೋಗ ಬ್ರೌಸರ್ ಬಳಸಿ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ನೆಟ್‌ವರ್ಕ್‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ನೆಟ್‌ವರ್ಕ್ ಸಬ್‌ಸೆಟ್‌ನ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM ಕಾರ್ಪೊರೇಟ್ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"ಹೊಸ ಹಿಗ್ಗಿಸುವಿಕೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ನೀವು ಇದೀಗ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಭಾಗವನ್ನು ಹಿಗ್ಗಿಸಬಹುದು"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಆನ್ ಮಾಡಿ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ವಜಾಗೊಳಿಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index dc59a700dcfc..765e0abf9464 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"앱이 근처의 블루투스 기기를 찾고 페어링하도록 허용"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"페어링된 블루투스 기기에 연결"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"앱이 페어링된 블루투스 기기에 연결하도록 허용"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"기본 NFC 결제 서비스 정보"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"앱이 등록된 AID와 경로 목적지 같은 기본 NFC 결제 서비스 정보를 확인하도록 허용합니다."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC(Near Field Communication) 제어"</string>
@@ -2137,9 +2141,9 @@
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"개인 뷰"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"직장 뷰"</string>
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"IT 관리자에 의해 차단됨"</string>
- <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"이 콘텐츠는 직장 앱으로 공유할 수 없습니다."</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"이 콘텐츠는 직장 앱을 통해 공유할 수 없습니다."</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"이 콘텐츠는 직장 앱으로 열 수 없습니다."</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"이 콘텐츠는 개인 앱으로 공유할 수 없습니다."</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"이 콘텐츠는 개인 앱을 통해 공유할 수 없습니다."</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"이 콘텐츠는 개인 앱으로 열 수 없습니다."</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"직장 프로필이 일시중지됨"</string>
<string name="resolver_switch_on_work" msgid="463709043650610420">"탭하여 사용"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 40940b059a0a..0d5f9be0fad1 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Колдонмого жакын жердеги Bluetooth түзмөктөрүн аныктап, жупташтырууга уруксат берет"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"жупташтырылган Bluetooth түзмөктөрү"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Колдонмого жупташтырылган Bluetooth түзмөктөрү менен байланышууга уруксат берет"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Тандалган NFC төлөм кызматы жөнүндө маалымат"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Колдонмого катталган жардам же көздөлгөн жерге маршрут сыяктуу тандалган nfc төлөм кызматы жөнүндө маалыматты алууга уруксат берүү."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication көзөмөлү"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Жүзүнөн таануу"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Жүзүңүздү кайра таанытыңыз."</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Мыкты таануу үчүн, жүзүңүздү кайра таанытыңыз"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Жүзүнөн таанып ачуу функциясын жөндөңүз"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Телефонуңузду карап туруп эле кулпусун ачып алыңыз"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Кулпусун ачуунун көбүрөөк жолдорун жөндөңүз"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Манжа изин кошуу үчүн басыңыз"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Жүзүңүз жакшы тартылган жок. Кайталап көрүңүз."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Өтө жарык. Жарыктыкты азайтып көрүңүз."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Өтө караңгы. Жарыгыраак жерден тартып көрүңүз."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"Көчүрүлдү"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> колдонмосунан чапталды"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> алмашуу буферинен чапталды"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>: көчүрүлгөн текст чапталды"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>: көчүрүлгөн сүрөт чапталды"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>: көчүрүлгөн мазмун чапталды"</string>
<string name="more_item_label" msgid="7419249600215749115">"Дагы"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Жумуш"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Жеке көрүнүш"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Жумуш көрүнүшү"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"IT администраторуңуз бөгөттөп койгон"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Бул мазмунду жумуш колдонмолору менен бөлүшүү мүмкүн эмес"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Бул мазмунду жумуш колдонмолору менен ачуу мүмкүн эмес"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Бул мазмунду жеке колдонмолор менен бөлүшүү мүмкүн эмес"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Бул мазмунду жеке колдонмолор менен ачуу мүмкүн эмес"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Жумуш профили тындырылган"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Күйгүзүү үчүн таптап коюңуз"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Жумуш колдонмолору жок"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Жеке колдонмолор жок"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"<xliff:g id="APP">%s</xliff:g> колдонмосунда жеке профилде ачылсынбы?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"<xliff:g id="APP">%s</xliff:g> колдонмосунда жумуш профилинде ачылсынбы?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Жеке серепчини колдонуу"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Жумуш серепчисин колдонуу"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM карта тармагынын кулпусун ачуучу PIN код"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM кичи тармагынын кулпусун ачуучу PIN код"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM картанын корпоративдик кулпусун ачуучу PIN код"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Жаңы чоңойтуу жөндөөлөрү"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Эми экрандын бир бөлүгүн чоңойто аласыз"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Жөндөөлөрдөн күйгүзүү"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Жабуу"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 5b0208bb64ce..13f492618040 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ອະນຸຍາດໃຫ້ແອັບຄົ້ນພົບ ແລະ ຈັບຄູ່ອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງໄດ້"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ເຊື່ອມຕໍ່ຫາອຸປະກອນ Bluetooth ທີ່ຈັບຄູ່ໄວ້"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ອະນຸຍາດໃຫ້ແອັບເຊື່ອມຕໍ່ຫາອຸປະກອນ Bluetooth ທີ່ຈັບຄູ່ແລ້ວໄດ້"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ຂໍ້ມູນບໍລິການການຈ່າຍເງິນ NFC ທີ່ຕ້ອງການ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ອະນຸຍາດໃຫ້ແອັບຮັບຂໍ້ມູນບໍລິການການຈ່າຍເງິນ NFC ທີ່ຕ້ອງການໄດ້ ເຊັ່ນ: ການຊ່ວຍເຫຼືອແບບລົງທະບຽນ ແລະ ປາຍທາງເສັ້ນທາງ."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ຄວບຄຸມ Near Field Communication"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"ປົດລັອກດ້ວຍໜ້າ"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ລົງທະບຽນໃບໜ້າຂອງທ່ານຄືນໃໝ່"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"ເພື່ອປັບປຸງການຈຳແນກ, ກະລຸນາລົງທະບຽນໃບໜ້າຂອງທ່ານຄືນໃໝ່."</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າ"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"ປົດລັອກໂທລະສັບຂອງທ່ານໂດຍການເບິ່ງມັນ"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ຕັ້ງຄ່າວິທີເພີ່ມເຕີມເພື່ອປົດລັອກ"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ແຕະເພື່ອເພີ່ມລາຍນິ້ວມື"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"ບໍ່ສາມາດບັນທຶກຂໍ້ມູນໃບໜ້າທີ່ຖືກຕ້ອງໄດ້. ກະລຸນາລອງໃໝ່."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ແຈ້ງເກີນໄປ. ລອງຄ່ອຍແສງໄຟລົງ."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"ມືດເກີນ. ກະລຸນາລອງໃຊ້ສະພາບແສງທີ່ແຈ້ງຂຶ້ນ."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"ສຳເນົາແລ້ວ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"ວາງ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ຈາກ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ແລ້ວ"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"ວາງ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ຈາກຄລິບບອດແລ້ວ"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງຂໍ້ຄວາມທີ່ທ່ານສຳເນົາແລ້ວ"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງຮູບທີ່ທ່ານສຳເນົາແລ້ວ"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງເນື້ອຫາທີ່ທ່ານສຳເນົາແລ້ວ"</string>
<string name="more_item_label" msgid="7419249600215749115">"ເພີ່ມເຕີມ"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"ເມນູ+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"ວຽກ"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"ມຸມມອງສ່ວນຕົວ"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"ມຸມມອງວຽກ"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"ຖືກບລັອກໄວ້ໂດຍຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານ"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"ເນື້ອຫານີ້ບໍ່ສາມາດຖືກແບ່ງປັນກັບແອັບບ່ອນເຮັດວຽກໄດ້"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ເນື້ອຫານີ້ບໍ່ສາມາດຖືກເປີດໄດ້ດ້ວຍແອັບບ່ອນເຮັດວຽກ"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ເນື້ອຫານີ້ບໍ່ສາມາດຖືກແບ່ງປັນກັບແອັບສ່ວນຕົວໄດ້"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ເນື້ອຫານີ້ບໍ່ສາມາດຖືກເປີດໄດ້ດ້ວຍແອັບສ່ວນຕົວ"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ຢຸດໂປຣໄຟລ໌ວຽກໄວ້ຊົ່ວຄາວແລ້ວ"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"ແຕະເພື່ອເປີດໃຊ້"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ບໍ່ມີແອັບບ່ອນເຮັດວຽກ"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ບໍ່ມີແອັບສ່ວນຕົວ"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"ເປີດໃນ <xliff:g id="APP">%s</xliff:g> ໃນໂປຣໄຟລ໌ສ່ວນຕົວບໍ?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"ເປີດໃນ <xliff:g id="APP">%s</xliff:g> ໃນ​ໂປຣ​ໄຟລ໌​ບ່ອນ​ເຮັດ​ວຽກບໍ?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ໃຊ້ໂປຣແກຣມທ່ອງເວັບສ່ວນຕົວ"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ໃຊ້ໂປຣແກຣມທ່ອງເວັບບ່ອນເຮັດວຽກ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ປົດລັອກເຄືອຂ່າຍຊິມ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN ການປົດລັອກຊຸດຍ່ອຍເຄືອຂ່າຍຊິມ"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN ປົດລັອກ SIM ອົງການ"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"ການຕັ້ງຄ່າການຂະຫຍາຍໃໝ່"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ຕອນນີ້ທ່ານສາມາດຂະຫຍາຍບາງສ່ວນຂອງໜ້າຈໍໄດ້ແລ້ວ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ເປີດໃຊ້ໃນການຕັ້ງຄ່າ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ປິດໄວ້"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 07438b5d0d6d..72e21f4024ba 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -545,6 +545,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Leidžiama programai aptikti ir susieti „Bluetooth“ įrenginius netoliese"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"prisijungimas prie susietų „Bluetooth“ įrenginių"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Leidžiama programai prisijungti prie susietų „Bluetooth“ įrenginių"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Pageidaujama ARL mokėjimo paslaugos informacija"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Programai leidžiama gauti pageidaujamą ARL mokamos paslaugos informaciją, pvz., užregistruotą pagalbą ir maršrutų tikslus."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"valdyti artimo lauko perdavimą (angl. „Near Field Communication“)"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index e8dceb9677f7..a4f87b304c3d 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -542,6 +542,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Ļauj lietotnei atrast un savienot pārī tuvumā esošas Bluetooth ierīces."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"piekļūt pārī savienotām Bluetooth ierīcēm"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Ļauj lietotnei piekļūt pārī savienotām Bluetooth ierīcēm."</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informācija par vēlamo NFC maksājumu pakalpojumu"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ļauj lietotnei iegūt informāciju par vēlamo NFC maksājumu pakalpojumu, piemēram, par reģistrētajiem lietojumprogrammu ID un maršruta galamērķi."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolē tuvlauka saziņu"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 2f1954a430e8..f86201f472e1 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозволува апликацијата да открива и да се поврзува со спарени уреди со Bluetooth во близина"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"да се поврзува со спарени уреди со Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозволува апликацијата да се поврзува со спарени уреди со Bluetooth"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информации за претпочитаната услуга за плаќање преку NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволува апликацијата да добие информации за претпочитаната услуга за плаќање преку NFC, како регистрирани помагала и дестинација на маршрутата."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контролирај комуникација на блиско поле"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 1143e22c119d..5f49f2cdb3cd 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"സമീപമുള്ള Bluetooth ഉപകരണങ്ങൾ കണ്ടെത്താനും ജോടിയാക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ജോടിയായ Bluetooth ഉപകരണങ്ങളിലേക്ക് കണക്റ്റ് ചെയ്യൂ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ജോടിയാക്കിയ Bluetooth ഉപകരണങ്ങളിലേക്ക് കണക്റ്റ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"റൂട്ട് ലക്ഷ്യസ്ഥാനം, രജിസ്‌റ്റർ ചെയ്തിരിക്കുന്ന സഹായങ്ങൾ എന്നിവ പോലുള്ള, തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ ലഭിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"സമീപ ഫീൽഡുമായുള്ള ആശയവിനിമയം നിയന്ത്രിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 30c664f4ab92..692d16a8ecd2 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Апп ажиллаж байна"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апп батарей ашиглаж байна"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Томруулах"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Хандалтын ашиглалт"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батерей ашиглаж байна"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батерей ашиглаж байна"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Aппыг ойролцоох Bluetooth төхөөрөмжүүдийг илрүүлж, хослуулахыг зөвшөөрдөг"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"хослуулсан Bluetooth төхөөрөмжүүдэд холбогдох"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Аппыг хослуулсан Bluetooth төхөөрөмжүүдэд холбогдохыг зөвшөөрдөг"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сонгосон NFC төлбөрийн үйлчилгээний мэдээлэл"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Бүртгүүлсэн төхөөрөмж болон маршрутын хүрэх цэг зэрэг сонгосон nfc төлбөрийн үйлчилгээний мэдээллийг авахыг аппад зөвшөөрдөг."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ойролцоо талбарын холбоог удирдах"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Дэлгэцийн түгжээг ашиглах"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Хэсэгчилсэн хурууны хээ илэрлээ"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Хурууны хээ боловсруулж чадахгүй байна. Дахин оролдоно уу."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Мэдрэгчийг цэвэрлэнэ үү"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Хуруу хэт хурдан хөдөллөө"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Хуруу хэт удаан хөдөлгөсөн байна. Дахин оролдоно уу."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Өөр хурууны хээ туршина уу"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Хэт гэрэлтэй байна"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Тохируулж үзнэ үү"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Хурууны хээг нотолсон"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Царайг баталгаажууллаа"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Царайг баталгаажууллаа. Баталгаажуулах товчлуурыг дарна уу"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хурууны хээний төхөөрөмж бэлэн бус байна."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Хурууны хээ тохируулах боломжгүй"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Хурууны хээ оруулах хугацаа өнгөрсөн байна. Дахин оруулна уу."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Хурууны хээний бүртгэл амжилтгүй боллоо."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Хэрэглэгч хурууны хээний баталгаажуулалтыг цуцалсан байна."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index ddc001f472e9..ac267a12c8e0 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ॲपला जवळपासची ब्लूटूथ डिव्‍हाइस शोधण्यासाठी आणि ती पेअर करण्यासाठी अनुमती देते"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"पेअर केलेल्या ब्लूटूथ डिव्‍हाइसशी कनेक्ट करा"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"पेअर केलेल्या ब्लूटूथ डिव्‍हाइसशी कनेक्ट करण्यासाठी ॲपला अनुमती द्या"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"प्राधान्यकृत NFC पेमेंट सेवा माहिती"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"नोंदणीकृत एड्स आणि मार्ग गंतव्यस्थान सारखी प्राधान्यकृत एनएफसी पेमेंट सेवेची माहिती मिळवण्यासाठी अ‍ॅपला अनुमती देते."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
@@ -2262,8 +2266,7 @@
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
<string name="window_magnification_prompt_title" msgid="2876703640772778215">"नवीन मॅग्निफिकेशन सेटिंग्ज"</string>
- <!-- no translation found for window_magnification_prompt_content (8159173903032344891) -->
- <skip />
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"आता तुम्ही तुमच्या स्क्रीनचा एखादा भाग मॅग्निफाय करू शकता"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग्ज मध्ये सुरू करा"</string>
<string name="dismiss_action" msgid="1728820550388704784">"डिसमिस करा"</string>
<string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"पुढे सुरू ठेवण्यासाठी, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ला तुमच्या डिव्हाइसचा मायक्रोफोन अ‍ॅक्सेस करण्याची आवश्यकता आहे."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 4d8726701009..b11028fa963f 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Membenarkan apl menemukan dan berganding dengan peranti Bluetooth yang berdekatan"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"sambung kepada peranti Bluetooth yang digandingkan"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Membenarkan apl untuk menyambung kepada peranti Bluetooth yang digandingkan"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maklumat Perkhidmatan Pembayaran NFC Pilihan"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Membenarkan apl mendapatkan maklumat perkhidmatan pembayaran nfc pilihan seperti bantuan berdaftar dan destinasi laluan."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"mengawal Komunikasi Medan Dekat"</string>
@@ -624,7 +628,7 @@
<string name="face_setup_notification_title" msgid="550617822603450009">"Sediakan wajah buka kunci"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"Buka kunci telefon anda dengan melihat telefon anda"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Sediakan lebih banyak cara untuk membuka kunci"</string>
- <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Ketik untuk menambah cap jari"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Ketik untuk menambahkan cap jari"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Gagal menangkap data wajah dgn tepat. Cuba lagi."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Terlalu terang. Cuba pencahayaan yang lebih lembut."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Terlalu gelap. Cuba pencahayaan yang lebih cerah."</string>
@@ -2142,7 +2146,7 @@
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Kandungan ini tidak boleh dikongsi dengan apl peribadi"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Kandungan ini tidak boleh dibuka dengan apl peribadi"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profil kerja dijeda"</string>
- <string name="resolver_switch_on_work" msgid="463709043650610420">"Ketik untuk menghidupkan"</string>
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Ketik untuk menghidupkan profil"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Tiada apl kerja"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Tiada apl peribadi"</string>
<string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Buka dalam <xliff:g id="APP">%s</xliff:g> pada profil peribadi?"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f2e813c90b9c..45773f36cf52 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"အနီးတစ်ဝိုက်ရှိ ဘလူးတုသ်သုံးစက်များကို ရှာဖွေပြီးတွဲချိတ်ရန် အက်ပ်ကိုခွင့်ပြုမည်"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"တွဲချိတ်ထားသော ဘလူးတုသ်စက်များနှင့် ချိတ်ဆက်ခြင်း"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"တွဲချိတ်ထားသော ဘလူးတုသ်သုံးစက်များနှင့် ချိတ်ဆက်ရန် အက်ပ်ကိုခွင့်ပြုမည်"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ဦးစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"အက်ပ်အား ဦစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များဖြစ်သည့် မှတ်ပုံတင်ထားသော အကူအညီများနှင့် သွားလာရာ လမ်းကြောင်းတို့ကို ရယူရန် ခွင့်ပြုသည်။"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communicationအား ထိန်းချုပ်ရန်"</string>
@@ -621,7 +625,7 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"မျက်နှာမှတ် သော့ဖွင့်ခြင်း"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"သင့်မျက်နှာကို စာရင်းပြန်သွင်းပါ"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"ပိုမှတ်မိစေရန် သင့်မျက်နှာကို စာရင်းပြန်သွင်းပါ"</string>
- <string name="face_setup_notification_title" msgid="550617822603450009">"မျက်နှာမှတ်သော့ဖွင့်ခြင်းကို စနစ်ထည့်သွင်းပါ"</string>
+ <string name="face_setup_notification_title" msgid="550617822603450009">"မျက်နှာမှတ် သော့ဖွင့်ခြင်းကို စနစ်ထည့်သွင်းပါ"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"သင့်ဖုန်းကိုကြည့်၍ သော့ဖွင့်ပါ"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"သော့ဖွင့်ရန် နောက်ထပ်နည်းလမ်းများကို စနစ်ထည့်သွင်းပါ"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"လက်ဗွေထည့်ရန် တို့ပါ"</string>
@@ -1029,9 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"မိတ္တူကူးပြီးပါပြီ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> မှ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> သို့ ကူးထည့်ထားသည်"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"ကလစ်ဘုတ်မှ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> သို့ ကူးထည့်ထားသည်"</string>
- <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> က သင်မိတ္တူကူးထားသော စာသားကို ကူးထည့်ထားသည်"</string>
- <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> က သင်မိတ္တူကူးထားသော ပုံကို ကူးထည့်ထားသည်"</string>
- <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> က သင်မိတ္တူကူးထားသော အကြောင်းအရာကို ကူးထည့်ထားသည်"</string>
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> က သင်မိတ္တူကူးထားသော စာသားကို ထည့်လိုက်သည်"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> က သင်မိတ္တူကူးထားသော ပုံကို ထည့်လိုက်သည်"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> က သင်မိတ္တူကူးထားသော အကြောင်းအရာကို ထည့်လိုက်သည်"</string>
<string name="more_item_label" msgid="7419249600215749115">"နောက်ထပ်"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 9921422185e8..a7f40c813096 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lar appen oppdage og koble til Bluetooth-enheter i nærheten"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"koble til tilkoblede Bluetooth-enheter"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lar appen koble til tilkoblede Bluetooth-enheter"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasjon om prioritert NFC-betalingstjeneste"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gir appen tilgang til informasjon om prioritert NFC-betalingstjeneste, for eksempel registrerte hjelpemidler og destinasjon."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontroller overføring av data med NFC-teknologi"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 8d11114e78bb..bbe7c5d8457c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"यो अनुमति दिइएमा एपले नजिकै रहेका ब्लुटुथ चल्ने यन्त्रहरू भेट्टाउन र ती यन्त्रहरूसँग कनेक्ट गर्न सक्छ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"लिंक गरिएका ब्लुटुथ चल्ने यन्त्रहरूसँग कनेक्ट गर्ने"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"यो अनुमति दिइएमा एपले लिंक गरिएका ब्लुटुथ चल्ने यन्त्रहरूसँग कनेक्ट गर्न सक्छ"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC भुक्तानी सेवासम्बन्धी रुचाइएको जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"यसले एपलाई दर्ता गरिएका सहायता तथा मार्गको गन्तव्य जस्ता रुचाइएका NFC भुक्तानी सेवासम्बन्धी जानकारी प्राप्त गर्न दिन्छ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"नजिक क्षेत्र संचार नियन्त्रणहरू"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"फेस अनलक"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"आफ्नो अनुहार पुनः दर्ता गर्नुहोस्"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"अनुहार पहिचानको गुणस्तर सुधार गर्न कृपया आफ्नो अनुहार पुनः दर्ता गर्नुहोस्"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"फेस अनलक सेटअप गर्नुहोस्"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"फोनमा हेरेकै भरमा फोन अनलक गर्नुहोस्"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"अनलक गर्ने अन्य तरिकाहरू सेटअप गर्नुहोस्"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फिंगरप्रिन्ट हाल्न ट्याप गर्नुहोस्"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"अनुहारको सटीक डेटा खिच्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ज्यादै चम्किलो। अझ मधुरो प्रकाश प्रयोग गरी हेर्नु…"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"ज्यादै अँध्यारो छ। अझ बढी प्रकाशमा गई हेर्नुहोस्"</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"प्रतिलिपि गरियो"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> मा रहेको डेटा कपी गरी <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> मा पेस्ट गरियो"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"क्लिपबोर्डमा रहेको डेटा कपी गरी <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> मा पेस्ट गरियो"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ले तपाईंले कपी गरेको टेक्स्ट पेस्ट गरेको छ"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ले तपाईंले कपी गरेको एउटा फोटो पेस्ट गरेको छ"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ले तपाईंले कपी गरेको सामग्री पेस्ट गरेको छ"</string>
<string name="more_item_label" msgid="7419249600215749115">"बढी"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"मेनु+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"काम"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"व्यक्तिगत दृश्य"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"कार्य दृश्य"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"तपाईंका IT एड्मिनले ब्लक गर्नुभएको छ"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"यो सामग्री कामसम्बन्धी एपहरूमार्फत सेयर गर्न मिल्दैन"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"यो सामग्री कामसम्बन्धी एपहरूमार्फत खोल्न मिल्दैन"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"यो सामग्री व्यक्तिगत एपहरूमार्फत सेयर गर्न मिल्दैन"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"यो सामग्री व्यक्तिगत एपहरूमार्फत खोल्न मिल्दैन"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"कार्य प्रोफाइल पज गरिएको छ"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"अन गर्न ट्याप गर्नुहोस्"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"यो सामग्री खोल्न मिल्ने कुनै पनि कामसम्बन्धी एप छैन"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"यो सामग्री खोल्न मिल्ने कुनै पनि व्यक्तिगत एप छैन"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"व्यक्तिगत प्रोफाइल प्रयोग गरी <xliff:g id="APP">%s</xliff:g> मा खोल्ने हो?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"कार्य प्रोफाइल प्रयोग गरी <xliff:g id="APP">%s</xliff:g> मा खोल्ने हो?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"व्यक्तिगत ब्राउजर प्रयोग गर्नुहोस्"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"कार्य ब्राउजर प्रयोग गर्नुहोस्"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM को नेटवर्क अनलक गर्ने PIN"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM को नेटवर्कको सबसेट अनलक गर्ने PIN"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM को कर्पोरेट लक खोल्ने PIN"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"जुम इन गर्ने सुविधासम्बन्धी नयाँ सेटिङ"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"तपाईं अब स्क्रिनको जुनसुकै भाग जुम इन गर्न सक्नुहुन्छ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिङमा गई यो सुविधा अन गर्नुहोस्"</string>
<string name="dismiss_action" msgid="1728820550388704784">"हटाउनुहोस्"</string>
diff --git a/core/res/res/values-night/values.xml b/core/res/res/values-night/values.xml
index 3fd82b874a84..1571fab66a5b 100644
--- a/core/res/res/values-night/values.xml
+++ b/core/res/res/values-night/values.xml
@@ -16,7 +16,7 @@
-->
<resources>
- <style name="Theme.DeviceDefault.QuickSettings" parent="android:Theme.DeviceDefault">
+ <style name="Theme.DeviceDefault.SystemUI" parent="android:Theme.DeviceDefault">
<!-- Color palette -->
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
<item name="colorSecondary">@color/secondary_device_default_settings</item>
@@ -27,5 +27,5 @@
<item name="forceDarkAllowed">false</item>
</style>
- <style name="Theme.DeviceDefault.QuickSettings.Dialog" parent="Theme.DeviceDefault.Dialog" />
+ <style name="Theme.DeviceDefault.SystemUI.Dialog" parent="Theme.DeviceDefault.Dialog" />
</resources> \ No newline at end of file
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index d8507f3bf7ed..800b66ec2d79 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App actief"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps die de batterij gebruiken"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Vergroting"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Toegankelijkheidsgebruik"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruikt de batterij"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps gebruiken de batterij"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tik voor batterij- en datagebruik"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Hiermee kan de app bluetooth-apparaten in de buurt vinden en koppelen"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"verbinding maken met gekoppelde bluetooth-apparaten"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Hiermee kan de app verbinding maken met gekoppelde bluetooth-apparaten"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informatie over voorkeursservice voor NFC-betaling"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Hiermee kun je zorgen dat de app informatie krijgt over de voorkeursservice voor NFC-betaling, zoals geregistreerde hulpmiddelen en routebestemmingen."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication regelen"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Schermvergrendeling gebruiken"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Gedeeltelijke vingerafdruk gedetecteerd"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kan vingerafdruk niet verwerken. Probeer het opnieuw."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Maak de sensor schoon"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Vinger bewoog te snel"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vinger te langzaam bewogen. Probeer het opnieuw."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probeer een andere vingerafdruk"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Te veel licht"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Verplaats je vinger"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk geverifieerd"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gezicht geverifieerd"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gezicht geverifieerd. Druk op Bevestigen."</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware voor vingerafdruk niet beschikbaar."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Kan vingerafdruk niet instellen"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Time-out bereikt voor vingerafdruk. Probeer het opnieuw."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Vingerafdrukbewerking geannuleerd."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Vingerafdrukverificatie geannuleerd door gebruiker."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 44831e304227..e1176a252596 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ଆପ୍‍ ଚାଲୁଛି"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"ଆପ୍‍ଗୁଡ଼ିକ ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କରିଥା\'ନ୍ତି"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ମ୍ୟାଗ୍ନିଫିକେସନ୍"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ଆକ୍ସେସିବିଲିଟୀ ବ୍ୟବହାର"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରୁଛି"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g>ଟି ଆପ୍‍ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରୁଛନ୍ତି"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ବ୍ୟାଟେରୀ ଏବଂ ଡାଟା ବ୍ୟବହାର ଉପରେ ବିବରଣୀ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ଆଖପାଖର ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକୁ ଖୋଜି ପେୟାର୍ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ପେୟାର୍ କରାଯାଇଥିବା ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକ ସହ ସଂଯୋଗ କର"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ପେୟାର୍ କରାଯାଇଥିବା ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକ ସହ ସଂଯୋଗ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ପସନ୍ଦର NFC ପେମେଣ୍ଟ ସେବା ସୂଚନା"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ପଞ୍ଜିକୃତ ଯନ୍ତ୍ର ଏବଂ ମାର୍ଗ ଲକ୍ଷସ୍ଥଳ ପରି ପସନ୍ଦର nfc ପେମେଣ୍ଟ ସେବା ସୂଚନା ପାଇବାକୁ ଆପ୍ ଅନୁମତି କରିଥାଏ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ନିଅର୍ ଫିଲ୍ଡ କମ୍ୟୁନିକେଶନ୍ ଉପରେ ନିୟନ୍ତ୍ରଣ ରଖନ୍ତୁ"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ଆଂଶିକ ଟିପଚିହ୍ନ ଚିହ୍ନଟ କରାଯାଇଛି"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ଟିପଚିହ୍ନ ପ୍ରୋସେସ୍‍ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"ସେନ୍ସରକୁ ସଫା କରନ୍ତୁ"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"ଆଙ୍ଗୁଠିକୁ ବହୁତ ଶୀଘ୍ର ମୁଭ୍ କରାଯାଇଛି"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ଆଙ୍ଗୁଠି ଖୁବ୍‍ ଧୀରେ ନିଆଗଲା। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ଅନ୍ୟ ଏକ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ବହୁତ ଉଜ୍ଜ୍ୱଳ"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ଆଡଜଷ୍ଟ କରି ଦେଖନ୍ତୁ"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"ଟିପଚିହ୍ନ ପ୍ରମାଣିତ ହେଲା"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ମୁହଁ ଚିହ୍ନଟ ହୋଇଛି"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ମୁହଁ ଚିହ୍ନଟ ହୋଇଛି, ଦୟାକରି ସୁନିଶ୍ଚିତ ଦବାନ୍ତୁ"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ଟିପଚିହ୍ନ ହାର୍ଡୱେର୍‍ ଉପଲବ୍ଧ ନାହିଁ।"</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ଟିପଚିହ୍ନକୁ ସେଟ୍ ଅପ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"ଟିପଚିହ୍ନର ସମୟ ଶେଷ ହେଲା । ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"ଟିପଚିହ୍ନ କାର୍ଯ୍ୟ ବାତିଲ୍ କରାଗଲା।"</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ଉପଯୋଗକର୍ତ୍ତା ଟିପଚିହ୍ନ କାର୍ଯ୍ୟ ବାତିଲ୍ କରିଛନ୍ତି।"</string>
@@ -1323,7 +1319,7 @@
<item msgid="9177085807664964627">"VPN"</item>
</string-array>
<string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ଏକ ଅଜଣା ନେଟ୍‌ୱର୍କ ପ୍ରକାର"</string>
- <string name="accept" msgid="5447154347815825107">"ସ୍ୱୀକାର କରନ୍ତୁ"</string>
+ <string name="accept" msgid="5447154347815825107">"ଗ୍ରହଣ କରନ୍ତୁ"</string>
<string name="decline" msgid="6490507610282145874">"ପ୍ରତ୍ୟାଖ୍ୟାନ"</string>
<string name="select_character" msgid="3352797107930786979">"ବର୍ଣ୍ଣ ଲେଖନ୍ତୁ"</string>
<string name="sms_control_title" msgid="4748684259903148341">"SMS ମେସେଜ୍‌ଗୁଡ଼ିକୁ ପଠାଯାଉଛି"</string>
@@ -2145,8 +2141,8 @@
<string name="resolver_switch_on_work" msgid="463709043650610420">"ଚାଲୁ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"କୌଣସି ୱାର୍କ ଆପ୍ ନାହିଁ"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"କୌଣସି ବ୍ୟକ୍ତିଗତ ଆପ୍ ନାହିଁ"</string>
- <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲରେ <xliff:g id="APP">%s</xliff:g>ରେ ଖୋଲିବେ?"</string>
- <string name="miniresolver_open_in_work" msgid="152208044699347924">"ୱାର୍କ ପ୍ରୋଫାଇଲରେ <xliff:g id="APP">%s</xliff:g>ରେ ଖୋଲିବେ?"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲକୁ <xliff:g id="APP">%s</xliff:g>ରେ ଖୋଲିବେ?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ <xliff:g id="APP">%s</xliff:g>ରେ ଖୋଲିବେ?"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ବ୍ୟକ୍ତିଗତ ବ୍ରାଉଜର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"ୱାର୍କ ବ୍ରାଉଜର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ନେଟୱାର୍କ ଅନଲକ୍ PIN"</string>
@@ -2262,8 +2258,7 @@
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
<string name="window_magnification_prompt_title" msgid="2876703640772778215">"ନୂଆ ମ୍ୟାଗ୍ନିଫିକେସନ୍ ସେଟିଂସ୍"</string>
- <!-- no translation found for window_magnification_prompt_content (8159173903032344891) -->
- <skip />
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"ଆପଣ ଏବେ ଆପଣଙ୍କ ସ୍କ୍ରିନର ଅଂଶକୁ ମ୍ୟାଗ୍ନିଫାଏ କରିପାରିବେ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ସେଟିଂସରେ ଚାଲୁ କରନ୍ତୁ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ଜାରି ରଖିବାକୁ, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ଆପଣଙ୍କ ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଆକ୍ସେସ୍ ଆବଶ୍ୟକ କରେ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 918753a05105..f2d9bfd71328 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਜੋੜਾਬੱਧ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ਜੋੜਾਬੱਧ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ਐਪਾਂ ਨੂੰ ਜੋੜਾਬੱਧ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ਐਪ ਨੂੰ ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਕਿ ਰਜਿਸਟਰ ਕੀਤੇ ਸਾਧਨ ਅਤੇ ਮੰਜ਼ਿਲ ਰਸਤਾ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"ਚਿਹਰਾ ਅਣਲਾਕ"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ਆਪਣਾ ਚਿਹਰਾ ਮੁੜ-ਦਰਜ ਕਰੋ"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"ਪਛਾਣ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਚਿਹਰੇ ਨੂੰ ਮੁੜ-ਦਰਜ ਕਰੋ"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"ਚਿਹਰਾ ਅਣਲਾਕ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"ਆਪਣੇ ਫ਼ੋਨ ਵੱਲ ਦੇਖ ਕੇ ਇਸਨੂੰ ਅਣਲਾਕ ਕਰੋ"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ਅਣਲਾਕ ਕਰਨ ਦੇ ਹੋਰ ਤਰੀਕਿਆਂ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"ਸਟੀਕ ਚਿਹਰਾ ਡਾਟਾ ਕੈਪਚਰ ਨਹੀਂ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਚਮਕ। ਹਲਕੀ ਚਮਕ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"ਬਹੁਤ ਗੂੜ੍ਹਾ। ਤੇਜ਼ ਰੋਸ਼ਨੀ ਕਰਕੇ ਦੇਖੋ।"</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"ਕਾਪੀ ਕੀਤੀ ਗਈ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ਤੋਂ ਕਾਪੀ ਕੀਤੇ ਡਾਟੇ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਪੇਸਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"ਕਲਿੱਪਬੋਰਡ ਦੇ ਡਾਟੇ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਪੇਸਟ ਕੀਤਾ ਗਿਆ"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਾਪੀ ਕੀਤੀ ਗਈ ਲਿਖਤ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਨੇ ਪੇਸਟ ਕੀਤਾ"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਾਪੀ ਕੀਤੇ ਗਏ ਚਿੱਤਰ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਨੇ ਪੇਸਟ ਕੀਤਾ"</string>
+ <string name="pasted_content" msgid="646276353060777131">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਾਪੀ ਕੀਤੀ ਗਈ ਸਮੱਗਰੀ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਨੇ ਪੇਸਟ ਕੀਤਾ"</string>
<string name="more_item_label" msgid="7419249600215749115">"ਹੋਰ"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"ਮੀਨੂ+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"ਕੰਮ"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"ਵਿਅਕਤੀਗਤ ਦ੍ਰਿਸ਼"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"ਕਾਰਜ ਦ੍ਰਿਸ਼"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਬਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨਾਲ ਸਾਂਝਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨਾਲ ਨਹੀਂ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਨਿੱਜੀ ਐਪਾਂ ਨਾਲ ਸਾਂਝਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਨਿੱਜੀ ਐਪਾਂ ਨਾਲ ਨਹੀਂ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਨੂੰ ਰੋਕਿਆ ਗਿਆ ਹੈ"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"ਚਾਲੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ਕੋਈ ਕੰਮ ਸੰਬੰਧੀ ਐਪ ਨਹੀਂ"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ਕੋਈ ਨਿੱਜੀ ਐਪ ਨਹੀਂ"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"ਕੀ ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ <xliff:g id="APP">%s</xliff:g> ਵਿੱਚ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"ਕੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ <xliff:g id="APP">%s</xliff:g> ਵਿੱਚ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ਨਿੱਜੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ਕੰਮ ਸੰਬੰਧੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ਸਿਮ ਨੈੱਟਵਰਕ ਅਣਲਾਕ ਪਿੰਨ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ਸਿਮ ਨੈੱਟਵਰਕ ਸਬਸੈੱਟ ਅਣਲਾਕ ਪਿੰਨ"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ਸਿਮ ਕਾਰਪੋਰੇਟ ਅਣਲਾਕ ਪਿੰਨ"</string>
@@ -2280,10 +2265,8 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
- <!-- no translation found for window_magnification_prompt_content (8159173903032344891) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"ਨਵੀਆਂ ਵੱਡਦਰਸ਼ੀਕਰਨ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"ਹੁਣ ਤੁਸੀਂ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦਾ ਕੁਝ ਹਿੱਸਾ ਵੱਡਦਰਸ਼ੀ ਕਰ ਸਕਦੇ ਹੋ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਾਲੂ ਕਰੋ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ਖਾਰਜ ਕਰੋ"</string>
<string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ਜਾਰੀ ਰੱਖਣ ਲਈ, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 60f395d2d8e5..78e13261e698 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -545,6 +545,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Zezwala na wykrywanie i parowanie przez aplikację urządzeń Bluetooth w pobliżu"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"łączenie ze sparowanymi urządzeniami Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Zezwala na łączenie aplikacji ze sparowanymi urządzeniami Bluetooth"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacje o preferowanych usługach płatniczych NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pozwala aplikacji uzyskiwać informacje o preferowanych usługach płatniczych NFC, np. zarejestrowanych pomocach i miejscach docelowych tras."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolowanie łączności Near Field Communication"</string>
@@ -627,14 +631,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Rozpoznawanie twarzy"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Zarejestruj swoją twarz ponownie"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Aby poprawić rozpoznawanie, ponownie zarejestruj swoją twarz"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Skonfiguruj rozpoznawanie twarzy"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Popatrz na ekran telefonu, aby go odblokować"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Skonfiguruj więcej sposobów odblokowywania"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Kliknij, aby dodać odcisk palca"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Nie udało się zarejestrować danych twarzy. Spróbuj ponownie."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Zbyt jasno. Spróbuj przy słabszym świetle."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Zbyt ciemno. Spróbuj w jaśniejszym świetle."</string>
@@ -1039,12 +1039,9 @@
<string name="copied" msgid="4675902854553014676">"Skopiowano"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła dane z aplikacji <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła dane ze schowka"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła skopiowany tekst"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła skopiowany obraz"</string>
+ <string name="pasted_content" msgid="646276353060777131">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła skopiowane treści"</string>
<string name="more_item_label" msgid="7419249600215749115">"Więcej"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2211,31 +2208,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Służbowe"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Widok osobisty"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Widok służbowy"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Działanie zablokowane przez administratora IT"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Tych treści nie można udostępniać w aplikacjach służbowych"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Tych treści nie można otworzyć w aplikacjach służbowych"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Tych treści nie można udostępniać w aplikacjach osobistych"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Tych treści nie można otworzyć w aplikacjach osobistych"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Działanie profilu służbowego jest wstrzymane"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Kliknij, aby włączyć"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Brak aplikacji służbowych"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Brak aplikacji osobistych"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Otworzyć w aplikacji <xliff:g id="APP">%s</xliff:g> w profilu osobistym?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"Otworzyć w aplikacji <xliff:g id="APP">%s</xliff:g> w profilu służbowym?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Użyj przeglądarki osobistej"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Użyj przeglądarki służbowej"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Kod PIN do karty SIM odblokowujący sieć"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Kod PIN odblokowujący podzbiór sieci na karcie SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Kod PIN odblokowujący dane korporacyjne na karcie SIM"</string>
@@ -2348,8 +2333,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nowe ustawienia powiększenia"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Możesz teraz powiększyć część ekranu"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Włącz w Ustawieniach"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Odrzuć"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index a65056de43b2..ab52b2607be1 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App em execução"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que estão consumindo a bateria"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliação"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uso de acessibilidade"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão consumindo a bateria"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que o app descubra e se pareie a dispositivos Bluetooth por perto"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conecte-se a dispositivos Bluetooth pareados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que o app se conecte a dispositivos Bluetooth pareados"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impressão digital parcial detectada"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Limpe o sensor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"O dedo se moveu rápido demais"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"O movimento do dedo está muito lento. Tente novamente."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ajuste a posição do dedo"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não foi possível configurar a impressão digital"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo usuário."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index f92481c25e88..b1ddb54f1f9e 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que a app descubra e sincronize com dispositivos Bluetooth próximos"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ligar-se a dispositivos Bluetooth sincronizados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que a app se ligue a dispositivos Bluetooth sincronizados"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações de serviços de pagamento com NFC preferenciais"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a app obtenha informações de serviços de pagamento com NFC preferenciais, como apoios registados e destino da rota."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlo Near Field Communication"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a65056de43b2..ab52b2607be1 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App em execução"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que estão consumindo a bateria"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliação"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uso de acessibilidade"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão consumindo a bateria"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que o app descubra e se pareie a dispositivos Bluetooth por perto"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conecte-se a dispositivos Bluetooth pareados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que o app se conecte a dispositivos Bluetooth pareados"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impressão digital parcial detectada"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Limpe o sensor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"O dedo se moveu rápido demais"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"O movimento do dedo está muito lento. Tente novamente."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ajuste a posição do dedo"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não foi possível configurar a impressão digital"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo usuário."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 0f4005abb478..38171d2d8e9e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -542,6 +542,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite aplicației să descopere și să asocieze dispozitive Bluetooth din apropiere"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"să se conecteze la dispozitive Bluetooth asociate"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite aplicației să se conecteze la dispozitive Bluetooth asociate"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informații despre serviciul de plăți NFC preferat"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite aplicației să obțină informații despre serviciul de plăți NFC preferat, de exemplu, identificatorii de aplicație înregistrați și destinația traseului."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlare schimb de date prin Near Field Communication"</string>
@@ -624,14 +628,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Deblocare facială"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Reînregistrați-vă chipul"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Pentru a îmbunătăți recunoașterea, reînregistrați-vă chipul"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Configurați deblocarea facială"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Deblocați-vă telefonul uitându-vă la acesta"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurați mai multe moduri de deblocare"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Atingeți ca să adăugați o amprentă"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Nu s-a putut fotografia fața cu precizie. Încercați din nou."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Prea luminos. Încercați o lumină mai slabă."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Prea întunecat. Încercați o lumină mai puternică."</string>
@@ -1036,12 +1036,9 @@
<string name="copied" msgid="4675902854553014676">"Copiat"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat date din <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat date din clipboard"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat textul copiat"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat o imagine copiată"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat conținutul copiat"</string>
<string name="more_item_label" msgid="7419249600215749115">"Mai multe"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Meniu+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2177,31 +2174,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Serviciu"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Afișarea conținutului personal"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Afișarea conținutului de lucru"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Blocat de administratorul IT"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Acest conținut nu poate fi trimis cu aplicații pentru lucru"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Acest conținut nu poate fi deschis cu aplicații pentru lucru"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Acest conținut nu poate fi trimis cu aplicații personale"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Acest conținut nu poate fi deschis cu aplicații personale"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profilul de serviciu este întrerupt"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Atingeți pentru a activa"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nicio aplicație pentru lucru"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nicio aplicație personală"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Deschideți în <xliff:g id="APP">%s</xliff:g> în profilul personal?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"Deschideți în <xliff:g id="APP">%s</xliff:g> în profilul de serviciu?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Folosiți browserul personal"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Folosiți browserul de serviciu"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Codul PIN de deblocare SIM privind rețeaua"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Codul PIN de deblocare SIM privind subsetul de rețea"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Codul PIN de deblocare SIM corporativă"</string>
@@ -2314,8 +2299,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Noi setări de mărire"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Acum puteți mări o parte a ecranului"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activați din Setări"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Respingeți"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d015f3089787..022dfc49bfd7 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -545,6 +545,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Приложение сможет находить устройства Bluetooth поблизости и подключаться к ним."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"доступ к подключенным устройствам Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"У приложения будет доступ к подключенным устройствам Bluetooth."</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сведения о предпочтительном платежном сервисе NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Приложение сможет получать сведения о предпочтительном платежном сервисе NFC (например, зарегистрированные идентификаторы AID и конечный пункт маршрута)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Управление NFC-модулем"</string>
@@ -627,14 +631,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Фейсконтроль"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Зарегистрируйте лицо ещё раз"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Чтобы улучшить распознавание лица, зарегистрируйте его ещё раз"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Настройте фейсконтроль"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Вы сможете разблокировать телефон, просто посмотрев на него."</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Настройте другие способы разблокировки"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Нажмите, чтобы добавить отпечаток пальца."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Не удалось собрать данные. Повторите попытку."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Слишком светло. Сделайте освещение менее ярким."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Слишком темно. Сделайте освещение ярче."</string>
@@ -1039,12 +1039,9 @@
<string name="copied" msgid="4675902854553014676">"Скопировано"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Данные из приложения \"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>\" вставлены в приложение \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\"."</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"Данные из буфера обмена вставлены в приложение \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\"."</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>: скопированный текст вставлен"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>: скопированное изображение вставлено"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>: скопированный контент вставлен"</string>
<string name="more_item_label" msgid="7419249600215749115">"Ещё"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -2211,31 +2208,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Рабочее"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Просмотр личных данных"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Просмотр рабочих данных"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Заблокировано вашим администратором"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Этот контент нельзя открывать через рабочие приложения."</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Этот контент нельзя открыть в рабочем приложении."</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Этот контент нельзя открывать через личные приложения."</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Этот контент нельзя открыть в личном приложении."</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Действие рабочего профиля приостановлено."</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Нажмите, чтобы включить"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Не поддерживается рабочими приложениями."</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Не поддерживается личными приложениями."</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Посмотреть на <xliff:g id="APP">%s</xliff:g> в личном профиле?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"Посмотреть на <xliff:g id="APP">%s</xliff:g> в рабочем профиле?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Использовать личный браузер"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Использовать рабочий браузер"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-код для разблокировки сети SIM-карты"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN-код для разблокировки подмножества сети SIM-карты"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN-код для разблокировки корпоративной SIM-карты"</string>
@@ -2348,8 +2333,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Новые настройки увеличения"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Теперь можно увеличивать часть экрана."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Включить в настройках"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Закрыть"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 0f54b2020a11..3676f629bff6 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"යෙදුම ධාවනය කරමින්"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"බැටරිය භාවිත කරන යෙදුම්"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"විශාලනය"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ප්‍රවේශ්‍යතා භාවිතය"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> බැටරිය භාවිත කරයි"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"යෙදුම් <xliff:g id="NUMBER">%1$d</xliff:g>ක් බැටරිය භාවිත කරයි"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"අව‍ට ඇති බ්ලූටූත් උපාංග සොයා ගැනීමට සහ යුගල කිරීමට යෙදුමට ඉඩ දෙයි"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"යුගල කළ බ්ලූටූත් උපාංගවලට සම්බන්ධ වන්න"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"යුගල කළ බ්ලූටූත් උපාංග සමඟ සම්බන්ධ වීමට යෙදුමට ඉඩ දෙයි"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"කැමති NFC ගෙවීම් සේවා තොරතුරු"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ලියාපදිංචි කළ ආධාර සහ ගමන් මාර්ග ගමනාන්ත වැනි කැමති nfc ගෙවීම් සේවා තොරතුරු ලබා ගැනීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ආසන්න ක්ෂේත්‍ර සන්නිවේදනය පාලනය කරන්න"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"තිර අගුල භාවිත කරන්න"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"අර්ධ ඇඟිලි සලකුණක් අනාවරණය කරන ලදි"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ඇඟිලි සලකුණ පිරිසැකසීමට නොහැකි විය. කරුණාකර නැවත උත්සාහ කරන්න."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"සංවේදකය පිරිසිදු කරන්න"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"ඇඟිල්ල වඩා වේගයෙන් ගෙන යන ලදි"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ඇඟිල්ල වඩා සෙමෙන් ගෙන යන ලදි. කරුණාකර නැවත උත්සාහ කරන්න."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"තවත් ඇඟිලි සලකුණක් උත්සාහ කරන්න"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"දීප්තිය වැඩියි"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"සීරුමාරු කිරීම උත්සාහ කරන්න"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"ඇඟිලි සලකුණ සත්‍යාපනය කරන ලදී"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"මුහුණ සත්‍යාපනය කරන ලදී"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"මුහුණ සත්‍යාපනය කරන ලදී, කරුණාකර තහවුරු කරන්න ඔබන්න"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ඇඟිලි සලකුණු දෘඪාංගය ලද නොහැකිය."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ඇඟිලි සලකුණ පිහිටුවිය නොහැකිය"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"ඇඟිලි සලකුණු කාල නිමාව ළඟා විය. නැවත උත්සාහ කරන්න."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"ඇඟිලි සලකුණු මෙහෙයුම අවලංගු කරන ලදී."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"පරිශීලක විසින් ඇඟිලි සලකුණු මෙහෙයුම අවසන් කරන ලදී."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index af1566e90ec9..ba0199ad3d3a 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -300,8 +300,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikácia je spustená"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikácie spotrebúvajúce batériu"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Zväčšenie"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Využitie dostupnosti"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> používa batériu"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Aplikácie (<xliff:g id="NUMBER">%1$d</xliff:g>) používajú batériu"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
@@ -545,6 +544,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Umožňuje aplikácii objaviť zariadenia s rozhraním Bluetooth nablízku a spárovať sa s nimi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"pripojiť sa k spárovaným zariadeniam Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Umožňuje aplikácii pripojiť sa k spárovaným zariadeniam s rozhraním Bluetooth"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferované informácie platenej služby NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikácii získavať preferované informácie platenej služby NFC, napríklad o registrovanej pomoci a trasách k cieľu."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ovládať technológiu NFC"</string>
@@ -581,28 +584,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použiť zámku obrazovky"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Bol rozpoznaný čiastočný odtlačok prsta"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Odtlačok prsta sa nepodarilo spracovať. Skúste to znova."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Vyčistite senzor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Prst ste posúvali príliš rýchlo"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pohli ste prstom príliš pomaly. Skúste to znova."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Vyskúšajte iný odtlačok prsta"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Príliš jasno"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Vyskúšajte upraviť"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Odtlačok prsta bol overený"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Tvár bola overená"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Tvár bola overená, stlačte tlačidlo potvrdenia"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardvér na snímanie odtlačku prsta nie je k dispozícii"</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Odtlačok prsta sa nedá nastaviť"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Časový limit rozpoznania odtlačku prsta vypršal. Skúste to znova."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Operácia týkajúca sa odtlačku prsta bola zrušená"</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Overenie odtlačku prsta zrušil používateľ."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 4752a7467566..c8b96cb036f3 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -300,8 +300,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikacija se izvaja"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije, ki porabljajo energijo baterije"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Povečava"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uporaba funkcij za ljudi s posebnimi potrebami"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> porablja energijo baterije"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Toliko aplikacij porablja energijo baterije: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dotaknite se za prikaz podrobnosti porabe baterije in prenosa podatkov"</string>
@@ -545,6 +544,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Aplikaciji omogoča odkrivanje naprav Bluetooth v bližini in seznanjanje z njimi."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezovanje s seznanjenimi napravami Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Aplikaciji omogoča povezovanje s seznanjenimi napravami Bluetooth."</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Podatki o prednostni storitvi za plačevanje prek povezave NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikaciji omogoča pridobivanje podatkov o prednostni storitvi za plačevanje prek povezave NFC, kot so registrirani pripomočki in cilj preusmeritve."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"nadzor nad komunikacijo s tehnologijo bližnjega polja"</string>
@@ -581,28 +584,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Uporaba odklepanja s poverilnico"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Zaznan je delni prstni odtis."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Prstnega odtisa ni bilo mogoče obdelati. Poskusite znova."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Očistite tipalo."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Prehitro ste odmaknili prst."</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Prepočasen premik prsta. Poskusite znova."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Poskusite z drugim prstnim odtisom."</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvetlo je."</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Poskusite popraviti položaj prsta."</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Pristnost prstnega odtisa je preverjena"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Pristnost obraza je potrjena"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Pristnost obraza je preverjena. Pritisnite gumb »Potrdi«."</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Strojna oprema za prstne odtise ni na voljo."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Prstnega odtisa ni mogoče nastaviti."</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Dosežena časovna omejitev za prstni odtis. Poskusite znova."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Dejanje s prstnim odtisom je bilo preklicano."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Dejanje s prstnim odtisom je preklical uporabnik."</string>
@@ -627,14 +623,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Odklepanje z obrazom"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Znova registrirajte obraz"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"Za izboljšanje prepoznavanja znova registrirajte svoj obraz"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"Nastavite odklepanje z obrazom"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Odklenite telefon tako, da ga pogledate."</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Nastavite več načinov odklepanja"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Dotaknite se, da dodate prstni odtis."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Točnih podatkov o obrazu ni bilo mogoče zajeti. Poskusite znova."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"Presvetlo. Poskusite z blažjo osvetlitvijo."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"Pretemno. Poskusite z močnejšo osvetlitvijo."</string>
@@ -1039,12 +1031,9 @@
<string name="copied" msgid="4675902854553014676">"Kopirano"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>."</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila iz odložišča."</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila besedilo iz odložišča."</string>
+ <string name="pasted_image" msgid="4729097394781491022">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila sliko iz odložišča."</string>
+ <string name="pasted_content" msgid="646276353060777131">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila vsebino iz odložišča."</string>
<string name="more_item_label" msgid="7419249600215749115">"Več"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Meni+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -2211,31 +2200,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Služba"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Pogled osebnega profila"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Pogled delovnega profila"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Blokiral skrbnik za IT"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Te vsebine ni mogoče deliti z delovnimi aplikacijami."</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Te vsebine ni mogoče odpreti z delovnimi aplikacijami."</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Te vsebine ni mogoče deliti z osebnimi aplikacijami."</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Te vsebine ni mogoče odpreti z osebnimi aplikacijami."</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Delovni profil je začasno zaustavljen"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Dotaknite se za vklop"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nobena delovna aplikacija"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nobena osebna aplikacija"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Želite odpreti v aplikaciji <xliff:g id="APP">%s</xliff:g> v osebnem profilu?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"Želite odpreti v aplikaciji <xliff:g id="APP">%s</xliff:g> v delovnem profilu?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Uporabi osebni brskalnik"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Uporabi delovni brskalnik"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Koda PIN za odklepanje omrežja kartice SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Koda PIN za odklepanje podnabora omrežja kartice SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Koda PIN za odklepanje kartice SIM za podjetje"</string>
@@ -2348,8 +2325,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nove nastavitve povečave"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Zdaj lahko povečate samo del zaslona."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Vklopite v nastavitvah"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Opusti"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 1044f21b7e0f..0816ab625b7c 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lejon që aplikacioni të zbulojë dhe të çiftohet me pajisjet me Bluetooth në afërsi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"të lidhet me pajisjet e çiftuara me Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lejon që aplikacioni të lidhet me pajisjet e çiftuara me Bluetooth"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacionet për shërbimin e preferuar të pagesës me NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lejon aplikacionin të marrë informacione për shërbimin e preferuar të pagesës me NFC si p.sh. ndihmat e regjistruara dhe destinacionin e itinerarit."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollo \"Komunikimin e fushës në afërsi\" NFC"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 99e909c76aa2..b73c4aead841 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -542,6 +542,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозвољава апликацији да открива Bluetooth уређаје у близини и упарује се са њима"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"повезивање са упареним Bluetooth уређајима"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозвољава апликацији да се повезује са упареним Bluetooth уређајима"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информације о жељеној NFC услузи за плаћање"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозвољава апликацији да преузима информације о жељеној NFC услузи за плаћање, попут регистрованих идентификатора апликација и одредишта преусмеравања."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контрола комуникације у ужем пољу (Near Field Communication)"</string>
@@ -1493,7 +1497,7 @@
<string name="ime_action_previous" msgid="6548799326860401611">"Претходно"</string>
<string name="ime_action_default" msgid="8265027027659800121">"Изврши"</string>
<string name="dial_number_using" msgid="6060769078933953531">"Бирај број\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <string name="create_contact_using" msgid="6200708808003692594">"Креирајте контакт\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="create_contact_using" msgid="6200708808003692594">"Направите контакт\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Следеће апликације захтевају дозволу за приступ налогу, како сада, тако и убудуће."</string>
<string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Желите да одобрите овај захтев?"</string>
<string name="grant_permissions_header_text" msgid="3420736827804657201">"Захтев за приступ"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c7a91f7dfa40..0f3bb6440bcb 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Tillåter appen att hitta och parkoppla Bluetooth-enheter i närheten"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ansluta till parkopplade Bluetooth-enheter"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Tillåter appen att ansluta till parkopplade Bluetooth-enheter"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information kopplad till standardtjänsten för NFC-betalning"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillåter att appen hämtar information kopplad till standardtjänsten för NFC-betalning, till exempel registrerade hjälpmedel och ruttdestinationer."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollera närfältskommunikationen"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 728c4a604d9a..5c68c6b496c5 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Huruhusu programu itambue na kuoanisha kwenye vifaa vyenye Bluetooth vilivyo karibu"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"kuunganisha kwenye vifaa vyenye Bluetooth vilivyooanishwa"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Huruhusu programu iunganishe kwenye vifaa vyenye Bluetooth vilivyooanishwa"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maelezo ya Huduma Inayopendelewa ya Malipo ya NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Huruhusu programu kupata maelezo ya huduma inayopendelewa ya malipo ya nfc kama vile huduma zilizosajiliwa na njia."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kudhibiti Mawasiliano ya Vifaa Vilivyokaribu (NFC)"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index d0e2b34c7021..c6e86f5c24d6 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"அருகிலுள்ள புளூடூத் சாதனங்களைக் கண்டறிந்து அவற்றுடன் இணைவதற்கு ஆப்ஸை அனுமதிக்கும்"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"இணைக்கப்பட்ட புளூடூத் சாதனங்களுடன் இணைத்தல்"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"இணைக்கப்பட்ட புளூடூத் சாதனங்களுடன் இணைவதற்கு ஆப்ஸை அனுமதிக்கும்"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்கள்"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"பதிவுசெய்யப்பட்ட கருவிகள், சேருமிடத்திற்கான வழி போன்ற விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"குறுகிய இடைவெளி தகவல்பரிமாற்றத்தைக் கட்டுப்படுத்துதல்"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"முகம் காட்டித் திறத்தல்"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"முகத்தை மீண்டும் பதிவுசெய்யவும்"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"அடையாளத்தை மேம்படுத்த முகத்தை மீண்டும் பதிவுசெய்யவும்"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"முகம் காட்டித் திறத்தலை அமையுங்கள்"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"மொபைலைப் பார்ப்பதன் மூலம் அதைத் திறக்கலாம்"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"திறக்க, மேலும் பல வழிகளை அமையுங்கள்"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"கைரேகையைச் சேர்க்கத் தட்டுங்கள்"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"முகம் தெளிவாகப் பதிவாகவில்லை. மீண்டும் முயலவும்."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"அதிக ஒளிர்வு. மிதமான ஒளியில் முயலவும்."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"இருட்டாக உள்ளது. பிரகாசமான ஒளியில் முயலவும்."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"நகலெடுக்கப்பட்டது"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ஆப்ஸிலிருந்து <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஒட்டப்பட்டது"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"கிளிப்போர்டிலிருந்து <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஒட்டப்பட்டது"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"நீங்கள் நகலெடுத்த உரையை <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒட்டியது"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"நீங்கள் நகலெடுத்த படத்தை <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒட்டியது"</string>
+ <string name="pasted_content" msgid="646276353060777131">"நீங்கள் நகலெடுத்த உள்ளடக்கத்தை <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒட்டியது"</string>
<string name="more_item_label" msgid="7419249600215749115">"மேலும்"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"மெனு+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"மெட்டா மற்றும்"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"பணிச் சுயவிவரம்"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"தனிப்பட்ட காட்சி"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"பணிக் காட்சி"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"இதை உங்கள் IT நிர்வாகி தடைசெய்துள்ளார்"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"பணி ஆப்ஸுடன் இந்த உள்ளடக்கத்தைப் பகிர முடியாது"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"பணி ஆப்ஸ் மூலம் இந்த உள்ளடக்கத்தைத் திறக்க முடியாது"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"தனிப்பட்ட ஆப்ஸுடன் இந்த உள்ளடக்கத்தைப் பகிர முடியாது"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"தனிப்பட்ட ஆப்ஸ் மூலம் இந்த உள்ளடக்கத்தைத் திறக்க முடியாது"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"பணிக் கணக்கு இடைநிறுத்தப்பட்டுள்ளது"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"ஆன் செய்யத் தட்டுக"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"பணி ஆப்ஸ் எதுவுமில்லை"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"தனிப்பட்ட ஆப்ஸ் எதுவுமில்லை"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"தனிப்பட்ட கணக்கிலுள்ள <xliff:g id="APP">%s</xliff:g> ஆப்ஸில் திறக்கவா?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"பணிக் கணக்கிலுள்ள <xliff:g id="APP">%s</xliff:g> ஆப்ஸில் திறக்கவா?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"தனிப்பட்ட உலாவியைப் பயன்படுத்து"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"பணி உலாவியைப் பயன்படுத்து"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"சிம் நெட்வொர்க் அன்லாக் பின்"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"சிம் நெட்வொர்க் சப்செட் அன்லாக் பின்"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"கார்ப்பரேட் அன்லாக் பின்"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"பெரிதாக்கலுக்கான புதிய அமைப்புகள்"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"இப்போது உங்கள் திரையின் ஒரு பகுதியைப் பெரிதாக்கலாம்"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"அமைப்புகளில் ஆன் செய்க"</string>
<string name="dismiss_action" msgid="1728820550388704784">"மூடுக"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 91f766e61769..2503c152f80e 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"సమీపంలోని బ్లూటూత్ పరికరాలను కనుగొనడానికి, పెయిర్ చేయడానికి యాప్‌ను అనుమతిస్తుంది"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"పెయిర్ చేసిన బ్లూటూత్ పరికరాలకు కనెక్ట్ అవ్వండి"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"పెయిర్ చేసిన బ్లూటూత్ పరికరాలకు కనెక్ట్ అవ్వడానికి యాప్‌ను అనుమతిస్తుంది"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారం"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారాన్ని, అంటే రిజిస్టర్ చేయబడిన సహాయక సాధనాలు, మార్గం, గమ్యస్థానం వంటి వాటిని పొందేందుకు యాప్‌ను అనుమతిస్తుంది."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"సమీప క్షేత్ర కమ్యూనికేషన్‌ను నియంత్రించడం"</string>
@@ -621,14 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"ఫేస్ అన్‌లాక్"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"మీ ముఖాన్ని తిరిగి నమోదు చేయండి"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"గుర్తింపును మెరుగుపరచడానికి, దయచేసి మీ ముఖంను తిరిగి నమోదు చేసుకోండి"</string>
- <!-- no translation found for face_setup_notification_title (550617822603450009) -->
- <skip />
- <!-- no translation found for face_setup_notification_content (5463999831057751676) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_title (2002630611398849495) -->
- <skip />
- <!-- no translation found for fingerprint_setup_notification_content (205578121848324852) -->
- <skip />
+ <string name="face_setup_notification_title" msgid="550617822603450009">"ఫేస్ అన్‌లాక్‌ను సెటప్ చేయండి"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"మీ ఫోన్‌ను చూడటం ద్వారా దాన్ని అన్‌లాక్ చేయండి"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"అన్‌లాక్ చేయడానికి మరిన్ని మార్గాలను సెటప్ చేయండి"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"వేలిముద్రను జోడించడానికి ట్యాప్ చేయండి"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"ముఖం డేటా సరిగ్గా రాలేదు. మళ్లీ ప్రయత్నించండి."</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"వెలుతురు అధికంగా ఉంది. తక్కువ ఉండేలా చూడండి."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"చాలా చీకటిగా ఉంది. బాగా వెలుతురులో ప్రయత్నించండి."</string>
@@ -1033,12 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"కాపీ చేయబడింది"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> నుండి పేస్ట్ చేయబడింది"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> క్లిప్‌బోర్డ్ నుండి పేస్ట్ చేయబడింది"</string>
- <!-- no translation found for pasted_text (4298871641549173733) -->
- <skip />
- <!-- no translation found for pasted_image (4729097394781491022) -->
- <skip />
- <!-- no translation found for pasted_content (646276353060777131) -->
- <skip />
+ <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> మీరు కాపీ చేసిన టెక్స్ట్‌ను పేస్ట్ చేసింది"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> మీరు కాపీ చేసిన ఇమేజ్‌ను పేస్ట్ చేసింది"</string>
+ <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> మీరు కాపీ చేసిన కంటెంట్‌ను పేస్ట్ చేసింది"</string>
<string name="more_item_label" msgid="7419249600215749115">"ఎక్కువ"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"మెనూ+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -2143,31 +2140,19 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"ఆఫీస్"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"వ్యక్తిగత వీక్షణ"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"పని వీక్షణ"</string>
- <!-- no translation found for resolver_cross_profile_blocked (3014597376026044840) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_work_apps_explanation (9071442683080586643) -->
- <skip />
- <!-- no translation found for resolver_cant_access_work_apps_explanation (1129960195389373279) -->
- <skip />
- <!-- no translation found for resolver_cant_share_with_personal_apps_explanation (6349766201904601544) -->
- <skip />
- <!-- no translation found for resolver_cant_access_personal_apps_explanation (1679399548862724359) -->
- <skip />
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"మీ IT అడ్మిన్ ద్వారా బ్లాక్ చేయబడింది"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"ఈ కంటెంట్ వర్క్ యాప్‌తో షేర్ చేయడం సాధ్యం కాదు"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ఈ కంటెంట్ వర్క్ యాప్‌తో తెరవడం సాధ్యం కాదు"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ఈ కంటెంట్ వ్యక్తిగత యాప్‌తో షేర్ చేయడం సాధ్యం కాదు"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ఈ కంటెంట్ వ్యక్తిగత యాప్‌తో తెరవడం సాధ్యం కాదు"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"కార్యాలయ ప్రొఫైల్ పాజ్ చేయబడింది"</string>
- <!-- no translation found for resolver_switch_on_work (463709043650610420) -->
- <skip />
- <!-- no translation found for resolver_no_work_apps_available (3298291360133337270) -->
- <skip />
- <!-- no translation found for resolver_no_personal_apps_available (6284837227019594881) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_personal (2937599899213467617) -->
- <skip />
- <!-- no translation found for miniresolver_open_in_work (152208044699347924) -->
- <skip />
- <!-- no translation found for miniresolver_use_personal_browser (776072682871133308) -->
- <skip />
- <!-- no translation found for miniresolver_use_work_browser (543575306251952994) -->
- <skip />
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"ఆన్ చేయడానికి ట్యాప్ చేయి"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"వర్క్ యాప్‌లు లేవు"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"వ్యక్తిగత యాప్‌లు లేవు"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"వ్యక్తిగత ప్రొఫైల్‌లో <xliff:g id="APP">%s</xliff:g>లో తెరవాలా?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"వర్క్ ప్రొఫైల్‌లో <xliff:g id="APP">%s</xliff:g>లో తెరవాలా?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"వ్యక్తిగత బ్రౌజర్‌ను ఉపయోగించు"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"వర్క్ బ్రౌజర్‌ను ఉపయోగించు"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM నెట్‌వర్క్ అన్‌లాక్ పిన్‌"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM నెట్‌వర్క్ సబ్‌సెట్ అన్‌లాక్ పిన్"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM కార్పొరేట్ అన్‌లాక్ పిన్"</string>
@@ -2280,8 +2265,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <!-- no translation found for window_magnification_prompt_title (2876703640772778215) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"కొత్త మ్యాగ్నిఫికేషన్ సెట్టింగ్‌లు"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"మీరు ఇప్పుడు మీ స్క్రీన్ కొంత భాగాన్ని మాగ్నిఫై చేయవచ్చు"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"సెట్టింగ్‌లలో ఆన్ చేయండి"</string>
<string name="dismiss_action" msgid="1728820550388704784">"విస్మరించు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 583f00c07c4e..fe862997d0a2 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"อนุญาตให้แอปค้นหาและจับคู่อุปกรณ์บลูทูธที่อยู่ใกล้เคียง"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"เชื่อมต่อกับอุปกรณ์บลูทูธที่จับคู่"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"อนุญาตให้แอปเชื่อมต่อกับอุปกรณ์บลูทูธที่จับคู่"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ข้อมูลบริการชำระเงิน NFC ที่ต้องการ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"อนุญาตให้แอปรับข้อมูลบริการชำระเงิน NFC ที่ต้องการ เช่น รหัสแอป (AID) ที่ลงทะเบียนและปลายทางของเส้นทาง"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ควบคุม Near Field Communication"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 0692c139cdec..d647ddda87bb 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Nagbibigay-daan sa app na tumuklas at makipagpares sa mga malapit na Bluetooth device"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"kumonekta sa mga nakapares na Bluetooth device"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Nagbibigay-daan sa app na kumonekta sa mga nakapares na Bluetooth device"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Impormasyon sa Gustong NFC na Serbisyo sa Pagbabayad"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pinapayagan ang app na makakuha ng impormasyon sa gustong nfc na serbisyo sa pagbabayad tulad ng mga nakarehistrong application ID at destinasyon ng ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolin ang Near Field Communication"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index b16d02df6e44..4ec9d7e8a1ba 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Uygulamaya, yakındaki Bluetooth cihazları keşfedip eşleme izni verir"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"eşlenen Bluetooth cihazlara bağlan"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Uygulamaya, eşlenen Bluetooth cihazlara bağlanma izni verir"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tercih Edilen NFC Ödeme Hizmeti Bilgileri"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Uygulamaya, kayıtlı yardımlar ve rota hedefi gibi tercih edilen NFC ödeme hizmeti bilgilerini alma izni verir."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Yakın Alan İletişimini denetle"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 95d63aa53abe..7774f568e8cd 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -545,6 +545,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозволяє додатку знаходити поблизу пристрої Bluetooth і створювати з ними пару"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"підключатися до пристроїв із Bluetooth, з якими є пара"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозволяє додатку підключатися до пристроїв із Bluetooth, з якими створено пару"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Використання інформації з платіжного NFC-сервісу"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволяє додатку отримувати доступ до інформації потрібного платіжного NFC-сервісу (наприклад, пов\'язаних ідентифікаторів чи даних про маршрутизацію трансакцій)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контрол. Near Field Communication"</string>
@@ -2204,7 +2208,7 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"Робоче"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Особистий перегляд"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Робочий перегляд"</string>
- <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Заблоковано адміністратором"</string>
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Заблокував адміністратор"</string>
<string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Цим контентом не можна ділитися в робочих додатках"</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Цей контент не можна відкривати в робочих додатках"</string>
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Цим контентом не можна ділитися в особистих додатках"</string>
@@ -2215,8 +2219,8 @@
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Немає особистих додатків"</string>
<string name="miniresolver_open_in_personal" msgid="2937599899213467617">"Відкрити в додатку <xliff:g id="APP">%s</xliff:g> в особистому профілі?"</string>
<string name="miniresolver_open_in_work" msgid="152208044699347924">"Відкрити в додатку <xliff:g id="APP">%s</xliff:g> у робочому профілі?"</string>
- <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Використовувати особистий веб-переглядач"</string>
- <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Використовувати робочий веб-переглядач"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Використати особистий веб-переглядач"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Використати робочий веб-переглядач"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-код розблокування мережі SIM-карти"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN-код розблокування підгрупи мереж SIM-карти"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN-код розблокування корпоративної SIM-карти"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 418b9ebc91e6..bbf771af23e9 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ایپ کو قریبی بلوٹوتھ آلات دریافت کرنے اور ان کا جوڑا بنانے کی اجازت دیں"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"جوڑا بنائے ہوئے بلوٹوتھ آلات سے منسلک کریں"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ایپ کو جوڑا بنائے ہوئے بلوٹوتھ آلات سے منسلک کرنے کی اجازت دیں"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏ترجیح شدہ NFC ادائیگی کی سروس کی معلومات"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏ایپ کو رجسٹرشدہ ایڈز اور روٹ ڈسٹنیشن جیسی ترجیح شدہ nfc ادائیگی سروس کی معلومات حاصل کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"‏Near Field کمیونیکیشن کنٹرول کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 048c3022a427..1f3108f864af 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -294,8 +294,7 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Ilova faol"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Batareya quvvatini sarflayotgan ilovalar"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Kattalashtirish"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Qulayliklar ishlatilishi"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi batareya quvvatini sarflamoqda"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> ta ilova batareya quvvatini sarflamoqda"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
@@ -539,6 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Ilovaga yaqin-atrofdagi Bluetooth qurilmalarini topish va juftlashish uchun ruxsat beradi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"juftlangan Bluetooth qurilmalariga ulanish"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Ilovaga juftlangan Bluetooth qurilmalariga ulanish uchun ruxsat beradi"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Asosiy NFC toʻlov xizmati haqidagi axborot"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Bu ilovaga asosiy NFC toʻlov xizmati haqidagi axborotni olish imkonini beradi (masalan, qayd qilingan AID identifikatorlari va marshrutning yakuniy manzili)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC modulini boshqarish"</string>
@@ -575,28 +578,21 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran qulfi"</string>
<!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
<skip />
- <!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Barmoq izi qismi aniqlandi"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmoq izi aniqlanmadi. Qaytadan urining."</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"Sensorni tozalang"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"Barmoq juda tez olindi"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Barmoq juda sekin harakatlandi. Qayta urinib ko‘ring."</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Boshqa barmoq izi bilan urining"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Juda yorqin"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Moslashga urining"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmoq izi tekshirildi"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Yuzingiz aniqlandi"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yuzingiz aniqlandi, tasdiqlash uchun bosing"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Barmoq izi skaneri ish holatida emas."</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Barmoq izi sozlanmadi"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"Barmoq izini aniqlash vaqti tugab qoldi. Qayta urinib ko‘ring."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Barmoq izi tekshiruvi bekor qilindi."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Barmoq izi amali foydalanuvchi tomonidan bekor qilindi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 22714a8e7619..55ead8a18e5a 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Cho phép ứng dụng khám phá và ghép nối với các thiết bị Bluetooth ở gần"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"kết nối với các thiết bị Bluetooth đã ghép nối"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Cho phép ứng dụng kết nối với thiết bị Bluetooth đã ghép nối"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần (NFC) được ưu tiên"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Cho phép ứng dụng nhận thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần mà bạn ưu tiên, chẳng hạn như các hình thức hỗ trợ đã đăng ký và điểm đến trong hành trình."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kiểm soát Liên lạc trường gần"</string>
@@ -2262,8 +2266,7 @@
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
<string name="window_magnification_prompt_title" msgid="2876703640772778215">"Chế độ cài đặt phóng to mới"</string>
- <!-- no translation found for window_magnification_prompt_content (8159173903032344891) -->
- <skip />
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Giờ đây, bạn có thể phóng to một phần màn hình"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Bật trong phần Cài đặt"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Đóng"</string>
<string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Để tiếp tục, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; cần quyền truy cập vào micrô trên thiết bị của bạn."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 93fcf30beb07..6ee5151e386e 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允许该应用发现附近的蓝牙设备并与其配对"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"连接到已配对的蓝牙设备"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允许该应用连接到已配对的蓝牙设备"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首选 NFC 付款服务信息"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允许应用获取首选 NFC 付款服务信息,例如注册的应用标识符和路线目的地。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距离通信"</string>
@@ -2143,10 +2147,10 @@
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"无法使用个人应用打开该内容"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"工作资料已被暂停"</string>
<string name="resolver_switch_on_work" msgid="463709043650610420">"点按即可开启"</string>
- <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"所有工作应用都不支持该内容"</string>
- <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"所有个人应用都不支持该内容"</string>
- <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"要使用个人资料打开<xliff:g id="APP">%s</xliff:g>吗?"</string>
- <string name="miniresolver_open_in_work" msgid="152208044699347924">"要使用工作资料打开<xliff:g id="APP">%s</xliff:g>吗?"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"没有支持该内容的工作应用"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"没有支持该内容的个人应用"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"要使用个人资料在<xliff:g id="APP">%s</xliff:g>中打开吗?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"要使用工作资料在<xliff:g id="APP">%s</xliff:g>中打开吗?"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用个人浏览器"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作浏览器"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 网络解锁 PIN 码"</string>
@@ -2261,9 +2265,8 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <string name="window_magnification_prompt_title" msgid="2876703640772778215">"推出了新的放大设置"</string>
- <!-- no translation found for window_magnification_prompt_content (8159173903032344891) -->
- <skip />
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"推出了新的放大功能设置"</string>
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"现在您可以放大屏幕上的部分内容"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在“设置”中开启"</string>
<string name="dismiss_action" msgid="1728820550388704784">"关闭"</string>
<string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"如要继续操作,请向&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;授予设备的麦克风使用权。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 57423e14363c..31d61ffbea73 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允許應用程式探索並配對附近的藍牙裝置"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"連接附近的藍牙裝置"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允許應用程式連接已配對的藍牙裝置"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"由用戶允許授權的 NFC 付款服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得由用戶允許授權的 NFC 付款服務資訊 (如已註冊的付款輔助功能和最終付款對象)。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -621,10 +625,10 @@
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"臉孔解鎖"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"重新註冊臉孔"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"如要提高識別能力,請重新註冊您的臉孔"</string>
- <string name="face_setup_notification_title" msgid="550617822603450009">"設定人臉解鎖功能"</string>
- <string name="face_setup_notification_content" msgid="5463999831057751676">"看著手機就能解鎖"</string>
- <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"設定更多解鎖方式"</string>
- <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"輕觸即可新增指紋"</string>
+ <string name="face_setup_notification_title" msgid="550617822603450009">"設定臉孔解鎖功能"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"直望手機即可解鎖"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"設定更多解鎖方法"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"輕按即可新增指紋"</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"無法擷取準確的臉容資料。請再試一次。"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"影像太亮。請嘗試在更暗的環境下使用。"</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"影像太暗。請嘗試在更明亮的環境下使用。"</string>
@@ -1029,9 +1033,9 @@
<string name="copied" msgid="4675902854553014676">"已複製"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> 已貼上從 <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> 複製的資料"</string>
<string name="pasted_from_clipboard" msgid="6295556725844421812">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> 已貼上剪貼簿中的資料"</string>
- <string name="pasted_text" msgid="4298871641549173733">"你複製的文字已貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
- <string name="pasted_image" msgid="4729097394781491022">"你複製的圖片已貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
- <string name="pasted_content" msgid="646276353060777131">"你複製的內容已貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
+ <string name="pasted_text" msgid="4298871641549173733">"您複製的文字已貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"您複製的圖片已貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
+ <string name="pasted_content" msgid="646276353060777131">"您複製的內容已貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
<string name="more_item_label" msgid="7419249600215749115">"更多"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"選單鍵 +"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta +"</string>
@@ -2136,17 +2140,17 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"公司"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"個人檢視模式"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"工作檢視模式"</string>
- <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"IT 管理員已封鎖這項操作"</string>
- <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"無法透過工作應用程式分享這項內容"</string>
- <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"無法使用工作應用程式開啟這項內容"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"無法透過個人應用程式分享這項內容"</string>
- <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"無法使用個人應用程式開啟這項內容"</string>
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"已被您的 IT 管理員封鎖"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"無法使用工作應用程式分享此內容"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"無法使用工作應用程式開啟此內容"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"無法使用個人應用程式分享此內容"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"無法使用個人應用程式開啟此內容"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"工作設定檔已暫停使用"</string>
- <string name="resolver_switch_on_work" msgid="463709043650610420">"輕觸即可啟用"</string>
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"輕按即可啟用"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"沒有適用的工作應用程式"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"沒有適用的個人應用程式"</string>
- <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"要使用個人資料夾中的「<xliff:g id="APP">%s</xliff:g>」開啟嗎?"</string>
- <string name="miniresolver_open_in_work" msgid="152208044699347924">"要使用工作資料夾中的「<xliff:g id="APP">%s</xliff:g>」開啟嗎?"</string>
+ <string name="miniresolver_open_in_personal" msgid="2937599899213467617">"要在個人設定檔中的「<xliff:g id="APP">%s</xliff:g>」開啟嗎?"</string>
+ <string name="miniresolver_open_in_work" msgid="152208044699347924">"要在工作設定檔中的「<xliff:g id="APP">%s</xliff:g>」開啟嗎?"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用個人瀏覽器"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作瀏覽器"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 網絡解鎖 PIN"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 74cbe3709268..23b083f6d2fe 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允許應用程式探索鄰近藍牙裝置並進行配對"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"與已配對的藍牙裝置連線"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允許應用程式與已配對的藍牙裝置連線"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首選 NFC 付費服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得首選 NFC 付費服務資訊,例如已註冊的輔助工具和路線目的地。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 0f0cf74bdaca..eff5a5ff278b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -539,6 +539,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Kuvumela i-app ithole futhi ibhangqe amadivayisi we-Bluetooth aseduze"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"xhuma kumadivayisi we-Bluetooth abhangqiwe"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Kuvumela i-app ixhume kumadivayisi we-Bluetooth abhangqiwe"</string>
+ <!-- no translation found for permlab_uwb_ranging (1386872477514626447) -->
+ <skip />
+ <!-- no translation found for permdesc_uwb_ranging (1583519616137382182) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ulwazi Lwesevisi Yenkokhelo Ye-NFC Okhethwayo"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ivuemela uhlelo lokusebenza ukuthola ulwazi lesevisi yenkokhelo ye-nfc njengezinsiza zokubhalisa nezindawo zomzila."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"lawula Uxhumano Lwenkambu Eseduze"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index af595a43e0d1..180fc124f92e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4428,6 +4428,9 @@
-->
</integer-array>
+ <!-- Indicates whether device has a power button fingerprint sensor. -->
+ <bool name="config_is_powerbutton_fps" translatable="false" >false</bool>
+
<!-- Messages that should not be shown to the user during face auth enrollment. This should be
used to hide messages that may be too chatty or messages that the user can't do much about.
Entries are defined in android.hardware.biometrics.face@1.0 types.hal -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 92d857d07353..eb1fe1dd367d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2558,6 +2558,7 @@
<java-symbol type="array" name="config_biometric_sensors" />
<java-symbol type="bool" name="allow_test_udfps" />
<java-symbol type="array" name="config_udfps_sensor_props" />
+ <java-symbol type="bool" name="config_is_powerbutton_fps" />
<java-symbol type="array" name="config_face_acquire_enroll_ignorelist" />
<java-symbol type="array" name="config_face_acquire_vendor_enroll_ignorelist" />
@@ -3569,7 +3570,7 @@
<java-symbol type="bool" name="config_quickSettingsSupported" />
- <java-symbol type="style" name="Theme.DeviceDefault.QuickSettings" />
+ <java-symbol type="style" name="Theme.DeviceDefault.SystemUI" />
<java-symbol type="integer" name="default_data_warning_level_mb" />
<java-symbol type="bool" name="config_useVideoPauseWorkaround" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index e40e31e582db..ca4265a90fc3 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1884,9 +1884,7 @@ easier.
<item name="opacityListDivider">@color/list_divider_opacity_device_default_light</item>
</style>
- <!-- @hide DeviceDefault theme for a window that should use Settings theme colors
- but has a full dark palette. ONLY USED FOR QUICK SETTINGS THEME -->
- <style name="Theme.DeviceDefault.QuickSettings" parent="Theme.DeviceDefault.Light">
+ <style name="Theme.DeviceDefault.SystemUI" parent="Theme.DeviceDefault.Light">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_settings_light</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
@@ -1914,7 +1912,7 @@ easier.
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
- <style name="Theme.DeviceDefault.QuickSettings.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
+ <style name="Theme.DeviceDefault.SystemUI.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_settings_light</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index fbabf4ae1200..e1d44dc9a3cf 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -61,7 +61,6 @@ android_test {
"org.apache.http.legacy",
"android.test.base",
"android.test.mock",
- "framework-atb-backward-compatibility",
"framework",
"ext",
"framework-res",
diff --git a/core/tests/coretests/src/android/app/NotificationHistoryTest.java b/core/tests/coretests/src/android/app/NotificationHistoryTest.java
index 3df0a6871639..bd493f41d25b 100644
--- a/core/tests/coretests/src/android/app/NotificationHistoryTest.java
+++ b/core/tests/coretests/src/android/app/NotificationHistoryTest.java
@@ -29,6 +29,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -327,6 +329,48 @@ public class NotificationHistoryTest {
}
@Test
+ public void testRemoveChannelFromWrite() {
+ NotificationHistory history = new NotificationHistory();
+
+ List<HistoricalNotification> postRemoveExpectedEntries = new ArrayList<>();
+ Set<String> postRemoveExpectedStrings = new HashSet<>();
+ for (int i = 1; i <= 10; i++) {
+ HistoricalNotification n = getHistoricalNotification("pkg", i);
+
+ // Remove channel numbers 5 and 6
+ if (i != 5 && i != 6) {
+ postRemoveExpectedStrings.add(n.getPackage());
+ postRemoveExpectedStrings.add(n.getChannelName());
+ postRemoveExpectedStrings.add(n.getChannelId());
+ if (n.getConversationId() != null) {
+ postRemoveExpectedStrings.add(n.getConversationId());
+ }
+ postRemoveExpectedEntries.add(n);
+ }
+
+ history.addNotificationToWrite(n);
+ }
+ // add second notification with the same channel id that will also be removed
+ history.addNotificationToWrite(getHistoricalNotification("pkg", 6));
+
+ history.poolStringsFromNotifications();
+
+ assertThat(history.getNotificationsToWrite().size()).isEqualTo(11);
+ // 1 package name and 20 unique channel names and ids and 5 conversation ids
+ assertThat(history.getPooledStringsToWrite().length).isEqualTo(26);
+
+ history.removeChannelFromWrite("pkg", "channelId5");
+ history.removeChannelFromWrite("pkg", "channelId6");
+
+ // 1 package names and 8 * 2 unique channel names and ids and 4 conversation ids
+ assertThat(history.getPooledStringsToWrite().length).isEqualTo(21);
+ assertThat(Arrays.asList(history.getPooledStringsToWrite()))
+ .containsExactlyElementsIn(postRemoveExpectedStrings);
+ assertThat(history.getNotificationsToWrite())
+ .containsExactlyElementsIn(postRemoveExpectedEntries);
+ }
+
+ @Test
public void testParceling() {
NotificationHistory history = new NotificationHistory();
diff --git a/core/tests/coretests/src/android/window/OWNERS b/core/tests/coretests/src/android/window/OWNERS
new file mode 100644
index 000000000000..6c80cf9e5945
--- /dev/null
+++ b/core/tests/coretests/src/android/window/OWNERS
@@ -0,0 +1,2 @@
+include /services/core/java/com/android/server/wm/OWNERS
+charlesccchen@google.com
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 64bcc1c379ba..6d85c7f5c567 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -129,7 +129,7 @@ public class FrameTrackerTest {
// end the trace session, the last janky frame is after the end() so is discarded.
when(mChoreographer.getVsyncId()).thenReturn(102L);
- mTracker.end();
+ mTracker.end(FrameTracker.REASON_END_NORMAL);
sendFrame(5, JANK_NONE, 102L);
sendFrame(500, JANK_APP_DEADLINE_MISSED, 103L);
@@ -151,7 +151,7 @@ public class FrameTrackerTest {
// end the trace session
when(mChoreographer.getVsyncId()).thenReturn(102L);
- mTracker.end();
+ mTracker.end(FrameTracker.REASON_END_NORMAL);
sendFrame(4, JANK_NONE, 102L);
verify(mTracker).removeObservers();
@@ -174,7 +174,7 @@ public class FrameTrackerTest {
// end the trace session
when(mChoreographer.getVsyncId()).thenReturn(102L);
- mTracker.end();
+ mTracker.end(FrameTracker.REASON_END_NORMAL);
sendFrame(4, JANK_NONE, 102L);
verify(mTracker).removeObservers();
@@ -197,7 +197,7 @@ public class FrameTrackerTest {
// end the trace session
when(mChoreographer.getVsyncId()).thenReturn(102L);
- mTracker.end();
+ mTracker.end(FrameTracker.REASON_END_NORMAL);
sendFrame(4, JANK_NONE, 102L);
verify(mTracker).removeObservers();
@@ -220,7 +220,7 @@ public class FrameTrackerTest {
// end the trace session, simulate one more valid callback came after the end call.
when(mChoreographer.getVsyncId()).thenReturn(102L);
- mTracker.end();
+ mTracker.end(FrameTracker.REASON_END_NORMAL);
sendFrame(50, JANK_APP_DEADLINE_MISSED, 102L);
// One more callback with VSYNC after the end() vsync id.
@@ -247,7 +247,7 @@ public class FrameTrackerTest {
// a janky frame
sendFrame(50, JANK_APP_DEADLINE_MISSED, 102L);
- mTracker.cancel();
+ mTracker.cancel(FrameTracker.REASON_CANCEL_NORMAL);
verify(mTracker).removeObservers();
// Since the tracker has been cancelled, shouldn't trigger perfetto.
verify(mTracker, never()).triggerPerfetto();
@@ -267,11 +267,11 @@ public class FrameTrackerTest {
// end the trace session
when(mChoreographer.getVsyncId()).thenReturn(101L);
- mTracker.end();
+ mTracker.end(FrameTracker.REASON_END_NORMAL);
sendFrame(4, JANK_NONE, 102L);
// Since the begin vsync id (101) equals to the end vsync id (101), will be treat as cancel.
- verify(mTracker).cancel();
+ verify(mTracker).cancel(FrameTracker.REASON_CANCEL_SAME_VSYNC);
// Observers should be removed in this case, or FrameTracker object will be leaked.
verify(mTracker).removeObservers();
@@ -282,13 +282,13 @@ public class FrameTrackerTest {
@Test
public void testCancelWhenSessionNeverBegun() {
- mTracker.cancel();
+ mTracker.cancel(FrameTracker.REASON_CANCEL_NORMAL);
verify(mTracker).removeObservers();
}
@Test
public void testEndWhenSessionNeverBegun() {
- mTracker.end();
+ mTracker.end(FrameTracker.REASON_END_NORMAL);
verify(mTracker).removeObservers();
}
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index 8f4948c02a74..5f4b854d872d 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -103,7 +103,7 @@ public class InteractionJankMonitorTest {
assertThat(monitor.begin(mView, session.getCuj())).isTrue();
verify(tracker).begin();
assertThat(monitor.end(session.getCuj())).isTrue();
- verify(tracker).end();
+ verify(tracker).end(FrameTracker.REASON_END_NORMAL);
}
@Test
@@ -154,7 +154,7 @@ public class InteractionJankMonitorTest {
assertThat(runnable).isNotNull();
mWorker.getThreadHandler().removeCallbacks(runnable);
runnable.run();
- verify(tracker).cancel();
+ verify(tracker).cancel(FrameTracker.REASON_CANCEL_NORMAL);
}
@Test
diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
index e41805dd3a59..8271bed940e2 100644
--- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
+++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.content.AttributionSource;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -45,13 +46,17 @@ public class RangingManagerTest {
private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
private static final PersistableBundle PARAMS = new PersistableBundle();
private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN;
+ private static final int UID = 343453;
+ private static final String PACKAGE_NAME = "com.uwb.test";
+ private static final AttributionSource ATTRIBUTION_SOURCE =
+ new AttributionSource.Builder(UID).setPackageName(PACKAGE_NAME).build();
@Test
public void testOpenSession_OpenRangingInvoked() throws RemoteException {
IUwbAdapter adapter = mock(IUwbAdapter.class);
RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback);
verify(adapter, times(1)).openRanging(any(), eq(rangingManager), eq(PARAMS));
}
@@ -74,11 +79,11 @@ public class RangingManagerTest {
ArgumentCaptor.forClass(SessionHandle.class);
RangingManager rangingManager = new RangingManager(adapter);
- rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1);
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
- rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2);
verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
@@ -100,7 +105,7 @@ public class RangingManagerTest {
ArgumentCaptor<SessionHandle> sessionHandleCaptor =
ArgumentCaptor.forClass(SessionHandle.class);
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback);
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
SessionHandle handle = sessionHandleCaptor.getValue();
@@ -145,11 +150,11 @@ public class RangingManagerTest {
ArgumentCaptor<SessionHandle> sessionHandleCaptor =
ArgumentCaptor.forClass(SessionHandle.class);
- rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1);
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
- rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2);
verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
@@ -172,12 +177,12 @@ public class RangingManagerTest {
ArgumentCaptor.forClass(SessionHandle.class);
RangingManager rangingManager = new RangingManager(adapter);
- rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1);
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
rangingManager.onRangingStarted(sessionHandle1, PARAMS);
- rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2);
verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingStarted(sessionHandle2, PARAMS);
@@ -224,7 +229,7 @@ public class RangingManagerTest {
ArgumentCaptor<SessionHandle> sessionHandleCaptor =
ArgumentCaptor.forClass(SessionHandle.class);
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback);
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
SessionHandle handle = sessionHandleCaptor.getValue();
@@ -232,7 +237,7 @@ public class RangingManagerTest {
verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS));
// Open a new session
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback);
verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
handle = sessionHandleCaptor.getValue();
rangingManager.onRangingOpened(handle);
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 8312320a8d87..89a2614a1d92 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -501,6 +501,8 @@ applications that come with the platform
<permission name="android.permission.SCHEDULE_PRIORITIZED_ALARM" />
<!-- Permission required for CTS test - SystemMediaRouter2Test -->
<permission name="android.permission.MODIFY_AUDIO_ROUTING"/>
+ <!-- Permission required for CTS test - CtsPermission5TestCases -->
+ <permission name="android.permission.RENOUNCE_PERMISSIONS" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/graphics/java/android/graphics/RecordingCanvas.java b/graphics/java/android/graphics/RecordingCanvas.java
index 8dd7f317c842..6c03ddc4a12d 100644
--- a/graphics/java/android/graphics/RecordingCanvas.java
+++ b/graphics/java/android/graphics/RecordingCanvas.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.NonNull;
+import android.os.SystemProperties;
import android.util.Pools.SynchronizedPool;
import dalvik.annotation.optimization.CriticalNative;
@@ -36,7 +37,15 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
// view hierarchy because display lists are generated recursively.
private static final int POOL_LIMIT = 25;
- private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
+ /** @hide */
+ private static int getPanelFrameSize() {
+ final int DefaultSize = 100 * 1024 * 1024; // 100 MB;
+ return Math.max(SystemProperties.getInt("ro.hwui.max_texture_allocation_size", DefaultSize),
+ DefaultSize);
+ }
+
+ /** @hide */
+ public static final int MAX_BITMAP_SIZE = getPanelFrameSize();
private static final SynchronizedPool<RecordingCanvas> sPool =
new SynchronizedPool<>(POOL_LIMIT);
diff --git a/graphics/java/android/graphics/drawable/RippleAnimationSession.java b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
index fb089741dfb2..9ee1ef1cadd3 100644
--- a/graphics/java/android/graphics/drawable/RippleAnimationSession.java
+++ b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
@@ -41,8 +41,8 @@ public final class RippleAnimationSession {
private static final int ENTER_ANIM_DURATION = 450;
private static final int EXIT_ANIM_DURATION = 300;
private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
- private static final Interpolator FAST_OUT_LINEAR_IN =
- new PathInterpolator(0.4f, 0f, 1f, 1f);
+ private static final Interpolator FAST_OUT_SLOW_IN =
+ new PathInterpolator(0.4f, 0f, 0.2f, 1f);
private Consumer<RippleAnimationSession> mOnSessionEnd;
private final AnimationProperties<Float, Paint> mProperties;
private AnimationProperties<CanvasProperty<Float>, CanvasProperty<Paint>> mCanvasProperties;
@@ -173,7 +173,7 @@ public final class RippleAnimationSession {
private void startAnimation(Animator expand) {
expand.setDuration(ENTER_ANIM_DURATION);
expand.addListener(new AnimatorListener(this));
- expand.setInterpolator(FAST_OUT_LINEAR_IN);
+ expand.setInterpolator(FAST_OUT_SLOW_IN);
expand.start();
mAnimateSparkle = true;
}
diff --git a/graphics/java/android/graphics/drawable/RippleShader.java b/graphics/java/android/graphics/drawable/RippleShader.java
index 6b2b9599facb..899a5eb3f849 100644
--- a/graphics/java/android/graphics/drawable/RippleShader.java
+++ b/graphics/java/android/graphics/drawable/RippleShader.java
@@ -48,7 +48,7 @@ final class RippleShader extends RuntimeShader {
+ " float s = 0.0;\n"
+ " for (float i = 0; i < 4; i += 1) {\n"
+ " float l = i * 0.01;\n"
- + " float h = l + 0.1;\n"
+ + " float h = l + 0.2;\n"
+ " float o = smoothstep(n - l, h, n);\n"
+ " o *= abs(sin(PI * o * (t + 0.55 * i)));\n"
+ " s += o;\n"
@@ -62,7 +62,7 @@ final class RippleShader extends RuntimeShader {
+ " return 1. - smoothstep(1. - blurHalf, 1. + blurHalf, d / radius);\n"
+ "}\n"
+ "float softRing(vec2 uv, vec2 xy, float radius, float progress, float blur) {\n"
- + " float thickness = 0.2 * radius;\n"
+ + " float thickness = 0.3 * radius;\n"
+ " float currentRadius = radius * progress;\n"
+ " float circle_outer = softCircle(uv, xy, currentRadius + thickness, blur);\n"
+ " float circle_inner = softCircle(uv, xy, currentRadius - thickness, blur);\n"
@@ -73,18 +73,19 @@ final class RippleShader extends RuntimeShader {
+ " return (sub - start) / (end - start); \n"
+ "}\n";
private static final String SHADER_MAIN = "vec4 main(vec2 p) {\n"
- + " float fadeIn = subProgress(0., 0.175, in_progress);\n"
- + " float fadeOutNoise = subProgress(0.375, 1., in_progress);\n"
- + " float fadeOutRipple = subProgress(0.375, 0.75, in_progress);\n"
- + " vec2 center = mix(in_touch, in_origin, fadeIn);\n"
- + " float ring = softRing(p, center, in_maxRadius, fadeIn, 0.45);\n"
- + " float alpha = 1. - fadeOutNoise;\n"
+ + " float fadeIn = subProgress(0., 0.1, in_progress);\n"
+ + " float scaleIn = subProgress(0., 0.45, in_progress);\n"
+ + " float fadeOutNoise = subProgress(0.5, 1., in_progress);\n"
+ + " float fadeOutRipple = subProgress(0.5, 0.75, in_progress);\n"
+ + " vec2 center = mix(in_touch, in_origin, scaleIn);\n"
+ + " float ring = softRing(p, center, in_maxRadius, scaleIn, 0.45);\n"
+ + " float alpha = min(fadeIn, 1. - fadeOutNoise);\n"
+ " vec2 uv = p * in_resolutionScale;\n"
+ " vec2 densityUv = uv - mod(uv, in_noiseScale);\n"
+ " float sparkle = sparkles(densityUv, in_noisePhase) * ring * alpha;\n"
+ " float fade = min(fadeIn, 1. - fadeOutRipple);\n"
+ " vec4 circle = in_color * (softCircle(p, center, in_maxRadius "
- + " * fadeIn, 0.2) * fade);\n"
+ + " * scaleIn, 0.2) * fade);\n"
+ " float mask = in_hasMask == 1. ? sample(in_shader).a > 0. ? 1. : 0. : 1.;\n"
+ " return mix(circle, vec4(sparkle), sparkle) * mask;\n"
+ "}";
@@ -134,7 +135,7 @@ final class RippleShader extends RuntimeShader {
}
public void setResolution(float w, float h, int density) {
- float densityScale = density * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ float densityScale = density * DisplayMetrics.DENSITY_DEFAULT_SCALE * 1.25f;
setUniform("in_resolutionScale", new float[] {1f / w, 1f / h});
setUniform("in_noiseScale", new float[] {densityScale / w, densityScale / h});
}
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index 72cea0cacd12..82639def02de 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -47,7 +47,6 @@ public class AndroidKeyStoreMaintenance {
* @hide
*/
public static int onUserAdded(@NonNull int userId) {
- if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
try {
getService().onUserAdded(userId);
return 0;
@@ -68,7 +67,6 @@ public class AndroidKeyStoreMaintenance {
* @hide
*/
public static int onUserRemoved(int userId) {
- if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
try {
getService().onUserRemoved(userId);
return 0;
@@ -91,7 +89,6 @@ public class AndroidKeyStoreMaintenance {
* @hide
*/
public static int onUserPasswordChanged(int userId, @Nullable byte[] password) {
- if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
try {
getService().onUserPasswordChanged(userId, password);
return 0;
@@ -109,7 +106,6 @@ public class AndroidKeyStoreMaintenance {
* be cleared.
*/
public static int clearNamespace(@Domain int domain, long namespace) {
- if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
try {
getService().clearNamespace(domain, namespace);
return 0;
@@ -144,7 +140,6 @@ public class AndroidKeyStoreMaintenance {
* Informs Keystore 2.0 that an off body event was detected.
*/
public static void onDeviceOffBody() {
- if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return;
try {
getService().onDeviceOffBody();
} catch (Exception e) {
diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java
index 50a90820117d..bd72d45297c1 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/Authorization.java
@@ -48,7 +48,6 @@ public class Authorization {
* @return 0 if successful or {@code ResponseCode.SYSTEM_ERROR}.
*/
public static int addAuthToken(@NonNull HardwareAuthToken authToken) {
- if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
try {
getService().addAuthToken(authToken);
return 0;
@@ -80,7 +79,6 @@ public class Authorization {
*/
public static int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId,
@Nullable byte[] syntheticPassword) {
- if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
try {
if (locked) {
getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null);
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index ae9f866459d6..28c601ba0e6f 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -208,78 +208,4 @@ public class Credentials {
pr.close();
}
}
-
- /**
- * Delete all types (private key, user certificate, CA certificate) for a
- * particular {@code alias}. All three can exist for any given alias.
- * Returns {@code true} if the alias no longer contains any types.
- */
- public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias) {
- return deleteAllTypesForAlias(keystore, alias, KeyStore.UID_SELF);
- }
-
- /**
- * Delete all types (private key, user certificate, CA certificate) for a
- * particular {@code alias}. All three can exist for any given alias.
- * Returns {@code true} if the alias no longer contains any types.
- */
- public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias, int uid) {
- /*
- * Make sure every type is deleted. There can be all three types, so
- * don't use a conditional here.
- */
- return deleteUserKeyTypeForAlias(keystore, alias, uid)
- & deleteCertificateTypesForAlias(keystore, alias, uid);
- }
-
- /**
- * Delete certificate types (user certificate, CA certificate) for a
- * particular {@code alias}. Both can exist for any given alias.
- * Returns {@code true} if the alias no longer contains either type.
- */
- public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias) {
- return deleteCertificateTypesForAlias(keystore, alias, KeyStore.UID_SELF);
- }
-
- /**
- * Delete certificate types (user certificate, CA certificate) for a
- * particular {@code alias}. Both can exist for any given alias.
- * Returns {@code true} if the alias no longer contains either type.
- */
- public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias, int uid) {
- /*
- * Make sure every certificate type is deleted. There can be two types,
- * so don't use a conditional here.
- */
- return keystore.delete(Credentials.USER_CERTIFICATE + alias, uid)
- & keystore.delete(Credentials.CA_CERTIFICATE + alias, uid);
- }
-
- /**
- * Delete user key for a particular {@code alias}.
- * Returns {@code true} if the entry no longer exists.
- */
- public static boolean deleteUserKeyTypeForAlias(KeyStore keystore, String alias) {
- return deleteUserKeyTypeForAlias(keystore, alias, KeyStore.UID_SELF);
- }
-
- /**
- * Delete user key for a particular {@code alias}.
- * Returns {@code true} if the entry no longer exists.
- */
- public static boolean deleteUserKeyTypeForAlias(KeyStore keystore, String alias, int uid) {
- int ret = keystore.delete2(Credentials.USER_PRIVATE_KEY + alias, uid);
- if (ret == KeyStore.KEY_NOT_FOUND) {
- return keystore.delete(Credentials.USER_SECRET_KEY + alias, uid);
- }
- return ret == KeyStore.NO_ERROR;
- }
-
- /**
- * Delete legacy prefixed entry for a particular {@code alias}
- * Returns {@code true} if the entry no longer exists.
- */
- public static boolean deleteLegacyKeyForAlias(KeyStore keystore, String alias, int uid) {
- return keystore.delete(Credentials.USER_SECRET_KEY + alias, uid);
- }
}
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 7c80f70593df..02cdeef77bec 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -42,7 +42,6 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
-import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.system.keystore2.Domain;
@@ -806,23 +805,13 @@ public final class KeyChain {
return null;
}
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- try {
- return android.security.keystore2.AndroidKeyStoreProvider
- .loadAndroidKeyStoreKeyPairFromKeystore(
- KeyStore2.getInstance(),
- getGrantDescriptor(keyId));
- } catch (UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
- throw new KeyChainException(e);
- }
- } else {
- try {
- return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
- KeyStore.getInstance(), keyId, KeyStore.UID_SELF);
- } catch (RuntimeException | UnrecoverableKeyException
- | KeyPermanentlyInvalidatedException e) {
- throw new KeyChainException(e);
- }
+ try {
+ return android.security.keystore2.AndroidKeyStoreProvider
+ .loadAndroidKeyStoreKeyPairFromKeystore(
+ KeyStore2.getInstance(),
+ getGrantDescriptor(keyId));
+ } catch (UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
+ throw new KeyChainException(e);
}
}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index b05149ef75bc..a9543443d3f4 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -16,53 +16,11 @@
package android.security;
-import android.app.ActivityThread;
-import android.app.Application;
-import android.app.KeyguardManager;
import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.hardware.biometrics.BiometricManager;
-import android.os.Binder;
import android.os.Build;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.UserHandle;
-import android.security.keymaster.ExportResult;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterBlob;
-import android.security.keymaster.KeymasterCertificateChain;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keymaster.OperationResult;
-import android.security.keystore.IKeystoreService;
-import android.security.keystore.KeyExpiredException;
-import android.security.keystore.KeyNotYetValidException;
-import android.security.keystore.KeyPermanentlyInvalidatedException;
-import android.security.keystore.KeyProperties;
-import android.security.keystore.KeystoreResponse;
-import android.security.keystore.UserNotAuthenticatedException;
import android.security.maintenance.UserState;
import android.system.keystore2.Domain;
-import android.util.Log;
-
-import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
-import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import sun.security.util.ObjectIdentifier;
-import sun.security.x509.AlgorithmId;
/**
* @hide This should not be made public in its present form because it
@@ -75,79 +33,10 @@ public class KeyStore {
// ResponseCodes - see system/security/keystore/include/keystore/keystore.h
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final int NO_ERROR = 1;
- public static final int LOCKED = 2;
- public static final int UNINITIALIZED = 3;
- public static final int SYSTEM_ERROR = 4;
- public static final int PROTOCOL_ERROR = 5;
- public static final int PERMISSION_DENIED = 6;
- public static final int KEY_NOT_FOUND = 7;
- public static final int VALUE_CORRUPTED = 8;
- public static final int UNDEFINED_ACTION = 9;
- public static final int WRONG_PASSWORD = 10;
- public static final int KEY_ALREADY_EXISTS = 16;
- public static final int CANNOT_ATTEST_IDS = -66;
- public static final int HARDWARE_TYPE_UNAVAILABLE = -68;
-
- /**
- * Per operation authentication is needed before this operation is valid.
- * This is returned from {@link #begin} when begin succeeds but the operation uses
- * per-operation authentication and must authenticate before calling {@link #update} or
- * {@link #finish}.
- */
- public static final int OP_AUTH_NEEDED = 15;
-
- // Used when a user changes their pin, invalidating old auth bound keys.
- public static final int KEY_PERMANENTLY_INVALIDATED = 17;
// Used for UID field to indicate the calling UID.
public static final int UID_SELF = -1;
- // Flags for "put" "import" and "generate"
- public static final int FLAG_NONE = 0;
-
- /**
- * Indicates that this key (or key pair) must be encrypted at rest. This will protect the key
- * (or key pair) with the secure lock screen credential (e.g., password, PIN, or pattern).
- *
- * <p>Note that this requires that the secure lock screen (e.g., password, PIN, pattern) is set
- * up, otherwise key (or key pair) generation or import will fail. Moreover, this key (or key
- * pair) will be deleted when the secure lock screen is disabled or reset (e.g., by the user or
- * a Device Administrator). Finally, this key (or key pair) cannot be used until the user
- * unlocks the secure lock screen after boot.
- *
- * @see KeyguardManager#isDeviceSecure()
- */
- public static final int FLAG_ENCRYPTED = 1;
-
- /**
- * Select Software keymaster device, which as of this writing is the lowest security
- * level available on an android device. If neither FLAG_STRONGBOX nor FLAG_SOFTWARE is provided
- * A TEE based keymaster implementation is implied.
- *
- * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h
- * For historical reasons this corresponds to the KEYSTORE_FLAG_FALLBACK flag.
- */
- public static final int FLAG_SOFTWARE = 1 << 1;
-
- /**
- * A private flag that's only available to system server to indicate that this key is part of
- * device encryption flow so it receives special treatment from keystore. For example this key
- * will not be super encrypted, and it will be stored separately under an unique UID instead
- * of the caller UID i.e. SYSTEM.
- *
- * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h
- */
- public static final int FLAG_CRITICAL_TO_DEVICE_ENCRYPTION = 1 << 3;
-
- /**
- * Select Strongbox keymaster device, which as of this writing the the highest security level
- * available an android devices. If neither FLAG_STRONGBOX nor FLAG_SOFTWARE is provided
- * A TEE based keymaster implementation is implied.
- *
- * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h
- */
- public static final int FLAG_STRONGBOX = 1 << 4;
-
// States
public enum State {
@UnsupportedAppUsage
@@ -157,853 +46,87 @@ public class KeyStore {
UNINITIALIZED
};
- private int mError = NO_ERROR;
-
- private final IKeystoreService mBinder;
- private final Context mContext;
-
- private IBinder mToken;
-
- private KeyStore(IKeystoreService binder) {
- mBinder = binder;
- mContext = getApplicationContext();
- }
-
- @UnsupportedAppUsage
- public static Context getApplicationContext() {
- Application application = ActivityThread.currentApplication();
- if (application == null) {
- throw new IllegalStateException(
- "Failed to obtain application Context from ActivityThread");
- }
- return application;
- }
+ private static final KeyStore KEY_STORE = new KeyStore();
@UnsupportedAppUsage
public static KeyStore getInstance() {
- IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
- .getService("android.security.keystore"));
- return new KeyStore(keystore);
- }
-
- private synchronized IBinder getToken() {
- if (mToken == null) {
- mToken = new Binder();
- }
- return mToken;
+ return KEY_STORE;
}
+ /** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public State state(int userId) {
- final int ret;
- try {
- if (android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) {
- int userState = AndroidKeyStoreMaintenance.getState(userId);
- switch (userState) {
- case UserState.UNINITIALIZED:
- return KeyStore.State.UNINITIALIZED;
- case UserState.LSKF_UNLOCKED:
- return KeyStore.State.UNLOCKED;
- case UserState.LSKF_LOCKED:
- return KeyStore.State.LOCKED;
- default:
- throw new AssertionError(userState);
- }
- }
- ret = mBinder.getState(userId);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- throw new AssertionError(e);
- }
-
- switch (ret) {
- case NO_ERROR: return State.UNLOCKED;
- case LOCKED: return State.LOCKED;
- case UNINITIALIZED: return State.UNINITIALIZED;
- default: throw new AssertionError(mError);
+ int userState = AndroidKeyStoreMaintenance.getState(userId);
+ switch (userState) {
+ case UserState.UNINITIALIZED:
+ return KeyStore.State.UNINITIALIZED;
+ case UserState.LSKF_UNLOCKED:
+ return KeyStore.State.UNLOCKED;
+ case UserState.LSKF_LOCKED:
+ return KeyStore.State.LOCKED;
+ default:
+ throw new AssertionError(userState);
}
}
+ /** @hide */
@UnsupportedAppUsage
public State state() {
return state(UserHandle.myUserId());
}
- public boolean isUnlocked() {
- return state() == State.UNLOCKED;
- }
-
- public byte[] get(String key, int uid) {
- return get(key, uid, false);
- }
-
+ /** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public byte[] get(String key) {
- return get(key, UID_SELF);
- }
-
- public byte[] get(String key, int uid, boolean suppressKeyNotFoundWarning) {
- try {
- key = key != null ? key : "";
- return mBinder.get(key, uid);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- } catch (android.os.ServiceSpecificException e) {
- if (!suppressKeyNotFoundWarning || e.errorCode != KEY_NOT_FOUND) {
- Log.w(TAG, "KeyStore exception", e);
- }
- return null;
- }
- }
-
- public byte[] get(String key, boolean suppressKeyNotFoundWarning) {
- return get(key, UID_SELF, suppressKeyNotFoundWarning);
- }
-
-
- public boolean put(String key, byte[] value, int uid, int flags) {
- return insert(key, value, uid, flags) == NO_ERROR;
- }
-
- public int insert(String key, byte[] value, int uid, int flags) {
- try {
- if (value == null) {
- value = new byte[0];
- }
- int error = mBinder.insert(key, value, uid, flags);
- if (error == KEY_ALREADY_EXISTS) {
- mBinder.del(key, uid);
- error = mBinder.insert(key, value, uid, flags);
- }
- return error;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- }
- }
-
- int delete2(String key, int uid) {
- try {
- return mBinder.del(key, uid);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- }
- }
-
- public boolean delete(String key, int uid) {
- int ret = delete2(key, uid);
- return ret == NO_ERROR || ret == KEY_NOT_FOUND;
+ return null;
}
+ /** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean delete(String key) {
- return delete(key, UID_SELF);
- }
-
- public boolean contains(String key, int uid) {
- try {
- return mBinder.exist(key, uid) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- public boolean contains(String key) {
- return contains(key, UID_SELF);
- }
-
- /**
- * List all entries in the keystore for {@code uid} starting with {@code prefix}.
- */
- public String[] list(String prefix, int uid) {
- try {
- return mBinder.list(prefix, uid);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- } catch (android.os.ServiceSpecificException e) {
- Log.w(TAG, "KeyStore exception", e);
- return null;
- }
+ return false;
}
/**
* List uids of all keys that are auth bound to the current user.
* Only system is allowed to call this method.
+ * @hide
+ * @deprecated This function always returns null.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public int[] listUidsOfAuthBoundKeys() {
- // uids are returned as a list of strings because list of integers
- // as an output parameter is not supported by aidl-cpp.
- List<String> uidsOut = new ArrayList<>();
- try {
- int rc = mBinder.listUidsOfAuthBoundKeys(uidsOut);
- if (rc != NO_ERROR) {
- Log.w(TAG, String.format("listUidsOfAuthBoundKeys failed with error code %d", rc));
- return null;
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- } catch (android.os.ServiceSpecificException e) {
- Log.w(TAG, "KeyStore exception", e);
- return null;
- }
- // Turn list of strings into an array of uid integers.
- return uidsOut.stream().mapToInt(Integer::parseInt).toArray();
- }
-
- public String[] list(String prefix) {
- return list(prefix, UID_SELF);
+ return null;
}
- /**
- * Attempt to lock the keystore for {@code user}.
- *
- * @param userId Android user to lock.
- * @return whether {@code user}'s keystore was locked.
- */
- public boolean lock(int userId) {
- try {
- return mBinder.lock(userId) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- public boolean lock() {
- return lock(UserHandle.myUserId());
- }
/**
- * Attempt to unlock the keystore for {@code user} with the password {@code password}.
- * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or
- * created.
- *
- * @param userId Android user ID to operate on
- * @param password user's keystore password. Should be the most recent value passed to
- * {@link #onUserPasswordChanged} for the user.
- *
- * @return whether the keystore was unlocked.
+ * @hide
+ * @deprecated This function has no effect.
*/
- public boolean unlock(int userId, String password) {
- try {
- password = password != null ? password : "";
- mError = mBinder.unlock(userId, password);
- return mError == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean unlock(String password) {
- return unlock(UserHandle.getUserId(Process.myUid()), password);
+ return false;
}
/**
- * Check if the keystore for {@code userId} is empty.
+ *
+ * @return
+ * @deprecated This function always returns true.
+ * @hide
*/
- public boolean isEmpty(int userId) {
- try {
- return mBinder.isEmpty(userId) != 0;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public boolean isEmpty() {
- return isEmpty(UserHandle.myUserId());
- }
-
- public String grant(String key, int uid) {
- try {
- String grantAlias = mBinder.grant(key, uid);
- if (grantAlias == "") return null;
- return grantAlias;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- }
- }
-
- public boolean ungrant(String key, int uid) {
- try {
- return mBinder.ungrant(key, uid) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- /**
- * Returns the last modification time of the key in milliseconds since the
- * epoch. Will return -1L if the key could not be found or other error.
- */
- public long getmtime(String key, int uid) {
- try {
- final long millis = mBinder.getmtime(key, uid);
- if (millis == -1L) {
- return -1L;
- }
-
- return millis * 1000L;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return -1L;
- }
- }
-
- public long getmtime(String key) {
- return getmtime(key, UID_SELF);
- }
-
- // TODO: remove this when it's removed from Settings
- public boolean isHardwareBacked() {
- return isHardwareBacked("RSA");
- }
-
- public boolean isHardwareBacked(String keyType) {
- try {
- return mBinder.is_hardware_backed(keyType.toUpperCase(Locale.US)) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- public boolean clearUid(int uid) {
- try {
- if (android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) {
- return AndroidKeyStoreMaintenance.clearNamespace(Domain.APP, uid) == 0;
- }
- return mBinder.clear_uid(uid) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- public int getLastError() {
- return mError;
- }
-
- public boolean addRngEntropy(byte[] data, int flags) {
- KeystoreResultPromise promise = new KeystoreResultPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- int errorCode = mBinder.addRngEntropy(promise, data, flags);
- if (errorCode == NO_ERROR) {
- return interruptedPreservingGet(promise.getFuture()).getErrorCode() == NO_ERROR;
- } else {
- return false;
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- } catch (ExecutionException e) {
- Log.e(TAG, "AddRngEntropy completed with exception", e);
- return false;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
-
- private class KeyCharacteristicsCallbackResult {
- private KeystoreResponse keystoreResponse;
- private KeyCharacteristics keyCharacteristics;
-
- public KeyCharacteristicsCallbackResult(KeystoreResponse keystoreResponse,
- KeyCharacteristics keyCharacteristics) {
- this.keystoreResponse = keystoreResponse;
- this.keyCharacteristics = keyCharacteristics;
- }
-
- public KeystoreResponse getKeystoreResponse() {
- return keystoreResponse;
- }
-
- public void setKeystoreResponse(KeystoreResponse keystoreResponse) {
- this.keystoreResponse = keystoreResponse;
- }
-
- public KeyCharacteristics getKeyCharacteristics() {
- return keyCharacteristics;
- }
-
- public void setKeyCharacteristics(KeyCharacteristics keyCharacteristics) {
- this.keyCharacteristics = keyCharacteristics;
- }
- }
-
- private class KeyCharacteristicsPromise
- extends android.security.keystore.IKeystoreKeyCharacteristicsCallback.Stub
- implements IBinder.DeathRecipient {
- final private CompletableFuture<KeyCharacteristicsCallbackResult> future =
- new CompletableFuture<KeyCharacteristicsCallbackResult>();
- @Override
- public void onFinished(KeystoreResponse keystoreResponse,
- KeyCharacteristics keyCharacteristics)
- throws android.os.RemoteException {
- future.complete(
- new KeyCharacteristicsCallbackResult(keystoreResponse, keyCharacteristics));
- }
- public final CompletableFuture<KeyCharacteristicsCallbackResult> getFuture() {
- return future;
- }
- @Override
- public void binderDied() {
- future.completeExceptionally(new RemoteException("Keystore died"));
- }
- };
-
- private int generateKeyInternal(String alias, KeymasterArguments args, byte[] entropy, int uid,
- int flags, KeyCharacteristics outCharacteristics)
- throws RemoteException, ExecutionException {
- KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
- int error = NO_ERROR;
- KeyCharacteristicsCallbackResult result = null;
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- error = mBinder.generateKey(promise, alias, args, entropy, uid, flags);
- if (error != NO_ERROR) {
- Log.e(TAG, "generateKeyInternal failed on request " + error);
- return error;
- }
- result = interruptedPreservingGet(promise.getFuture());
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
-
- error = result.getKeystoreResponse().getErrorCode();
- if (error != NO_ERROR) {
- Log.e(TAG, "generateKeyInternal failed on response " + error);
- return error;
- }
- KeyCharacteristics characteristics = result.getKeyCharacteristics();
- if (characteristics == null) {
- Log.e(TAG, "generateKeyInternal got empty key characteristics " + error);
- return SYSTEM_ERROR;
- }
- outCharacteristics.shallowCopyFrom(characteristics);
- return NO_ERROR;
- }
-
- public int generateKey(String alias, KeymasterArguments args, byte[] entropy, int uid,
- int flags, KeyCharacteristics outCharacteristics) {
- try {
- entropy = entropy != null ? entropy : new byte[0];
- args = args != null ? args : new KeymasterArguments();
- int error = generateKeyInternal(alias, args, entropy, uid, flags, outCharacteristics);
- if (error == KEY_ALREADY_EXISTS) {
- mBinder.del(alias, uid);
- error = generateKeyInternal(alias, args, entropy, uid, flags, outCharacteristics);
- }
- return error;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- } catch (ExecutionException e) {
- Log.e(TAG, "generateKey completed with exception", e);
- return SYSTEM_ERROR;
- }
- }
-
- public int generateKey(String alias, KeymasterArguments args, byte[] entropy, int flags,
- KeyCharacteristics outCharacteristics) {
- return generateKey(alias, args, entropy, UID_SELF, flags, outCharacteristics);
- }
-
- public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId,
- int uid, KeyCharacteristics outCharacteristics) {
- KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- clientId = clientId != null ? clientId : new KeymasterBlob(new byte[0]);
- appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
-
- int error = mBinder.getKeyCharacteristics(promise, alias, clientId, appId, uid);
- if (error != NO_ERROR) return error;
-
- KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());
- error = result.getKeystoreResponse().getErrorCode();
- if (error != NO_ERROR) return error;
-
- KeyCharacteristics characteristics = result.getKeyCharacteristics();
- if (characteristics == null) return SYSTEM_ERROR;
- outCharacteristics.shallowCopyFrom(characteristics);
- return NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- } catch (ExecutionException e) {
- Log.e(TAG, "GetKeyCharacteristics completed with exception", e);
- return SYSTEM_ERROR;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
-
- public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId,
- KeyCharacteristics outCharacteristics) {
- return getKeyCharacteristics(alias, clientId, appId, UID_SELF, outCharacteristics);
- }
-
- private int importKeyInternal(String alias, KeymasterArguments args, int format, byte[] keyData,
- int uid, int flags, KeyCharacteristics outCharacteristics)
- throws RemoteException, ExecutionException {
- KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
- mBinder.asBinder().linkToDeath(promise, 0);
- try {
- int error = mBinder.importKey(promise, alias, args, format, keyData, uid, flags);
- if (error != NO_ERROR) return error;
-
- KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());
-
- error = result.getKeystoreResponse().getErrorCode();
- if (error != NO_ERROR) return error;
-
- KeyCharacteristics characteristics = result.getKeyCharacteristics();
- if (characteristics == null) return SYSTEM_ERROR;
- outCharacteristics.shallowCopyFrom(characteristics);
- return NO_ERROR;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
-
- public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData,
- int uid, int flags, KeyCharacteristics outCharacteristics) {
- try {
- int error = importKeyInternal(alias, args, format, keyData, uid, flags,
- outCharacteristics);
- if (error == KEY_ALREADY_EXISTS) {
- mBinder.del(alias, uid);
- error = importKeyInternal(alias, args, format, keyData, uid, flags,
- outCharacteristics);
- }
- return error;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- } catch (ExecutionException e) {
- Log.e(TAG, "ImportKey completed with exception", e);
- return SYSTEM_ERROR;
- }
- }
-
- public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData,
- int flags, KeyCharacteristics outCharacteristics) {
- return importKey(alias, args, format, keyData, UID_SELF, flags, outCharacteristics);
- }
-
- private String getAlgorithmFromPKCS8(byte[] keyData) {
- try {
- final ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(keyData));
- final PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
- final String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
- return new AlgorithmId(new ObjectIdentifier(algOid)).getName();
- } catch (IOException e) {
- Log.e(TAG, "getAlgorithmFromPKCS8 Failed to parse key data");
- Log.e(TAG, Log.getStackTraceString(e));
- return null;
- }
- }
-
- private KeymasterArguments makeLegacyArguments(String algorithm) {
- KeymasterArguments args = new KeymasterArguments();
- args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM,
- KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(algorithm));
- args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_SIGN);
- args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_VERIFY);
- args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- if (algorithm.equalsIgnoreCase(KeyProperties.KEY_ALGORITHM_RSA)) {
- args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_OAEP);
- args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
- args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
- args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PSS);
- }
- args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_NONE);
- args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_MD5);
- args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA1);
- args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_224);
- args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_256);
- args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_384);
- args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_512);
- args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
- args.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, new Date(Long.MAX_VALUE));
- args.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, new Date(Long.MAX_VALUE));
- args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, new Date(0));
- return args;
- }
-
- public boolean importKey(String alias, byte[] keyData, int uid, int flags) {
- String algorithm = getAlgorithmFromPKCS8(keyData);
- if (algorithm == null) return false;
- KeymasterArguments args = makeLegacyArguments(algorithm);
- KeyCharacteristics out = new KeyCharacteristics();
- int result = importKey(alias, args, KeymasterDefs.KM_KEY_FORMAT_PKCS8, keyData, uid,
- flags, out);
- if (result != NO_ERROR) {
- Log.e(TAG, Log.getStackTraceString(
- new KeyStoreException(result, "legacy key import failed")));
- return false;
- }
return true;
}
- private int importWrappedKeyInternal(String wrappedKeyAlias, byte[] wrappedKey,
- String wrappingKeyAlias,
- byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid,
- KeyCharacteristics outCharacteristics)
- throws RemoteException, ExecutionException {
- KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
- mBinder.asBinder().linkToDeath(promise, 0);
- try {
- int error = mBinder.importWrappedKey(promise, wrappedKeyAlias, wrappedKey,
- wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid);
- if (error != NO_ERROR) return error;
-
- KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());
-
- error = result.getKeystoreResponse().getErrorCode();
- if (error != NO_ERROR) return error;
-
- KeyCharacteristics characteristics = result.getKeyCharacteristics();
- if (characteristics == null) return SYSTEM_ERROR;
- outCharacteristics.shallowCopyFrom(characteristics);
- return NO_ERROR;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
-
- public int importWrappedKey(String wrappedKeyAlias, byte[] wrappedKey,
- String wrappingKeyAlias,
- byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid, int uid,
- KeyCharacteristics outCharacteristics) {
- // TODO b/119217337 uid parameter gets silently ignored.
- try {
- int error = importWrappedKeyInternal(wrappedKeyAlias, wrappedKey, wrappingKeyAlias,
- maskingKey, args, rootSid, fingerprintSid, outCharacteristics);
- if (error == KEY_ALREADY_EXISTS) {
- mBinder.del(wrappedKeyAlias, UID_SELF);
- error = importWrappedKeyInternal(wrappedKeyAlias, wrappedKey, wrappingKeyAlias,
- maskingKey, args, rootSid, fingerprintSid, outCharacteristics);
- }
- return error;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- } catch (ExecutionException e) {
- Log.e(TAG, "ImportWrappedKey completed with exception", e);
- return SYSTEM_ERROR;
- }
- }
-
- private class ExportKeyPromise
- extends android.security.keystore.IKeystoreExportKeyCallback.Stub
- implements IBinder.DeathRecipient {
- final private CompletableFuture<ExportResult> future = new CompletableFuture<ExportResult>();
- @Override
- public void onFinished(ExportResult exportKeyResult) throws android.os.RemoteException {
- future.complete(exportKeyResult);
- }
- public final CompletableFuture<ExportResult> getFuture() {
- return future;
- }
- @Override
- public void binderDied() {
- future.completeExceptionally(new RemoteException("Keystore died"));
- }
- };
-
- public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
- KeymasterBlob appId, int uid) {
- ExportKeyPromise promise = new ExportKeyPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- clientId = clientId != null ? clientId : new KeymasterBlob(new byte[0]);
- appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
- int error = mBinder.exportKey(promise, alias, format, clientId, appId, uid);
- if (error == NO_ERROR) {
- return interruptedPreservingGet(promise.getFuture());
- } else {
- return new ExportResult(error);
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- } catch (ExecutionException e) {
- Log.e(TAG, "ExportKey completed with exception", e);
- return null;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
- public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
- KeymasterBlob appId) {
- return exportKey(alias, format, clientId, appId, UID_SELF);
- }
-
- private class OperationPromise
- extends android.security.keystore.IKeystoreOperationResultCallback.Stub
- implements IBinder.DeathRecipient {
- final private CompletableFuture<OperationResult> future = new CompletableFuture<OperationResult>();
- @Override
- public void onFinished(OperationResult operationResult) throws android.os.RemoteException {
- future.complete(operationResult);
- }
- public final CompletableFuture<OperationResult> getFuture() {
- return future;
- }
- @Override
- public void binderDied() {
- future.completeExceptionally(new RemoteException("Keystore died"));
- }
- };
-
- public OperationResult begin(String alias, int purpose, boolean pruneable,
- KeymasterArguments args, byte[] entropy, int uid) {
- OperationPromise promise = new OperationPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- args = args != null ? args : new KeymasterArguments();
- entropy = entropy != null ? entropy : new byte[0];
- int errorCode = mBinder.begin(promise, getToken(), alias, purpose, pruneable, args,
- entropy, uid);
- if (errorCode == NO_ERROR) {
- return interruptedPreservingGet(promise.getFuture());
- } else {
- return new OperationResult(errorCode);
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- } catch (ExecutionException e) {
- Log.e(TAG, "Begin completed with exception", e);
- return null;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
-
- public OperationResult begin(String alias, int purpose, boolean pruneable,
- KeymasterArguments args, byte[] entropy) {
- entropy = entropy != null ? entropy : new byte[0];
- args = args != null ? args : new KeymasterArguments();
- return begin(alias, purpose, pruneable, args, entropy, UID_SELF);
- }
-
- public OperationResult update(IBinder token, KeymasterArguments arguments, byte[] input) {
- OperationPromise promise = new OperationPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- arguments = arguments != null ? arguments : new KeymasterArguments();
- input = input != null ? input : new byte[0];
- int errorCode = mBinder.update(promise, token, arguments, input);
- if (errorCode == NO_ERROR) {
- return interruptedPreservingGet(promise.getFuture());
- } else {
- return new OperationResult(errorCode);
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- } catch (ExecutionException e) {
- Log.e(TAG, "Update completed with exception", e);
- return null;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
-
/**
- * Android KeyStore finish operation.
- *
- * @param token Authentication token.
- * @param arguments Keymaster arguments
- * @param input Optional additional input data.
- * @param signature Optional signature to be verified.
- * @param entropy Optional additional entropy
- * @return OperationResult that will indicate success or error of the operation.
+ * Forwards the request to clear a UID to Keystore 2.0.
+ * @hide
*/
- public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] input,
- byte[] signature, byte[] entropy) {
- OperationPromise promise = new OperationPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- arguments = arguments != null ? arguments : new KeymasterArguments();
- entropy = entropy != null ? entropy : new byte[0];
- input = input != null ? input : new byte[0];
- signature = signature != null ? signature : new byte[0];
- int errorCode = mBinder.finish(promise, token, arguments, input, signature, entropy);
- if (errorCode == NO_ERROR) {
- return interruptedPreservingGet(promise.getFuture());
- } else {
- return new OperationResult(errorCode);
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- } catch (ExecutionException e) {
- Log.e(TAG, "Finish completed with exception", e);
- return null;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
-
- public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature) {
- return finish(token, arguments, null, signature, null);
+ public boolean clearUid(int uid) {
+ return AndroidKeyStoreMaintenance.clearNamespace(Domain.APP, uid) == 0;
}
- private class KeystoreResultPromise
- extends android.security.keystore.IKeystoreResponseCallback.Stub
- implements IBinder.DeathRecipient {
- final private CompletableFuture<KeystoreResponse> future = new CompletableFuture<KeystoreResponse>();
- @Override
- public void onFinished(KeystoreResponse keystoreResponse) throws android.os.RemoteException {
- future.complete(keystoreResponse);
- }
- public final CompletableFuture<KeystoreResponse> getFuture() {
- return future;
- }
- @Override
- public void binderDied() {
- future.completeExceptionally(new RemoteException("Keystore died"));
- }
- };
-
- public int abort(IBinder token) {
- KeystoreResultPromise promise = new KeystoreResultPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- int errorCode = mBinder.abort(promise, token);
- if (errorCode == NO_ERROR) {
- return interruptedPreservingGet(promise.getFuture()).getErrorCode();
- } else {
- return errorCode;
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- } catch (ExecutionException e) {
- Log.e(TAG, "Abort completed with exception", e);
- return SYSTEM_ERROR;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
/**
* Add an authentication record to the keystore authorization table.
@@ -1013,191 +136,7 @@ public class KeyStore {
* a {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode.
*/
public int addAuthToken(byte[] authToken) {
- try {
- Authorization.addAuthToken(authToken);
- return mBinder.addAuthToken(authToken);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- }
- }
-
- /**
- * Notify keystore that a user's password has changed.
- *
- * @param userId the user whose password changed.
- * @param newPassword the new password or "" if the password was removed.
- */
- public boolean onUserPasswordChanged(int userId, String newPassword) {
- // Parcel.cpp doesn't support deserializing null strings and treats them as "". Make that
- // explicit here.
- if (newPassword == null) {
- newPassword = "";
- }
- try {
- return mBinder.onUserPasswordChanged(userId, newPassword) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- /**
- * Notify keystore that a user was added.
- *
- * @param userId the new user.
- * @param parentId the parent of the new user, or -1 if the user has no parent. If parentId is
- * specified then the new user's keystore will be intialized with the same secure lockscreen
- * password as the parent.
- */
- public void onUserAdded(int userId, int parentId) {
- try {
- mBinder.onUserAdded(userId, parentId);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- }
- }
-
- /**
- * Notify keystore that a user was added.
- *
- * @param userId the new user.
- */
- public void onUserAdded(int userId) {
- onUserAdded(userId, -1);
- }
-
- /**
- * Notify keystore that a user was removed.
- *
- * @param userId the removed user.
- */
- public void onUserRemoved(int userId) {
- try {
- mBinder.onUserRemoved(userId);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- }
- }
-
- public boolean onUserPasswordChanged(String newPassword) {
- return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword);
- }
-
- /**
- * Notify keystore about the latest user locked state. This is to support keyguard-bound key.
- */
- public void onUserLockedStateChanged(int userHandle, boolean locked) {
- try {
- mBinder.onKeyguardVisibilityChanged(locked, userHandle);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to update user locked state " + userHandle, e);
- }
- }
-
- private class KeyAttestationCallbackResult {
- private KeystoreResponse keystoreResponse;
- private KeymasterCertificateChain certificateChain;
-
- public KeyAttestationCallbackResult(KeystoreResponse keystoreResponse,
- KeymasterCertificateChain certificateChain) {
- this.keystoreResponse = keystoreResponse;
- this.certificateChain = certificateChain;
- }
-
- public KeystoreResponse getKeystoreResponse() {
- return keystoreResponse;
- }
-
- public void setKeystoreResponse(KeystoreResponse keystoreResponse) {
- this.keystoreResponse = keystoreResponse;
- }
-
- public KeymasterCertificateChain getCertificateChain() {
- return certificateChain;
- }
-
- public void setCertificateChain(KeymasterCertificateChain certificateChain) {
- this.certificateChain = certificateChain;
- }
- }
-
- private class CertificateChainPromise
- extends android.security.keystore.IKeystoreCertificateChainCallback.Stub
- implements IBinder.DeathRecipient {
- final private CompletableFuture<KeyAttestationCallbackResult> future = new CompletableFuture<KeyAttestationCallbackResult>();
- @Override
- public void onFinished(KeystoreResponse keystoreResponse,
- KeymasterCertificateChain certificateChain) throws android.os.RemoteException {
- future.complete(new KeyAttestationCallbackResult(keystoreResponse, certificateChain));
- }
- public final CompletableFuture<KeyAttestationCallbackResult> getFuture() {
- return future;
- }
- @Override
- public void binderDied() {
- future.completeExceptionally(new RemoteException("Keystore died"));
- }
- };
-
-
- public int attestKey(
- String alias, KeymasterArguments params, KeymasterCertificateChain outChain) {
- CertificateChainPromise promise = new CertificateChainPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- if (params == null) {
- params = new KeymasterArguments();
- }
- if (outChain == null) {
- outChain = new KeymasterCertificateChain();
- }
- int error = mBinder.attestKey(promise, alias, params);
- if (error != NO_ERROR) return error;
- KeyAttestationCallbackResult result = interruptedPreservingGet(promise.getFuture());
- error = result.getKeystoreResponse().getErrorCode();
- if (error == NO_ERROR) {
- outChain.shallowCopyFrom(result.getCertificateChain());
- }
- return error;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- } catch (ExecutionException e) {
- Log.e(TAG, "AttestKey completed with exception", e);
- return SYSTEM_ERROR;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
- }
-
- public int attestDeviceIds(KeymasterArguments params, KeymasterCertificateChain outChain) {
- CertificateChainPromise promise = new CertificateChainPromise();
- try {
- mBinder.asBinder().linkToDeath(promise, 0);
- if (params == null) {
- params = new KeymasterArguments();
- }
- if (outChain == null) {
- outChain = new KeymasterCertificateChain();
- }
- int error = mBinder.attestDeviceIds(promise, params);
- if (error != NO_ERROR) return error;
- KeyAttestationCallbackResult result = interruptedPreservingGet(promise.getFuture());
- error = result.getKeystoreResponse().getErrorCode();
- if (error == NO_ERROR) {
- outChain.shallowCopyFrom(result.getCertificateChain());
- }
- return error;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return SYSTEM_ERROR;
- } catch (ExecutionException e) {
- Log.e(TAG, "AttestDevicdeIds completed with exception", e);
- return SYSTEM_ERROR;
- } finally {
- mBinder.asBinder().unlinkToDeath(promise, 0);
- }
+ return Authorization.addAuthToken(authToken);
}
/**
@@ -1205,77 +144,6 @@ public class KeyStore {
*/
public void onDeviceOffBody() {
AndroidKeyStoreMaintenance.onDeviceOffBody();
- try {
- mBinder.onDeviceOffBody();
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- }
- }
-
- // Keep in sync with confirmationui/1.0/types.hal.
- public static final int CONFIRMATIONUI_OK = 0;
- public static final int CONFIRMATIONUI_CANCELED = 1;
- public static final int CONFIRMATIONUI_ABORTED = 2;
- public static final int CONFIRMATIONUI_OPERATION_PENDING = 3;
- public static final int CONFIRMATIONUI_IGNORED = 4;
- public static final int CONFIRMATIONUI_SYSTEM_ERROR = 5;
- public static final int CONFIRMATIONUI_UNIMPLEMENTED = 6;
- public static final int CONFIRMATIONUI_UNEXPECTED = 7;
- public static final int CONFIRMATIONUI_UIERROR = 0x10000;
- public static final int CONFIRMATIONUI_UIERROR_MISSING_GLYPH = 0x10001;
- public static final int CONFIRMATIONUI_UIERROR_MESSAGE_TOO_LONG = 0x10002;
- public static final int CONFIRMATIONUI_UIERROR_MALFORMED_UTF8_ENCODING = 0x10003;
-
- /**
- * Requests keystore call into the confirmationui HAL to display a prompt.
- *
- * @param listener the binder to use for callbacks.
- * @param promptText the prompt to display.
- * @param extraData extra data / nonce from application.
- * @param locale the locale as a BCP 47 langauge tag.
- * @param uiOptionsAsFlags the UI options to use, as flags.
- * @return one of the {@code CONFIRMATIONUI_*} constants, for
- * example {@code KeyStore.CONFIRMATIONUI_OK}.
- */
- public int presentConfirmationPrompt(IBinder listener, String promptText, byte[] extraData,
- String locale, int uiOptionsAsFlags) {
- try {
- return mBinder.presentConfirmationPrompt(listener, promptText, extraData, locale,
- uiOptionsAsFlags);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return CONFIRMATIONUI_SYSTEM_ERROR;
- }
- }
-
- /**
- * Requests keystore call into the confirmationui HAL to cancel displaying a prompt.
- *
- * @param listener the binder passed to the {@link #presentConfirmationPrompt} method.
- * @return one of the {@code CONFIRMATIONUI_*} constants, for
- * example {@code KeyStore.CONFIRMATIONUI_OK}.
- */
- public int cancelConfirmationPrompt(IBinder listener) {
- try {
- return mBinder.cancelConfirmationPrompt(listener);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return CONFIRMATIONUI_SYSTEM_ERROR;
- }
- }
-
- /**
- * Requests keystore to check if the confirmationui HAL is available.
- *
- * @return whether the confirmationUI HAL is available.
- */
- public boolean isConfirmationPromptSupported() {
- try {
- return mBinder.isConfirmationPromptSupported();
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
}
/**
@@ -1284,143 +152,6 @@ public class KeyStore {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static KeyStoreException getKeyStoreException(int errorCode) {
- if (errorCode > 0) {
- // KeyStore layer error
- switch (errorCode) {
- case NO_ERROR:
- return new KeyStoreException(errorCode, "OK");
- case LOCKED:
- return new KeyStoreException(errorCode, "User authentication required");
- case UNINITIALIZED:
- return new KeyStoreException(errorCode, "Keystore not initialized");
- case SYSTEM_ERROR:
- return new KeyStoreException(errorCode, "System error");
- case PERMISSION_DENIED:
- return new KeyStoreException(errorCode, "Permission denied");
- case KEY_NOT_FOUND:
- return new KeyStoreException(errorCode, "Key not found");
- case VALUE_CORRUPTED:
- return new KeyStoreException(errorCode, "Key blob corrupted");
- case OP_AUTH_NEEDED:
- return new KeyStoreException(errorCode, "Operation requires authorization");
- case KEY_PERMANENTLY_INVALIDATED:
- return new KeyStoreException(errorCode, "Key permanently invalidated");
- default:
- return new KeyStoreException(errorCode, String.valueOf(errorCode));
- }
- } else {
- // Keymaster layer error
- switch (errorCode) {
- case KeymasterDefs.KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT:
- // The name of this parameter significantly differs between Keymaster and
- // framework APIs. Use the framework wording to make life easier for developers.
- return new KeyStoreException(errorCode,
- "Invalid user authentication validity duration");
- default:
- return new KeyStoreException(errorCode,
- KeymasterDefs.getErrorMessage(errorCode));
- }
- }
- }
-
- /**
- * Returns an {@link InvalidKeyException} corresponding to the provided
- * {@link KeyStoreException}.
- */
- public InvalidKeyException getInvalidKeyException(
- String keystoreKeyAlias, int uid, KeyStoreException e) {
- switch (e.getErrorCode()) {
- case LOCKED:
- return new UserNotAuthenticatedException();
- case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
- return new KeyExpiredException();
- case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID:
- return new KeyNotYetValidException();
- case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
- case OP_AUTH_NEEDED:
- {
- // We now need to determine whether the key/operation can become usable if user
- // authentication is performed, or whether it can never become usable again.
- // User authentication requirements are contained in the key's characteristics. We
- // need to check whether these requirements can be be satisfied by asking the user
- // to authenticate.
- KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
- int getKeyCharacteristicsErrorCode =
- getKeyCharacteristics(keystoreKeyAlias, null, null, uid,
- keyCharacteristics);
- if (getKeyCharacteristicsErrorCode != NO_ERROR) {
- return new InvalidKeyException(
- "Failed to obtained key characteristics",
- getKeyStoreException(getKeyCharacteristicsErrorCode));
- }
- List<BigInteger> keySids =
- keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
- if (keySids.isEmpty()) {
- // Key is not bound to any SIDs -- no amount of authentication will help here.
- return new KeyPermanentlyInvalidatedException();
- }
- long rootSid = GateKeeper.getSecureUserId();
- if ((rootSid != 0) && (keySids.contains(KeymasterArguments.toUint64(rootSid)))) {
- // One of the key's SIDs is the current root SID -- user can be authenticated
- // against that SID.
- return new UserNotAuthenticatedException();
- }
-
- final BiometricManager bm = mContext.getSystemService(BiometricManager.class);
- long[] biometricSids = bm.getAuthenticatorIds();
-
- // The key must contain every biometric SID. This is because the current API surface
- // treats all biometrics (capable of keystore integration) equally. e.g. if the
- // device has multiple keystore-capable sensors, and one of the sensor's SIDs
- // changed, 1) there is no way for a developer to specify authentication with a
- // specific sensor (the one that hasn't changed), and 2) currently the only
- // signal to developers is the UserNotAuthenticatedException, which doesn't
- // indicate a specific sensor.
- boolean canUnlockViaBiometrics = true;
- for (long sid : biometricSids) {
- if (!keySids.contains(KeymasterArguments.toUint64(sid))) {
- canUnlockViaBiometrics = false;
- break;
- }
- }
-
- if (canUnlockViaBiometrics) {
- // All of the biometric SIDs are contained in the key's SIDs.
- return new UserNotAuthenticatedException();
- }
-
- // None of the key's SIDs can ever be authenticated
- return new KeyPermanentlyInvalidatedException();
- }
- case UNINITIALIZED:
- return new KeyPermanentlyInvalidatedException();
- default:
- return new InvalidKeyException("Keystore operation failed", e);
- }
- }
-
- /**
- * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error
- * code.
- */
- public InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int uid,
- int errorCode) {
- return getInvalidKeyException(keystoreKeyAlias, uid, getKeyStoreException(errorCode));
- }
-
- private static <R> R interruptedPreservingGet(CompletableFuture<R> future)
- throws ExecutionException {
- boolean wasInterrupted = false;
- while (true) {
- try {
- R result = future.get();
- if (wasInterrupted) {
- Thread.currentThread().interrupt();
- }
- return result;
- } catch (InterruptedException e) {
- wasInterrupted = true;
- }
- }
+ return new KeyStoreException(-10000, "Should not be called.");
}
}
diff --git a/keystore/java/android/security/LegacyVpnProfileStore.java b/keystore/java/android/security/LegacyVpnProfileStore.java
index 41cfb2707fcf..1d2738e71311 100644
--- a/keystore/java/android/security/LegacyVpnProfileStore.java
+++ b/keystore/java/android/security/LegacyVpnProfileStore.java
@@ -19,7 +19,6 @@ package android.security;
import android.annotation.NonNull;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
-import android.security.keystore.AndroidKeyStoreProvider;
import android.security.vpnprofilestore.IVpnProfileStore;
import android.util.Log;
@@ -53,13 +52,8 @@ public class LegacyVpnProfileStore {
*/
public static boolean put(@NonNull String alias, @NonNull byte[] profile) {
try {
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- getService().put(alias, profile);
- return true;
- } else {
- return KeyStore.getInstance().put(
- alias, profile, KeyStore.UID_SELF, 0);
- }
+ getService().put(alias, profile);
+ return true;
} catch (Exception e) {
Log.e(TAG, "Failed to put vpn profile.", e);
return false;
@@ -77,11 +71,7 @@ public class LegacyVpnProfileStore {
*/
public static byte[] get(@NonNull String alias) {
try {
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- return getService().get(alias);
- } else {
- return KeyStore.getInstance().get(alias, true /* suppressKeyNotFoundWarning */);
- }
+ return getService().get(alias);
} catch (ServiceSpecificException e) {
if (e.errorCode != PROFILE_NOT_FOUND) {
Log.e(TAG, "Failed to get vpn profile.", e);
@@ -100,12 +90,8 @@ public class LegacyVpnProfileStore {
*/
public static boolean remove(@NonNull String alias) {
try {
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- getService().remove(alias);
- return true;
- } else {
- return KeyStore.getInstance().delete(alias);
- }
+ getService().remove(alias);
+ return true;
} catch (ServiceSpecificException e) {
if (e.errorCode != PROFILE_NOT_FOUND) {
Log.e(TAG, "Failed to remove vpn profile.", e);
@@ -124,16 +110,11 @@ public class LegacyVpnProfileStore {
*/
public static @NonNull String[] list(@NonNull String prefix) {
try {
- if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
- final String[] aliases = getService().list(prefix);
- for (int i = 0; i < aliases.length; ++i) {
- aliases[i] = aliases[i].substring(prefix.length());
- }
- return aliases;
- } else {
- final String[] result = KeyStore.getInstance().list(prefix);
- return result != null ? result : new String[0];
+ final String[] aliases = getService().list(prefix);
+ for (int i = 0; i < aliases.length; ++i) {
+ aliases[i] = aliases[i].substring(prefix.length());
}
+ return aliases;
} catch (Exception e) {
Log.e(TAG, "Failed to list vpn profiles.", e);
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStore3DESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStore3DESCipherSpi.java
deleted file mode 100644
index 01fd0624572c..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStore3DESCipherSpi.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-import java.util.Arrays;
-
-import javax.crypto.CipherSpi;
-import javax.crypto.spec.IvParameterSpec;
-
-/**
- * Base class for Android Keystore 3DES {@link CipherSpi} implementations.
- *
- * @hide
- */
-public class AndroidKeyStore3DESCipherSpi extends AndroidKeyStoreCipherSpiBase {
-
- private static final int BLOCK_SIZE_BYTES = 8;
-
- private final int mKeymasterBlockMode;
- private final int mKeymasterPadding;
- /** Whether this transformation requires an IV. */
- private final boolean mIvRequired;
-
- private byte[] mIv;
-
- /** Whether the current {@code #mIv} has been used by the underlying crypto operation. */
- private boolean mIvHasBeenUsed;
-
- AndroidKeyStore3DESCipherSpi(
- int keymasterBlockMode,
- int keymasterPadding,
- boolean ivRequired) {
- mKeymasterBlockMode = keymasterBlockMode;
- mKeymasterPadding = keymasterPadding;
- mIvRequired = ivRequired;
- }
-
- abstract static class ECB extends AndroidKeyStore3DESCipherSpi {
- protected ECB(int keymasterPadding) {
- super(KeymasterDefs.KM_MODE_ECB, keymasterPadding, false);
- }
-
- public static class NoPadding extends ECB {
- public NoPadding() {
- super(KeymasterDefs.KM_PAD_NONE);
- }
- }
-
- public static class PKCS7Padding extends ECB {
- public PKCS7Padding() {
- super(KeymasterDefs.KM_PAD_PKCS7);
- }
- }
- }
-
- abstract static class CBC extends AndroidKeyStore3DESCipherSpi {
- protected CBC(int keymasterPadding) {
- super(KeymasterDefs.KM_MODE_CBC, keymasterPadding, true);
- }
-
- public static class NoPadding extends CBC {
- public NoPadding() {
- super(KeymasterDefs.KM_PAD_NONE);
- }
- }
-
- public static class PKCS7Padding extends CBC {
- public PKCS7Padding() {
- super(KeymasterDefs.KM_PAD_PKCS7);
- }
- }
- }
-
- @Override
- protected void initKey(int i, Key key) throws InvalidKeyException {
- if (!(key instanceof AndroidKeyStoreSecretKey)) {
- throw new InvalidKeyException(
- "Unsupported key: " + ((key != null) ? key.getClass().getName() : "null"));
- }
- if (!KeyProperties.KEY_ALGORITHM_3DES.equalsIgnoreCase(key.getAlgorithm())) {
- throw new InvalidKeyException(
- "Unsupported key algorithm: " + key.getAlgorithm() + ". Only " +
- KeyProperties.KEY_ALGORITHM_3DES + " supported");
- }
- setKey((AndroidKeyStoreSecretKey) key);
- }
-
- @Override
- protected int engineGetBlockSize() {
- return BLOCK_SIZE_BYTES;
- }
-
- @Override
- protected int engineGetOutputSize(int inputLen) {
- return inputLen + 3 * BLOCK_SIZE_BYTES;
- }
-
- @Override
- protected final byte[] engineGetIV() {
- return ArrayUtils.cloneIfNotEmpty(mIv);
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- if (!mIvRequired) {
- return null;
- }
- if ((mIv != null) && (mIv.length > 0)) {
- try {
- AlgorithmParameters params = AlgorithmParameters.getInstance("DESede");
- params.init(new IvParameterSpec(mIv));
- return params;
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(
- "Failed to obtain 3DES AlgorithmParameters", e);
- } catch (InvalidParameterSpecException e) {
- throw new ProviderException(
- "Failed to initialize 3DES AlgorithmParameters with an IV",
- e);
- }
- }
- return null;
- }
-
- @Override
- protected void initAlgorithmSpecificParameters() throws InvalidKeyException {
- if (!mIvRequired) {
- return;
- }
-
- // IV is used
- if (!isEncrypting()) {
- throw new InvalidKeyException("IV required when decrypting"
- + ". Use IvParameterSpec or AlgorithmParameters to provide it.");
- }
- }
-
- @Override
- protected void initAlgorithmSpecificParameters(AlgorithmParameterSpec params)
- throws InvalidAlgorithmParameterException {
- if (!mIvRequired) {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("Unsupported parameters: " + params);
- }
- return;
- }
-
- // IV is used
- if (params == null) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException(
- "IvParameterSpec must be provided when decrypting");
- }
- return;
- }
- if (!(params instanceof IvParameterSpec)) {
- throw new InvalidAlgorithmParameterException("Only IvParameterSpec supported");
- }
- mIv = ((IvParameterSpec) params).getIV();
- if (mIv == null) {
- throw new InvalidAlgorithmParameterException("Null IV in IvParameterSpec");
- }
- }
-
- @Override
- protected void initAlgorithmSpecificParameters(AlgorithmParameters params)
- throws InvalidAlgorithmParameterException {
- if (!mIvRequired) {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("Unsupported parameters: " + params);
- }
- return;
- }
-
- // IV is used
- if (params == null) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException("IV required when decrypting"
- + ". Use IvParameterSpec or AlgorithmParameters to provide it.");
- }
- return;
- }
-
- if (!"DESede".equalsIgnoreCase(params.getAlgorithm())) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported AlgorithmParameters algorithm: " + params.getAlgorithm()
- + ". Supported: DESede");
- }
-
- IvParameterSpec ivSpec;
- try {
- ivSpec = params.getParameterSpec(IvParameterSpec.class);
- } catch (InvalidParameterSpecException e) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException("IV required when decrypting"
- + ", but not found in parameters: " + params, e);
- }
- mIv = null;
- return;
- }
- mIv = ivSpec.getIV();
- if (mIv == null) {
- throw new InvalidAlgorithmParameterException("Null IV in AlgorithmParameters");
- }
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForBegin() {
- if ((mIvRequired) && (mIv == null) && (isEncrypting())) {
- // IV will need to be generated
- return BLOCK_SIZE_BYTES;
- }
-
- return 0;
- }
-
- @Override
- protected int getAdditionalEntropyAmountForFinish() {
- return 0;
- }
-
- @Override
- protected void addAlgorithmSpecificParametersToBegin(KeymasterArguments keymasterArgs) {
- if ((isEncrypting()) && (mIvRequired) && (mIvHasBeenUsed)) {
- // IV is being reused for encryption: this violates security best practices.
- throw new IllegalStateException(
- "IV has already been used. Reusing IV in encryption mode violates security best"
- + " practices.");
- }
-
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_3DES);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
- if ((mIvRequired) && (mIv != null)) {
- keymasterArgs.addBytes(KeymasterDefs.KM_TAG_NONCE, mIv);
- }
- }
-
- @Override
- protected void loadAlgorithmSpecificParametersFromBeginResult(
- KeymasterArguments keymasterArgs) {
- mIvHasBeenUsed = true;
-
- // NOTE: Keymaster doesn't always return an IV, even if it's used.
- byte[] returnedIv = keymasterArgs.getBytes(KeymasterDefs.KM_TAG_NONCE, null);
- if ((returnedIv != null) && (returnedIv.length == 0)) {
- returnedIv = null;
- }
-
- if (mIvRequired) {
- if (mIv == null) {
- mIv = returnedIv;
- } else if ((returnedIv != null) && (!Arrays.equals(returnedIv, mIv))) {
- throw new ProviderException("IV in use differs from provided IV");
- }
- } else {
- if (returnedIv != null) {
- throw new ProviderException(
- "IV in use despite IV not being used by this transformation");
- }
- }
- }
-
- @Override
- protected final void resetAll() {
- mIv = null;
- mIvHasBeenUsed = false;
- super.resetAll();
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
deleted file mode 100644
index feb6101cb080..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.IBinder;
-import android.security.KeyStore;
-import android.security.KeyStoreException;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keymaster.OperationResult;
-import android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.Stream;
-
-import libcore.util.EmptyArray;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-import java.util.Arrays;
-
-import javax.crypto.CipherSpi;
-import javax.crypto.spec.GCMParameterSpec;
-
-/**
- * Base class for Android Keystore authenticated AES {@link CipherSpi} implementations.
- *
- * @hide
- */
-abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreCipherSpiBase {
-
- abstract static class GCM extends AndroidKeyStoreAuthenticatedAESCipherSpi {
- static final int MIN_SUPPORTED_TAG_LENGTH_BITS = 96;
- private static final int MAX_SUPPORTED_TAG_LENGTH_BITS = 128;
- private static final int DEFAULT_TAG_LENGTH_BITS = 128;
- private static final int IV_LENGTH_BYTES = 12;
-
- private int mTagLengthBits = DEFAULT_TAG_LENGTH_BITS;
-
- GCM(int keymasterPadding) {
- super(KeymasterDefs.KM_MODE_GCM, keymasterPadding);
- }
-
- @Override
- protected final void resetAll() {
- mTagLengthBits = DEFAULT_TAG_LENGTH_BITS;
- super.resetAll();
- }
-
- @Override
- protected final void resetWhilePreservingInitState() {
- super.resetWhilePreservingInitState();
- }
-
- @Override
- protected final void initAlgorithmSpecificParameters() throws InvalidKeyException {
- if (!isEncrypting()) {
- throw new InvalidKeyException("IV required when decrypting"
- + ". Use IvParameterSpec or AlgorithmParameters to provide it.");
- }
- }
-
- @Override
- protected final void initAlgorithmSpecificParameters(AlgorithmParameterSpec params)
- throws InvalidAlgorithmParameterException {
- // IV is used
- if (params == null) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException(
- "GCMParameterSpec must be provided when decrypting");
- }
- return;
- }
- if (!(params instanceof GCMParameterSpec)) {
- throw new InvalidAlgorithmParameterException("Only GCMParameterSpec supported");
- }
- GCMParameterSpec spec = (GCMParameterSpec) params;
- byte[] iv = spec.getIV();
- if (iv == null) {
- throw new InvalidAlgorithmParameterException("Null IV in GCMParameterSpec");
- } else if (iv.length != IV_LENGTH_BYTES) {
- throw new InvalidAlgorithmParameterException("Unsupported IV length: "
- + iv.length + " bytes. Only " + IV_LENGTH_BYTES
- + " bytes long IV supported");
- }
- int tagLengthBits = spec.getTLen();
- if ((tagLengthBits < MIN_SUPPORTED_TAG_LENGTH_BITS)
- || (tagLengthBits > MAX_SUPPORTED_TAG_LENGTH_BITS)
- || ((tagLengthBits % 8) != 0)) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported tag length: " + tagLengthBits + " bits"
- + ". Supported lengths: 96, 104, 112, 120, 128");
- }
- setIv(iv);
- mTagLengthBits = tagLengthBits;
- }
-
- @Override
- protected final void initAlgorithmSpecificParameters(AlgorithmParameters params)
- throws InvalidAlgorithmParameterException {
- if (params == null) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException("IV required when decrypting"
- + ". Use GCMParameterSpec or GCM AlgorithmParameters to provide it.");
- }
- return;
- }
-
- if (!"GCM".equalsIgnoreCase(params.getAlgorithm())) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported AlgorithmParameters algorithm: " + params.getAlgorithm()
- + ". Supported: GCM");
- }
-
- GCMParameterSpec spec;
- try {
- spec = params.getParameterSpec(GCMParameterSpec.class);
- } catch (InvalidParameterSpecException e) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException("IV and tag length required when"
- + " decrypting, but not found in parameters: " + params, e);
- }
- setIv(null);
- return;
- }
- initAlgorithmSpecificParameters(spec);
- }
-
- @Nullable
- @Override
- protected final AlgorithmParameters engineGetParameters() {
- byte[] iv = getIv();
- if ((iv != null) && (iv.length > 0)) {
- try {
- AlgorithmParameters params = AlgorithmParameters.getInstance("GCM");
- params.init(new GCMParameterSpec(mTagLengthBits, iv));
- return params;
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(
- "Failed to obtain GCM AlgorithmParameters", e);
- } catch (InvalidParameterSpecException e) {
- throw new ProviderException(
- "Failed to initialize GCM AlgorithmParameters", e);
- }
- }
- return null;
- }
-
- @NonNull
- @Override
- protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
- KeyStore keyStore, IBinder operationToken) {
- KeyStoreCryptoOperationStreamer streamer = new KeyStoreCryptoOperationChunkedStreamer(
- new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
- keyStore, operationToken), 0);
- if (isEncrypting()) {
- return streamer;
- } else {
- // When decrypting, to avoid leaking unauthenticated plaintext, do not return any
- // plaintext before ciphertext is authenticated by KeyStore.finish.
- return new BufferAllOutputUntilDoFinalStreamer(streamer);
- }
- }
-
- @NonNull
- @Override
- protected final KeyStoreCryptoOperationStreamer createAdditionalAuthenticationDataStreamer(
- KeyStore keyStore, IBinder operationToken) {
- return new KeyStoreCryptoOperationChunkedStreamer(
- new AdditionalAuthenticationDataStream(keyStore, operationToken), 0);
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForBegin() {
- if ((getIv() == null) && (isEncrypting())) {
- // IV will need to be generated
- return IV_LENGTH_BYTES;
- }
-
- return 0;
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForFinish() {
- return 0;
- }
-
- @Override
- protected final void addAlgorithmSpecificParametersToBegin(
- @NonNull KeymasterArguments keymasterArgs) {
- super.addAlgorithmSpecificParametersToBegin(keymasterArgs);
- keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mTagLengthBits);
- }
-
- protected final int getTagLengthBits() {
- return mTagLengthBits;
- }
-
- public static final class NoPadding extends GCM {
- public NoPadding() {
- super(KeymasterDefs.KM_PAD_NONE);
- }
-
- @Override
- protected final int engineGetOutputSize(int inputLen) {
- int tagLengthBytes = (getTagLengthBits() + 7) / 8;
- long result;
- if (isEncrypting()) {
- result = getConsumedInputSizeBytes() - getProducedOutputSizeBytes() + inputLen
- + tagLengthBytes;
- } else {
- result = getConsumedInputSizeBytes() - getProducedOutputSizeBytes() + inputLen
- - tagLengthBytes;
- }
- if (result < 0) {
- return 0;
- } else if (result > Integer.MAX_VALUE) {
- return Integer.MAX_VALUE;
- }
- return (int) result;
- }
- }
- }
-
- private static final int BLOCK_SIZE_BYTES = 16;
-
- private final int mKeymasterBlockMode;
- private final int mKeymasterPadding;
-
- private byte[] mIv;
-
- /** Whether the current {@code #mIv} has been used by the underlying crypto operation. */
- private boolean mIvHasBeenUsed;
-
- AndroidKeyStoreAuthenticatedAESCipherSpi(
- int keymasterBlockMode,
- int keymasterPadding) {
- mKeymasterBlockMode = keymasterBlockMode;
- mKeymasterPadding = keymasterPadding;
- }
-
- @Override
- protected void resetAll() {
- mIv = null;
- mIvHasBeenUsed = false;
- super.resetAll();
- }
-
- @Override
- protected final void initKey(int opmode, Key key) throws InvalidKeyException {
- if (!(key instanceof AndroidKeyStoreSecretKey)) {
- throw new InvalidKeyException(
- "Unsupported key: " + ((key != null) ? key.getClass().getName() : "null"));
- }
- if (!KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(key.getAlgorithm())) {
- throw new InvalidKeyException(
- "Unsupported key algorithm: " + key.getAlgorithm() + ". Only " +
- KeyProperties.KEY_ALGORITHM_AES + " supported");
- }
- setKey((AndroidKeyStoreSecretKey) key);
- }
-
- @Override
- protected void addAlgorithmSpecificParametersToBegin(
- @NonNull KeymasterArguments keymasterArgs) {
- if ((isEncrypting()) && (mIvHasBeenUsed)) {
- // IV is being reused for encryption: this violates security best practices.
- throw new IllegalStateException(
- "IV has already been used. Reusing IV in encryption mode violates security best"
- + " practices.");
- }
-
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
- if (mIv != null) {
- keymasterArgs.addBytes(KeymasterDefs.KM_TAG_NONCE, mIv);
- }
- }
-
- @Override
- protected final void loadAlgorithmSpecificParametersFromBeginResult(
- @NonNull KeymasterArguments keymasterArgs) {
- mIvHasBeenUsed = true;
-
- // NOTE: Keymaster doesn't always return an IV, even if it's used.
- byte[] returnedIv = keymasterArgs.getBytes(KeymasterDefs.KM_TAG_NONCE, null);
- if ((returnedIv != null) && (returnedIv.length == 0)) {
- returnedIv = null;
- }
-
- if (mIv == null) {
- mIv = returnedIv;
- } else if ((returnedIv != null) && (!Arrays.equals(returnedIv, mIv))) {
- throw new ProviderException("IV in use differs from provided IV");
- }
- }
-
- @Override
- protected final int engineGetBlockSize() {
- return BLOCK_SIZE_BYTES;
- }
-
- @Override
- protected final byte[] engineGetIV() {
- return ArrayUtils.cloneIfNotEmpty(mIv);
- }
-
- protected void setIv(byte[] iv) {
- mIv = iv;
- }
-
- protected byte[] getIv() {
- return mIv;
- }
-
- /**
- * {@link KeyStoreCryptoOperationStreamer} which buffers all output until {@code doFinal} from
- * which it returns all output in one go, provided {@code doFinal} succeeds.
- */
- private static class BufferAllOutputUntilDoFinalStreamer
- implements KeyStoreCryptoOperationStreamer {
-
- private final KeyStoreCryptoOperationStreamer mDelegate;
- private ByteArrayOutputStream mBufferedOutput = new ByteArrayOutputStream();
- private long mProducedOutputSizeBytes;
-
- private BufferAllOutputUntilDoFinalStreamer(KeyStoreCryptoOperationStreamer delegate) {
- mDelegate = delegate;
- }
-
- @Override
- public byte[] update(byte[] input, int inputOffset, int inputLength)
- throws KeyStoreException {
- byte[] output = mDelegate.update(input, inputOffset, inputLength);
- if (output != null) {
- try {
- mBufferedOutput.write(output);
- } catch (IOException e) {
- throw new ProviderException("Failed to buffer output", e);
- }
- }
- return EmptyArray.BYTE;
- }
-
- @Override
- public byte[] doFinal(byte[] input, int inputOffset, int inputLength,
- byte[] signature, byte[] additionalEntropy) throws KeyStoreException {
- byte[] output = mDelegate.doFinal(input, inputOffset, inputLength, signature,
- additionalEntropy);
- if (output != null) {
- try {
- mBufferedOutput.write(output);
- } catch (IOException e) {
- throw new ProviderException("Failed to buffer output", e);
- }
- }
- byte[] result = mBufferedOutput.toByteArray();
- mBufferedOutput.reset();
- mProducedOutputSizeBytes += result.length;
- return result;
- }
-
- @Override
- public long getConsumedInputSizeBytes() {
- return mDelegate.getConsumedInputSizeBytes();
- }
-
- @Override
- public long getProducedOutputSizeBytes() {
- return mProducedOutputSizeBytes;
- }
- }
-
- /**
- * Additional Authentication Data (AAD) stream via a KeyStore streaming operation. This stream
- * sends AAD into the KeyStore.
- */
- private static class AdditionalAuthenticationDataStream implements Stream {
-
- private final KeyStore mKeyStore;
- private final IBinder mOperationToken;
-
- private AdditionalAuthenticationDataStream(KeyStore keyStore, IBinder operationToken) {
- mKeyStore = keyStore;
- mOperationToken = operationToken;
- }
-
- @Override
- public OperationResult update(byte[] input) {
- KeymasterArguments keymasterArgs = new KeymasterArguments();
- keymasterArgs.addBytes(KeymasterDefs.KM_TAG_ASSOCIATED_DATA, input);
-
- // KeyStore does not reflect AAD in inputConsumed, but users of Stream rely on this
- // field. We fix this discrepancy here. KeyStore.update contract is that all of AAD
- // has been consumed if the method succeeds.
- OperationResult result = mKeyStore.update(mOperationToken, keymasterArgs, null);
- if (result.resultCode == KeyStore.NO_ERROR) {
- result = new OperationResult(
- result.resultCode,
- result.token,
- result.operationHandle,
- input.length, // inputConsumed
- result.output,
- result.outParams);
- }
- return result;
- }
-
- @Override
- public OperationResult finish(byte[] input, byte[] signature, byte[] additionalEntropy) {
- if ((additionalEntropy != null) && (additionalEntropy.length > 0)) {
- throw new ProviderException("AAD stream does not support additional entropy");
- }
- return new OperationResult(
- KeyStore.NO_ERROR,
- mOperationToken,
- 0, // operation handle -- nobody cares about this being returned from finish
- 0, // inputConsumed
- EmptyArray.BYTE, // output
- new KeymasterArguments() // additional params returned by finish
- );
- }
- }
-} \ No newline at end of file
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
deleted file mode 100644
index 5730234184ab..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import java.security.Provider;
-
-/**
- * {@link Provider} of JCA crypto operations operating on Android KeyStore keys.
- *
- * <p>This provider was separated out of {@link AndroidKeyStoreProvider} to work around the issue
- * that Bouncy Castle provider incorrectly declares that it accepts arbitrary keys (incl. Android
- * KeyStore ones). This causes JCA to select the Bouncy Castle's implementation of JCA crypto
- * operations for Android KeyStore keys unless Android KeyStore's own implementations are installed
- * as higher-priority than Bouncy Castle ones. The purpose of this provider is to do just that: to
- * offer crypto operations operating on Android KeyStore keys and to be installed at higher priority
- * than the Bouncy Castle provider.
- *
- * <p>Once Bouncy Castle provider is fixed, this provider can be merged into the
- * {@code AndroidKeyStoreProvider}.
- *
- * @hide
- */
-public class AndroidKeyStoreBCWorkaroundProvider extends Provider {
-
- // IMPLEMENTATION NOTE: Class names are hard-coded in this provider to avoid loading these
- // classes when this provider is instantiated and installed early on during each app's
- // initialization process.
-
- private static final String PACKAGE_NAME = "android.security.keystore";
- private static final String KEYSTORE_SECRET_KEY_CLASS_NAME =
- PACKAGE_NAME + ".AndroidKeyStoreSecretKey";
- private static final String KEYSTORE_PRIVATE_KEY_CLASS_NAME =
- PACKAGE_NAME + ".AndroidKeyStorePrivateKey";
- private static final String KEYSTORE_PUBLIC_KEY_CLASS_NAME =
- PACKAGE_NAME + ".AndroidKeyStorePublicKey";
-
- private static final String DESEDE_SYSTEM_PROPERTY = "ro.hardware.keystore_desede";
-
- /** @hide */
- public AndroidKeyStoreBCWorkaroundProvider() {
- this("AndroidKeyStoreBCWorkaround");
- }
-
- /** @hide **/
- public AndroidKeyStoreBCWorkaroundProvider(String providerName) {
- super(providerName,
- 1.0,
- "Android KeyStore security provider to work around Bouncy Castle");
-
- // --------------------- javax.crypto.Mac
- putMacImpl("HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA1");
- put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1");
- put("Alg.Alias.Mac.HMAC-SHA1", "HmacSHA1");
- put("Alg.Alias.Mac.HMAC/SHA1", "HmacSHA1");
-
- putMacImpl("HmacSHA224", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA224");
- put("Alg.Alias.Mac.1.2.840.113549.2.9", "HmacSHA224");
- put("Alg.Alias.Mac.HMAC-SHA224", "HmacSHA224");
- put("Alg.Alias.Mac.HMAC/SHA224", "HmacSHA224");
-
- putMacImpl("HmacSHA256", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA256");
- put("Alg.Alias.Mac.1.2.840.113549.2.9", "HmacSHA256");
- put("Alg.Alias.Mac.HMAC-SHA256", "HmacSHA256");
- put("Alg.Alias.Mac.HMAC/SHA256", "HmacSHA256");
-
- putMacImpl("HmacSHA384", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA384");
- put("Alg.Alias.Mac.1.2.840.113549.2.10", "HmacSHA384");
- put("Alg.Alias.Mac.HMAC-SHA384", "HmacSHA384");
- put("Alg.Alias.Mac.HMAC/SHA384", "HmacSHA384");
-
- putMacImpl("HmacSHA512", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA512");
- put("Alg.Alias.Mac.1.2.840.113549.2.11", "HmacSHA512");
- put("Alg.Alias.Mac.HMAC-SHA512", "HmacSHA512");
- put("Alg.Alias.Mac.HMAC/SHA512", "HmacSHA512");
-
- // --------------------- javax.crypto.Cipher
- putSymmetricCipherImpl("AES/ECB/NoPadding",
- PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$ECB$NoPadding");
- putSymmetricCipherImpl("AES/ECB/PKCS7Padding",
- PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$ECB$PKCS7Padding");
-
- putSymmetricCipherImpl("AES/CBC/NoPadding",
- PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$CBC$NoPadding");
- putSymmetricCipherImpl("AES/CBC/PKCS7Padding",
- PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$CBC$PKCS7Padding");
-
- putSymmetricCipherImpl("AES/CTR/NoPadding",
- PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$CTR$NoPadding");
-
- if ("true".equals(android.os.SystemProperties.get(DESEDE_SYSTEM_PROPERTY))) {
- putSymmetricCipherImpl("DESede/CBC/NoPadding",
- PACKAGE_NAME + ".AndroidKeyStore3DESCipherSpi$CBC$NoPadding");
- putSymmetricCipherImpl("DESede/CBC/PKCS7Padding",
- PACKAGE_NAME + ".AndroidKeyStore3DESCipherSpi$CBC$PKCS7Padding");
-
- putSymmetricCipherImpl("DESede/ECB/NoPadding",
- PACKAGE_NAME + ".AndroidKeyStore3DESCipherSpi$ECB$NoPadding");
- putSymmetricCipherImpl("DESede/ECB/PKCS7Padding",
- PACKAGE_NAME + ".AndroidKeyStore3DESCipherSpi$ECB$PKCS7Padding");
- }
-
- putSymmetricCipherImpl("AES/GCM/NoPadding",
- PACKAGE_NAME + ".AndroidKeyStoreAuthenticatedAESCipherSpi$GCM$NoPadding");
-
- putAsymmetricCipherImpl("RSA/ECB/NoPadding",
- PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$NoPadding");
- put("Alg.Alias.Cipher.RSA/None/NoPadding", "RSA/ECB/NoPadding");
- putAsymmetricCipherImpl("RSA/ECB/PKCS1Padding",
- PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$PKCS1Padding");
- put("Alg.Alias.Cipher.RSA/None/PKCS1Padding", "RSA/ECB/PKCS1Padding");
- putAsymmetricCipherImpl("RSA/ECB/OAEPPadding",
- PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA1AndMGF1Padding");
- put("Alg.Alias.Cipher.RSA/None/OAEPPadding", "RSA/ECB/OAEPPadding");
- putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-1AndMGF1Padding",
- PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA1AndMGF1Padding");
- put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-1AndMGF1Padding",
- "RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
- putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-224AndMGF1Padding",
- PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA224AndMGF1Padding");
- put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-224AndMGF1Padding",
- "RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
- putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-256AndMGF1Padding",
- PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA256AndMGF1Padding");
- put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-256AndMGF1Padding",
- "RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
- putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-384AndMGF1Padding",
- PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA384AndMGF1Padding");
- put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-384AndMGF1Padding",
- "RSA/ECB/OAEPWithSHA-384AndMGF1Padding");
- putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-512AndMGF1Padding",
- PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA512AndMGF1Padding");
- put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-512AndMGF1Padding",
- "RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
-
- // --------------------- java.security.Signature
- putSignatureImpl("NONEwithRSA",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$NONEWithPKCS1Padding");
-
- putSignatureImpl("MD5withRSA",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$MD5WithPKCS1Padding");
- put("Alg.Alias.Signature.MD5WithRSAEncryption", "MD5withRSA");
- put("Alg.Alias.Signature.MD5/RSA", "MD5withRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
- put("Alg.Alias.Signature.1.2.840.113549.2.5with1.2.840.113549.1.1.1", "MD5withRSA");
-
- putSignatureImpl("SHA1withRSA",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA1WithPKCS1Padding");
- put("Alg.Alias.Signature.SHA1WithRSAEncryption", "SHA1withRSA");
- put("Alg.Alias.Signature.SHA1/RSA", "SHA1withRSA");
- put("Alg.Alias.Signature.SHA-1/RSA", "SHA1withRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.1", "SHA1withRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.5", "SHA1withRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA");
-
- putSignatureImpl("SHA224withRSA",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA224WithPKCS1Padding");
- put("Alg.Alias.Signature.SHA224WithRSAEncryption", "SHA224withRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA224withRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.4with1.2.840.113549.1.1.1",
- "SHA224withRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.4with1.2.840.113549.1.1.11",
- "SHA224withRSA");
-
- putSignatureImpl("SHA256withRSA",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA256WithPKCS1Padding");
- put("Alg.Alias.Signature.SHA256WithRSAEncryption", "SHA256withRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.1",
- "SHA256withRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.11",
- "SHA256withRSA");
-
- putSignatureImpl("SHA384withRSA",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA384WithPKCS1Padding");
- put("Alg.Alias.Signature.SHA384WithRSAEncryption", "SHA384withRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.113549.1.1.1",
- "SHA384withRSA");
-
- putSignatureImpl("SHA512withRSA",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA512WithPKCS1Padding");
- put("Alg.Alias.Signature.SHA512WithRSAEncryption", "SHA512withRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.113549.1.1.1",
- "SHA512withRSA");
-
- putSignatureImpl("SHA1withRSA/PSS",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA1WithPSSPadding");
- putSignatureImpl("SHA224withRSA/PSS",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA224WithPSSPadding");
- putSignatureImpl("SHA256withRSA/PSS",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA256WithPSSPadding");
- putSignatureImpl("SHA384withRSA/PSS",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA384WithPSSPadding");
- putSignatureImpl("SHA512withRSA/PSS",
- PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA512WithPSSPadding");
-
- putSignatureImpl("NONEwithECDSA",
- PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$NONE");
-
- putSignatureImpl("SHA1withECDSA", PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA1");
- put("Alg.Alias.Signature.ECDSA", "SHA1withECDSA");
- put("Alg.Alias.Signature.ECDSAwithSHA1", "SHA1withECDSA");
- // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA1(1)
- put("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10045.2.1", "SHA1withECDSA");
-
- // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA2(3)
- putSignatureImpl("SHA224withECDSA",
- PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA224");
- // ecdsa-with-SHA224(1)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.1", "SHA224withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.4with1.2.840.10045.2.1", "SHA224withECDSA");
-
- // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA2(3)
- putSignatureImpl("SHA256withECDSA",
- PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA256");
- // ecdsa-with-SHA256(2)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.2", "SHA256withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.10045.2.1", "SHA256withECDSA");
-
- putSignatureImpl("SHA384withECDSA",
- PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA384");
- // ecdsa-with-SHA384(3)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.3", "SHA384withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.10045.2.1", "SHA384withECDSA");
-
- putSignatureImpl("SHA512withECDSA",
- PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA512");
- // ecdsa-with-SHA512(4)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.4", "SHA512withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.10045.2.1", "SHA512withECDSA");
- }
-
- private void putMacImpl(String algorithm, String implClass) {
- put("Mac." + algorithm, implClass);
- put("Mac." + algorithm + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME);
- }
-
- private void putSymmetricCipherImpl(String transformation, String implClass) {
- put("Cipher." + transformation, implClass);
- put("Cipher." + transformation + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME);
- }
-
- private void putAsymmetricCipherImpl(String transformation, String implClass) {
- put("Cipher." + transformation, implClass);
- put("Cipher." + transformation + " SupportedKeyClasses",
- KEYSTORE_PRIVATE_KEY_CLASS_NAME + "|" + KEYSTORE_PUBLIC_KEY_CLASS_NAME);
- }
-
- private void putSignatureImpl(String algorithm, String implClass) {
- put("Signature." + algorithm, implClass);
- put("Signature." + algorithm + " SupportedKeyClasses",
- KEYSTORE_PRIVATE_KEY_CLASS_NAME + "|" + KEYSTORE_PUBLIC_KEY_CLASS_NAME);
- }
-
- public static String[] getSupportedEcdsaSignatureDigests() {
- return new String[] {"NONE", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"};
- }
-
- public static String[] getSupportedRsaSignatureWithPkcs1PaddingDigests() {
- return new String[] {"NONE", "MD5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"};
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
deleted file mode 100644
index ccc3153749fb..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.annotation.CallSuper;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.IBinder;
-import android.security.KeyStore;
-import android.security.KeyStoreException;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keymaster.OperationResult;
-
-import libcore.util.EmptyArray;
-
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.security.AlgorithmParameters;
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.ProviderException;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-import javax.crypto.AEADBadTagException;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.CipherSpi;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * Base class for {@link CipherSpi} implementations of Android KeyStore backed ciphers.
- *
- * @hide
- */
-abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStoreCryptoOperation {
- private final KeyStore mKeyStore;
-
- // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after
- // doFinal finishes.
- private boolean mEncrypting;
- private int mKeymasterPurposeOverride = -1;
- private AndroidKeyStoreKey mKey;
- private SecureRandom mRng;
-
- /**
- * Token referencing this operation inside keystore service. It is initialized by
- * {@code engineInit} and is invalidated when {@code engineDoFinal} succeeds and on some error
- * conditions in between.
- */
- private IBinder mOperationToken;
- private long mOperationHandle;
- private KeyStoreCryptoOperationStreamer mMainDataStreamer;
- private KeyStoreCryptoOperationStreamer mAdditionalAuthenticationDataStreamer;
- private boolean mAdditionalAuthenticationDataStreamerClosed;
-
- /**
- * Encountered exception which could not be immediately thrown because it was encountered inside
- * a method that does not throw checked exception. This exception will be thrown from
- * {@code engineDoFinal}. Once such an exception is encountered, {@code engineUpdate} and
- * {@code engineDoFinal} start ignoring input data.
- */
- private Exception mCachedException;
-
- AndroidKeyStoreCipherSpiBase() {
- mKeyStore = KeyStore.getInstance();
- }
-
- @Override
- protected final void engineInit(int opmode, Key key, SecureRandom random)
- throws InvalidKeyException {
- resetAll();
-
- boolean success = false;
- try {
- init(opmode, key, random);
- initAlgorithmSpecificParameters();
- try {
- ensureKeystoreOperationInitialized();
- } catch (InvalidAlgorithmParameterException e) {
- throw new InvalidKeyException(e);
- }
- success = true;
- } finally {
- if (!success) {
- resetAll();
- }
- }
- }
-
- @Override
- protected final void engineInit(int opmode, Key key, AlgorithmParameters params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- resetAll();
-
- boolean success = false;
- try {
- init(opmode, key, random);
- initAlgorithmSpecificParameters(params);
- ensureKeystoreOperationInitialized();
- success = true;
- } finally {
- if (!success) {
- resetAll();
- }
- }
- }
-
- @Override
- protected final void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- resetAll();
-
- boolean success = false;
- try {
- init(opmode, key, random);
- initAlgorithmSpecificParameters(params);
- ensureKeystoreOperationInitialized();
- success = true;
- } finally {
- if (!success) {
- resetAll();
- }
- }
- }
-
- private void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- switch (opmode) {
- case Cipher.ENCRYPT_MODE:
- case Cipher.WRAP_MODE:
- mEncrypting = true;
- break;
- case Cipher.DECRYPT_MODE:
- case Cipher.UNWRAP_MODE:
- mEncrypting = false;
- break;
- default:
- throw new InvalidParameterException("Unsupported opmode: " + opmode);
- }
- initKey(opmode, key);
- if (mKey == null) {
- throw new ProviderException("initKey did not initialize the key");
- }
- mRng = random;
- }
-
- /**
- * Resets this cipher to its pristine pre-init state. This must be equivalent to obtaining a new
- * cipher instance.
- *
- * <p>Subclasses storing additional state should override this method, reset the additional
- * state, and then chain to superclass.
- */
- @CallSuper
- protected void resetAll() {
- IBinder operationToken = mOperationToken;
- if (operationToken != null) {
- mKeyStore.abort(operationToken);
- }
- mEncrypting = false;
- mKeymasterPurposeOverride = -1;
- mKey = null;
- mRng = null;
- mOperationToken = null;
- mOperationHandle = 0;
- mMainDataStreamer = null;
- mAdditionalAuthenticationDataStreamer = null;
- mAdditionalAuthenticationDataStreamerClosed = false;
- mCachedException = null;
- }
-
- /**
- * Resets this cipher while preserving the initialized state. This must be equivalent to
- * rolling back the cipher's state to just after the most recent {@code engineInit} completed
- * successfully.
- *
- * <p>Subclasses storing additional post-init state should override this method, reset the
- * additional state, and then chain to superclass.
- */
- @CallSuper
- protected void resetWhilePreservingInitState() {
- IBinder operationToken = mOperationToken;
- if (operationToken != null) {
- mKeyStore.abort(operationToken);
- }
- mOperationToken = null;
- mOperationHandle = 0;
- mMainDataStreamer = null;
- mAdditionalAuthenticationDataStreamer = null;
- mAdditionalAuthenticationDataStreamerClosed = false;
- mCachedException = null;
- }
-
- private void ensureKeystoreOperationInitialized() throws InvalidKeyException,
- InvalidAlgorithmParameterException {
- if (mMainDataStreamer != null) {
- return;
- }
- if (mCachedException != null) {
- return;
- }
- if (mKey == null) {
- throw new IllegalStateException("Not initialized");
- }
-
- KeymasterArguments keymasterInputArgs = new KeymasterArguments();
- addAlgorithmSpecificParametersToBegin(keymasterInputArgs);
- byte[] additionalEntropy = KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
- mRng, getAdditionalEntropyAmountForBegin());
-
- int purpose;
- if (mKeymasterPurposeOverride != -1) {
- purpose = mKeymasterPurposeOverride;
- } else {
- purpose = mEncrypting
- ? KeymasterDefs.KM_PURPOSE_ENCRYPT : KeymasterDefs.KM_PURPOSE_DECRYPT;
- }
- OperationResult opResult = mKeyStore.begin(
- mKey.getAlias(),
- purpose,
- true, // permit aborting this operation if keystore runs out of resources
- keymasterInputArgs,
- additionalEntropy,
- mKey.getUid());
- if (opResult == null) {
- throw new KeyStoreConnectException();
- }
-
- // Store operation token and handle regardless of the error code returned by KeyStore to
- // ensure that the operation gets aborted immediately if the code below throws an exception.
- mOperationToken = opResult.token;
- mOperationHandle = opResult.operationHandle;
-
- // If necessary, throw an exception due to KeyStore operation having failed.
- GeneralSecurityException e = KeyStoreCryptoOperationUtils.getExceptionForCipherInit(
- mKeyStore, mKey, opResult.resultCode);
- if (e != null) {
- if (e instanceof InvalidKeyException) {
- throw (InvalidKeyException) e;
- } else if (e instanceof InvalidAlgorithmParameterException) {
- throw (InvalidAlgorithmParameterException) e;
- } else {
- throw new ProviderException("Unexpected exception type", e);
- }
- }
-
- if (mOperationToken == null) {
- throw new ProviderException("Keystore returned null operation token");
- }
- if (mOperationHandle == 0) {
- throw new ProviderException("Keystore returned invalid operation handle");
- }
-
- loadAlgorithmSpecificParametersFromBeginResult(opResult.outParams);
- mMainDataStreamer = createMainDataStreamer(mKeyStore, opResult.token);
- mAdditionalAuthenticationDataStreamer =
- createAdditionalAuthenticationDataStreamer(mKeyStore, opResult.token);
- mAdditionalAuthenticationDataStreamerClosed = false;
- }
-
- /**
- * Creates a streamer which sends plaintext/ciphertext into the provided KeyStore and receives
- * the corresponding ciphertext/plaintext from the KeyStore.
- *
- * <p>This implementation returns a working streamer.
- */
- @NonNull
- protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
- KeyStore keyStore, IBinder operationToken) {
- return new KeyStoreCryptoOperationChunkedStreamer(
- new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
- keyStore, operationToken), 0);
- }
-
- /**
- * Creates a streamer which sends Additional Authentication Data (AAD) into the KeyStore.
- *
- * <p>This implementation returns {@code null}.
- *
- * @return stream or {@code null} if AAD is not supported by this cipher.
- */
- @Nullable
- protected KeyStoreCryptoOperationStreamer createAdditionalAuthenticationDataStreamer(
- @SuppressWarnings("unused") KeyStore keyStore,
- @SuppressWarnings("unused") IBinder operationToken) {
- return null;
- }
-
- @Override
- protected final byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
- if (mCachedException != null) {
- return null;
- }
- try {
- ensureKeystoreOperationInitialized();
- } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
- mCachedException = e;
- return null;
- }
-
- if (inputLen == 0) {
- return null;
- }
-
- byte[] output;
- try {
- flushAAD();
- output = mMainDataStreamer.update(input, inputOffset, inputLen);
- } catch (KeyStoreException e) {
- mCachedException = e;
- return null;
- }
-
- if (output.length == 0) {
- return null;
- }
-
- return output;
- }
-
- private void flushAAD() throws KeyStoreException {
- if ((mAdditionalAuthenticationDataStreamer != null)
- && (!mAdditionalAuthenticationDataStreamerClosed)) {
- byte[] output;
- try {
- output = mAdditionalAuthenticationDataStreamer.doFinal(
- EmptyArray.BYTE, 0, 0,
- null, // no signature
- null // no additional entropy needed flushing AAD
- );
- } finally {
- mAdditionalAuthenticationDataStreamerClosed = true;
- }
- if ((output != null) && (output.length > 0)) {
- throw new ProviderException(
- "AAD update unexpectedly returned data: " + output.length + " bytes");
- }
- }
- }
-
- @Override
- protected final int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException {
- byte[] outputCopy = engineUpdate(input, inputOffset, inputLen);
- if (outputCopy == null) {
- return 0;
- }
- int outputAvailable = output.length - outputOffset;
- if (outputCopy.length > outputAvailable) {
- throw new ShortBufferException("Output buffer too short. Produced: "
- + outputCopy.length + ", available: " + outputAvailable);
- }
- System.arraycopy(outputCopy, 0, output, outputOffset, outputCopy.length);
- return outputCopy.length;
- }
-
- @Override
- protected final int engineUpdate(ByteBuffer input, ByteBuffer output)
- throws ShortBufferException {
- if (input == null) {
- throw new NullPointerException("input == null");
- }
- if (output == null) {
- throw new NullPointerException("output == null");
- }
-
- int inputSize = input.remaining();
- byte[] outputArray;
- if (input.hasArray()) {
- outputArray =
- engineUpdate(
- input.array(), input.arrayOffset() + input.position(), inputSize);
- input.position(input.position() + inputSize);
- } else {
- byte[] inputArray = new byte[inputSize];
- input.get(inputArray);
- outputArray = engineUpdate(inputArray, 0, inputSize);
- }
-
- int outputSize = (outputArray != null) ? outputArray.length : 0;
- if (outputSize > 0) {
- int outputBufferAvailable = output.remaining();
- try {
- output.put(outputArray);
- } catch (BufferOverflowException e) {
- throw new ShortBufferException(
- "Output buffer too small. Produced: " + outputSize + ", available: "
- + outputBufferAvailable);
- }
- }
- return outputSize;
- }
-
- @Override
- protected final void engineUpdateAAD(byte[] input, int inputOffset, int inputLen) {
- if (mCachedException != null) {
- return;
- }
-
- try {
- ensureKeystoreOperationInitialized();
- } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
- mCachedException = e;
- return;
- }
-
- if (mAdditionalAuthenticationDataStreamerClosed) {
- throw new IllegalStateException(
- "AAD can only be provided before Cipher.update is invoked");
- }
-
- if (mAdditionalAuthenticationDataStreamer == null) {
- throw new IllegalStateException("This cipher does not support AAD");
- }
-
- byte[] output;
- try {
- output = mAdditionalAuthenticationDataStreamer.update(input, inputOffset, inputLen);
- } catch (KeyStoreException e) {
- mCachedException = e;
- return;
- }
-
- if ((output != null) && (output.length > 0)) {
- throw new ProviderException("AAD update unexpectedly produced output: "
- + output.length + " bytes");
- }
- }
-
- @Override
- protected final void engineUpdateAAD(ByteBuffer src) {
- if (src == null) {
- throw new IllegalArgumentException("src == null");
- }
- if (!src.hasRemaining()) {
- return;
- }
-
- byte[] input;
- int inputOffset;
- int inputLen;
- if (src.hasArray()) {
- input = src.array();
- inputOffset = src.arrayOffset() + src.position();
- inputLen = src.remaining();
- src.position(src.limit());
- } else {
- input = new byte[src.remaining()];
- inputOffset = 0;
- inputLen = input.length;
- src.get(input);
- }
- engineUpdateAAD(input, inputOffset, inputLen);
- }
-
- @Override
- protected final byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
- throws IllegalBlockSizeException, BadPaddingException {
- if (mCachedException != null) {
- throw (IllegalBlockSizeException)
- new IllegalBlockSizeException().initCause(mCachedException);
- }
-
- try {
- ensureKeystoreOperationInitialized();
- } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
- throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
- }
-
- byte[] output;
- try {
- flushAAD();
- byte[] additionalEntropy =
- KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
- mRng, getAdditionalEntropyAmountForFinish());
- output = mMainDataStreamer.doFinal(
- input, inputOffset, inputLen,
- null, // no signature involved
- additionalEntropy);
- } catch (KeyStoreException e) {
- switch (e.getErrorCode()) {
- case KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH:
- throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
- case KeymasterDefs.KM_ERROR_INVALID_ARGUMENT:
- throw (BadPaddingException) new BadPaddingException().initCause(e);
- case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
- throw (AEADBadTagException) new AEADBadTagException().initCause(e);
- default:
- throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
- }
- }
-
- resetWhilePreservingInitState();
- return output;
- }
-
- @Override
- protected final int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException {
- byte[] outputCopy = engineDoFinal(input, inputOffset, inputLen);
- if (outputCopy == null) {
- return 0;
- }
- int outputAvailable = output.length - outputOffset;
- if (outputCopy.length > outputAvailable) {
- throw new ShortBufferException("Output buffer too short. Produced: "
- + outputCopy.length + ", available: " + outputAvailable);
- }
- System.arraycopy(outputCopy, 0, output, outputOffset, outputCopy.length);
- return outputCopy.length;
- }
-
- @Override
- protected final int engineDoFinal(ByteBuffer input, ByteBuffer output)
- throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
- if (input == null) {
- throw new NullPointerException("input == null");
- }
- if (output == null) {
- throw new NullPointerException("output == null");
- }
-
- int inputSize = input.remaining();
- byte[] outputArray;
- if (input.hasArray()) {
- outputArray =
- engineDoFinal(
- input.array(), input.arrayOffset() + input.position(), inputSize);
- input.position(input.position() + inputSize);
- } else {
- byte[] inputArray = new byte[inputSize];
- input.get(inputArray);
- outputArray = engineDoFinal(inputArray, 0, inputSize);
- }
-
- int outputSize = (outputArray != null) ? outputArray.length : 0;
- if (outputSize > 0) {
- int outputBufferAvailable = output.remaining();
- try {
- output.put(outputArray);
- } catch (BufferOverflowException e) {
- throw new ShortBufferException(
- "Output buffer too small. Produced: " + outputSize + ", available: "
- + outputBufferAvailable);
- }
- }
- return outputSize;
- }
-
- @Override
- protected final byte[] engineWrap(Key key)
- throws IllegalBlockSizeException, InvalidKeyException {
- if (mKey == null) {
- throw new IllegalStateException("Not initilized");
- }
-
- if (!isEncrypting()) {
- throw new IllegalStateException(
- "Cipher must be initialized in Cipher.WRAP_MODE to wrap keys");
- }
-
- if (key == null) {
- throw new NullPointerException("key == null");
- }
- byte[] encoded = null;
- if (key instanceof SecretKey) {
- if ("RAW".equalsIgnoreCase(key.getFormat())) {
- encoded = key.getEncoded();
- }
- if (encoded == null) {
- try {
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(key.getAlgorithm());
- SecretKeySpec spec =
- (SecretKeySpec) keyFactory.getKeySpec(
- (SecretKey) key, SecretKeySpec.class);
- encoded = spec.getEncoded();
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- throw new InvalidKeyException(
- "Failed to wrap key because it does not export its key material",
- e);
- }
- }
- } else if (key instanceof PrivateKey) {
- if ("PKCS8".equalsIgnoreCase(key.getFormat())) {
- encoded = key.getEncoded();
- }
- if (encoded == null) {
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm());
- PKCS8EncodedKeySpec spec =
- keyFactory.getKeySpec(key, PKCS8EncodedKeySpec.class);
- encoded = spec.getEncoded();
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- throw new InvalidKeyException(
- "Failed to wrap key because it does not export its key material",
- e);
- }
- }
- } else if (key instanceof PublicKey) {
- if ("X.509".equalsIgnoreCase(key.getFormat())) {
- encoded = key.getEncoded();
- }
- if (encoded == null) {
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm());
- X509EncodedKeySpec spec =
- keyFactory.getKeySpec(key, X509EncodedKeySpec.class);
- encoded = spec.getEncoded();
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- throw new InvalidKeyException(
- "Failed to wrap key because it does not export its key material",
- e);
- }
- }
- } else {
- throw new InvalidKeyException("Unsupported key type: " + key.getClass().getName());
- }
-
- if (encoded == null) {
- throw new InvalidKeyException(
- "Failed to wrap key because it does not export its key material");
- }
-
- try {
- return engineDoFinal(encoded, 0, encoded.length);
- } catch (BadPaddingException e) {
- throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
- }
- }
-
- @Override
- protected final Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
- int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
- if (mKey == null) {
- throw new IllegalStateException("Not initilized");
- }
-
- if (isEncrypting()) {
- throw new IllegalStateException(
- "Cipher must be initialized in Cipher.WRAP_MODE to wrap keys");
- }
-
- if (wrappedKey == null) {
- throw new NullPointerException("wrappedKey == null");
- }
-
- byte[] encoded;
- try {
- encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
- } catch (IllegalBlockSizeException | BadPaddingException e) {
- throw new InvalidKeyException("Failed to unwrap key", e);
- }
-
- switch (wrappedKeyType) {
- case Cipher.SECRET_KEY:
- {
- return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
- // break;
- }
- case Cipher.PRIVATE_KEY:
- {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- try {
- return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(
- "Failed to create private key from its PKCS#8 encoded form", e);
- }
- // break;
- }
- case Cipher.PUBLIC_KEY:
- {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- try {
- return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(
- "Failed to create public key from its X.509 encoded form", e);
- }
- // break;
- }
- default:
- throw new InvalidParameterException(
- "Unsupported wrappedKeyType: " + wrappedKeyType);
- }
- }
-
- @Override
- protected final void engineSetMode(String mode) throws NoSuchAlgorithmException {
- // This should never be invoked because all algorithms registered with the AndroidKeyStore
- // provide explicitly specify block mode.
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected final void engineSetPadding(String arg0) throws NoSuchPaddingException {
- // This should never be invoked because all algorithms registered with the AndroidKeyStore
- // provide explicitly specify padding mode.
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected final int engineGetKeySize(Key key) throws InvalidKeyException {
- throw new UnsupportedOperationException();
- }
-
- @CallSuper
- @Override
- public void finalize() throws Throwable {
- try {
- IBinder operationToken = mOperationToken;
- if (operationToken != null) {
- mKeyStore.abort(operationToken);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public final long getOperationHandle() {
- return mOperationHandle;
- }
-
- protected final void setKey(@NonNull AndroidKeyStoreKey key) {
- mKey = key;
- }
-
- /**
- * Overrides the default purpose/type of the crypto operation.
- */
- protected final void setKeymasterPurposeOverride(int keymasterPurpose) {
- mKeymasterPurposeOverride = keymasterPurpose;
- }
-
- protected final int getKeymasterPurposeOverride() {
- return mKeymasterPurposeOverride;
- }
-
- /**
- * Returns {@code true} if this cipher is initialized for encryption, {@code false} if this
- * cipher is initialized for decryption.
- */
- protected final boolean isEncrypting() {
- return mEncrypting;
- }
-
- @NonNull
- protected final KeyStore getKeyStore() {
- return mKeyStore;
- }
-
- protected final long getConsumedInputSizeBytes() {
- if (mMainDataStreamer == null) {
- throw new IllegalStateException("Not initialized");
- }
- return mMainDataStreamer.getConsumedInputSizeBytes();
- }
-
- protected final long getProducedOutputSizeBytes() {
- if (mMainDataStreamer == null) {
- throw new IllegalStateException("Not initialized");
- }
- return mMainDataStreamer.getProducedOutputSizeBytes();
- }
-
- static String opmodeToString(int opmode) {
- switch (opmode) {
- case Cipher.ENCRYPT_MODE:
- return "ENCRYPT_MODE";
- case Cipher.DECRYPT_MODE:
- return "DECRYPT_MODE";
- case Cipher.WRAP_MODE:
- return "WRAP_MODE";
- case Cipher.UNWRAP_MODE:
- return "UNWRAP_MODE";
- default:
- return String.valueOf(opmode);
- }
- }
-
- // The methods below need to be implemented by subclasses.
-
- /**
- * Initializes this cipher with the provided key.
- *
- * @throws InvalidKeyException if the {@code key} is not suitable for this cipher in the
- * specified {@code opmode}.
- *
- * @see #setKey(AndroidKeyStoreKey)
- */
- protected abstract void initKey(int opmode, @Nullable Key key) throws InvalidKeyException;
-
- /**
- * Returns algorithm-specific parameters used by this cipher or {@code null} if no
- * algorithm-specific parameters are used.
- */
- @Nullable
- @Override
- protected abstract AlgorithmParameters engineGetParameters();
-
- /**
- * Invoked by {@code engineInit} to initialize algorithm-specific parameters when no additional
- * initialization parameters were provided.
- *
- * @throws InvalidKeyException if this cipher cannot be configured based purely on the provided
- * key and needs additional parameters to be provided to {@code Cipher.init}.
- */
- protected abstract void initAlgorithmSpecificParameters() throws InvalidKeyException;
-
- /**
- * Invoked by {@code engineInit} to initialize algorithm-specific parameters when additional
- * parameters were provided.
- *
- * @param params additional algorithm parameters or {@code null} if not specified.
- *
- * @throws InvalidAlgorithmParameterException if there is insufficient information to configure
- * this cipher or if the provided parameters are not suitable for this cipher.
- */
- protected abstract void initAlgorithmSpecificParameters(
- @Nullable AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException;
-
- /**
- * Invoked by {@code engineInit} to initialize algorithm-specific parameters when additional
- * parameters were provided.
- *
- * @param params additional algorithm parameters or {@code null} if not specified.
- *
- * @throws InvalidAlgorithmParameterException if there is insufficient information to configure
- * this cipher or if the provided parameters are not suitable for this cipher.
- */
- protected abstract void initAlgorithmSpecificParameters(@Nullable AlgorithmParameters params)
- throws InvalidAlgorithmParameterException;
-
- /**
- * Returns the amount of additional entropy (in bytes) to be provided to the KeyStore's
- * {@code begin} operation. This amount of entropy is typically what's consumed to generate
- * random parameters, such as IV.
- *
- * <p>For decryption, the return value should be {@code 0} because decryption should not be
- * consuming any entropy. For encryption, the value combined with
- * {@link #getAdditionalEntropyAmountForFinish()} should match (or exceed) the amount of Shannon
- * entropy of the ciphertext produced by this cipher assuming the key, the plaintext, and all
- * explicitly provided parameters to {@code Cipher.init} are known. For example, for AES CBC
- * encryption with an explicitly provided IV the return value should be {@code 0}, whereas for
- * the case where IV is generated by the KeyStore's {@code begin} operation it should be
- * {@code 16}.
- */
- protected abstract int getAdditionalEntropyAmountForBegin();
-
- /**
- * Returns the amount of additional entropy (in bytes) to be provided to the KeyStore's
- * {@code finish} operation. This amount of entropy is typically what's consumed by encryption
- * padding scheme.
- *
- * <p>For decryption, the return value should be {@code 0} because decryption should not be
- * consuming any entropy. For encryption, the value combined with
- * {@link #getAdditionalEntropyAmountForBegin()} should match (or exceed) the amount of Shannon
- * entropy of the ciphertext produced by this cipher assuming the key, the plaintext, and all
- * explicitly provided parameters to {@code Cipher.init} are known. For example, for RSA with
- * OAEP the return value should be the size of the OAEP hash output. For RSA with PKCS#1 padding
- * the return value should be the size of the padding string or could be raised (for simplicity)
- * to the size of the modulus.
- */
- protected abstract int getAdditionalEntropyAmountForFinish();
-
- /**
- * Invoked to add algorithm-specific parameters for the KeyStore's {@code begin} operation.
- *
- * @param keymasterArgs keystore/keymaster arguments to be populated with algorithm-specific
- * parameters.
- */
- protected abstract void addAlgorithmSpecificParametersToBegin(
- @NonNull KeymasterArguments keymasterArgs);
-
- /**
- * Invoked to obtain algorithm-specific parameters from the result of the KeyStore's
- * {@code begin} operation.
- *
- * <p>Some parameters, such as IV, are not required to be provided to {@code Cipher.init}. Such
- * parameters, if not provided, must be generated by KeyStore and returned to the user of
- * {@code Cipher} and potentially reused after {@code doFinal}.
- *
- * @param keymasterArgs keystore/keymaster arguments returned by KeyStore {@code begin}
- * operation.
- */
- protected abstract void loadAlgorithmSpecificParametersFromBeginResult(
- @NonNull KeymasterArguments keymasterArgs);
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java
deleted file mode 100644
index 45f2110e0c77..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.annotation.NonNull;
-import android.os.IBinder;
-import android.security.KeyStore;
-import android.security.KeyStoreException;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-
-import libcore.util.EmptyArray;
-
-import java.io.ByteArrayOutputStream;
-import java.security.InvalidKeyException;
-import java.security.SignatureSpi;
-
-/**
- * Base class for {@link SignatureSpi} providing Android KeyStore backed ECDSA signatures.
- *
- * @hide
- */
-abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignatureSpiBase {
-
- public final static class NONE extends AndroidKeyStoreECDSASignatureSpi {
- public NONE() {
- super(KeymasterDefs.KM_DIGEST_NONE);
- }
-
- @Override
- protected KeyStoreCryptoOperationStreamer createMainDataStreamer(KeyStore keyStore,
- IBinder operationToken) {
- return new TruncateToFieldSizeMessageStreamer(
- super.createMainDataStreamer(keyStore, operationToken),
- getGroupSizeBits());
- }
-
- /**
- * Streamer which buffers all input, then truncates it to field size, and then sends it into
- * KeyStore via the provided delegate streamer.
- */
- private static class TruncateToFieldSizeMessageStreamer
- implements KeyStoreCryptoOperationStreamer {
-
- private final KeyStoreCryptoOperationStreamer mDelegate;
- private final int mGroupSizeBits;
- private final ByteArrayOutputStream mInputBuffer = new ByteArrayOutputStream();
- private long mConsumedInputSizeBytes;
-
- private TruncateToFieldSizeMessageStreamer(
- KeyStoreCryptoOperationStreamer delegate,
- int groupSizeBits) {
- mDelegate = delegate;
- mGroupSizeBits = groupSizeBits;
- }
-
- @Override
- public byte[] update(byte[] input, int inputOffset, int inputLength)
- throws KeyStoreException {
- if (inputLength > 0) {
- mInputBuffer.write(input, inputOffset, inputLength);
- mConsumedInputSizeBytes += inputLength;
- }
- return EmptyArray.BYTE;
- }
-
- @Override
- public byte[] doFinal(byte[] input, int inputOffset, int inputLength, byte[] signature,
- byte[] additionalEntropy) throws KeyStoreException {
- if (inputLength > 0) {
- mConsumedInputSizeBytes += inputLength;
- mInputBuffer.write(input, inputOffset, inputLength);
- }
-
- byte[] bufferedInput = mInputBuffer.toByteArray();
- mInputBuffer.reset();
- // Truncate input at field size (bytes)
- return mDelegate.doFinal(bufferedInput,
- 0,
- Math.min(bufferedInput.length, ((mGroupSizeBits + 7) / 8)),
- signature, additionalEntropy);
- }
-
- @Override
- public long getConsumedInputSizeBytes() {
- return mConsumedInputSizeBytes;
- }
-
- @Override
- public long getProducedOutputSizeBytes() {
- return mDelegate.getProducedOutputSizeBytes();
- }
- }
- }
-
- public final static class SHA1 extends AndroidKeyStoreECDSASignatureSpi {
- public SHA1() {
- super(KeymasterDefs.KM_DIGEST_SHA1);
- }
- }
-
- public final static class SHA224 extends AndroidKeyStoreECDSASignatureSpi {
- public SHA224() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_224);
- }
- }
-
- public final static class SHA256 extends AndroidKeyStoreECDSASignatureSpi {
- public SHA256() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_256);
- }
- }
-
- public final static class SHA384 extends AndroidKeyStoreECDSASignatureSpi {
- public SHA384() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_384);
- }
- }
-
- public final static class SHA512 extends AndroidKeyStoreECDSASignatureSpi {
- public SHA512() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_512);
- }
- }
-
- private final int mKeymasterDigest;
-
- private int mGroupSizeBits = -1;
-
- AndroidKeyStoreECDSASignatureSpi(int keymasterDigest) {
- mKeymasterDigest = keymasterDigest;
- }
-
- @Override
- protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException {
- if (!KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(key.getAlgorithm())) {
- throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm()
- + ". Only" + KeyProperties.KEY_ALGORITHM_EC + " supported");
- }
-
- KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
- int errorCode = getKeyStore().getKeyCharacteristics(
- key.getAlias(), null, null, key.getUid(), keyCharacteristics);
- if (errorCode != KeyStore.NO_ERROR) {
- throw getKeyStore().getInvalidKeyException(key.getAlias(), key.getUid(), errorCode);
- }
- long keySizeBits = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
- if (keySizeBits == -1) {
- throw new InvalidKeyException("Size of key not known");
- } else if (keySizeBits > Integer.MAX_VALUE) {
- throw new InvalidKeyException("Key too large: " + keySizeBits + " bits");
- }
- mGroupSizeBits = (int) keySizeBits;
-
- super.initKey(key);
- }
-
- @Override
- protected final void resetAll() {
- mGroupSizeBits = -1;
- super.resetAll();
- }
-
- @Override
- protected final void resetWhilePreservingInitState() {
- super.resetWhilePreservingInitState();
- }
-
- @Override
- protected final void addAlgorithmSpecificParametersToBegin(
- @NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_EC);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForSign() {
- return (mGroupSizeBits + 7) / 8;
- }
-
- protected final int getGroupSizeBits() {
- if (mGroupSizeBits == -1) {
- throw new IllegalStateException("Not initialized");
- }
- return mGroupSizeBits;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreECPrivateKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreECPrivateKey.java
deleted file mode 100644
index aa7bdffb9e07..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreECPrivateKey.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import java.security.PrivateKey;
-import java.security.interfaces.ECKey;
-import java.security.spec.ECParameterSpec;
-
-/**
- * EC private key (instance of {@link PrivateKey} and {@link ECKey}) backed by keystore.
- *
- * @hide
- */
-public class AndroidKeyStoreECPrivateKey extends AndroidKeyStorePrivateKey implements ECKey {
- private final ECParameterSpec mParams;
-
- public AndroidKeyStoreECPrivateKey(String alias, int uid, ECParameterSpec params) {
- super(alias, uid, KeyProperties.KEY_ALGORITHM_EC);
- mParams = params;
- }
-
- @Override
- public ECParameterSpec getParams() {
- return mParams;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreECPublicKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreECPublicKey.java
deleted file mode 100644
index 2efaeb6545a0..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreECPublicKey.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-
-/**
- * {@link ECPublicKey} backed by keystore.
- *
- * @hide
- */
-public class AndroidKeyStoreECPublicKey extends AndroidKeyStorePublicKey implements ECPublicKey {
-
- private final ECParameterSpec mParams;
- private final ECPoint mW;
-
- public AndroidKeyStoreECPublicKey(String alias, int uid, byte[] x509EncodedForm, ECParameterSpec params,
- ECPoint w) {
- super(alias, uid, KeyProperties.KEY_ALGORITHM_EC, x509EncodedForm);
- mParams = params;
- mW = w;
- }
-
- public AndroidKeyStoreECPublicKey(String alias, int uid, ECPublicKey info) {
- this(alias, uid, info.getEncoded(), info.getParams(), info.getW());
- if (!"X.509".equalsIgnoreCase(info.getFormat())) {
- throw new IllegalArgumentException(
- "Unsupported key export format: " + info.getFormat());
- }
- }
-
- @Override
- public ECParameterSpec getParams() {
- return mParams;
- }
-
- @Override
- public ECPoint getW() {
- return mW;
- }
-} \ No newline at end of file
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
deleted file mode 100644
index 2e8ac3236463..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.os.IBinder;
-import android.security.KeyStore;
-import android.security.KeyStoreException;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keymaster.OperationResult;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.ProviderException;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.MacSpi;
-
-/**
- * {@link MacSpi} which provides HMAC implementations backed by Android KeyStore.
- *
- * @hide
- */
-public abstract class AndroidKeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOperation {
-
- public static class HmacSHA1 extends AndroidKeyStoreHmacSpi {
- public HmacSHA1() {
- super(KeymasterDefs.KM_DIGEST_SHA1);
- }
- }
-
- public static class HmacSHA224 extends AndroidKeyStoreHmacSpi {
- public HmacSHA224() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_224);
- }
- }
-
- public static class HmacSHA256 extends AndroidKeyStoreHmacSpi {
- public HmacSHA256() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_256);
- }
- }
-
- public static class HmacSHA384 extends AndroidKeyStoreHmacSpi {
- public HmacSHA384() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_384);
- }
- }
-
- public static class HmacSHA512 extends AndroidKeyStoreHmacSpi {
- public HmacSHA512() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_512);
- }
- }
-
- private final KeyStore mKeyStore = KeyStore.getInstance();
- private final int mKeymasterDigest;
- private final int mMacSizeBits;
-
- // Fields below are populated by engineInit and should be preserved after engineDoFinal.
- private AndroidKeyStoreSecretKey mKey;
-
- // Fields below are reset when engineDoFinal succeeds.
- private KeyStoreCryptoOperationChunkedStreamer mChunkedStreamer;
- private IBinder mOperationToken;
- private long mOperationHandle;
-
- protected AndroidKeyStoreHmacSpi(int keymasterDigest) {
- mKeymasterDigest = keymasterDigest;
- mMacSizeBits = KeymasterUtils.getDigestOutputSizeBits(keymasterDigest);
- }
-
- @Override
- protected int engineGetMacLength() {
- return (mMacSizeBits + 7) / 8;
- }
-
- @Override
- protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
- InvalidAlgorithmParameterException {
- resetAll();
-
- boolean success = false;
- try {
- init(key, params);
- ensureKeystoreOperationInitialized();
- success = true;
- } finally {
- if (!success) {
- resetAll();
- }
- }
- }
-
- private void init(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
- InvalidAlgorithmParameterException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- } else if (!(key instanceof AndroidKeyStoreSecretKey)) {
- throw new InvalidKeyException(
- "Only Android KeyStore secret keys supported. Key: " + key);
- }
- mKey = (AndroidKeyStoreSecretKey) key;
-
- if (params != null) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported algorithm parameters: " + params);
- }
-
- }
-
- private void resetAll() {
- mKey = null;
- IBinder operationToken = mOperationToken;
- if (operationToken != null) {
- mKeyStore.abort(operationToken);
- }
- mOperationToken = null;
- mOperationHandle = 0;
- mChunkedStreamer = null;
- }
-
- private void resetWhilePreservingInitState() {
- IBinder operationToken = mOperationToken;
- if (operationToken != null) {
- mKeyStore.abort(operationToken);
- }
- mOperationToken = null;
- mOperationHandle = 0;
- mChunkedStreamer = null;
- }
-
- @Override
- protected void engineReset() {
- resetWhilePreservingInitState();
- }
-
- private void ensureKeystoreOperationInitialized() throws InvalidKeyException {
- if (mChunkedStreamer != null) {
- return;
- }
- if (mKey == null) {
- throw new IllegalStateException("Not initialized");
- }
-
- KeymasterArguments keymasterArgs = new KeymasterArguments();
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mMacSizeBits);
-
- OperationResult opResult = mKeyStore.begin(
- mKey.getAlias(),
- KeymasterDefs.KM_PURPOSE_SIGN,
- true,
- keymasterArgs,
- null, // no additional entropy needed for HMAC because it's deterministic
- mKey.getUid());
-
- if (opResult == null) {
- throw new KeyStoreConnectException();
- }
-
- // Store operation token and handle regardless of the error code returned by KeyStore to
- // ensure that the operation gets aborted immediately if the code below throws an exception.
- mOperationToken = opResult.token;
- mOperationHandle = opResult.operationHandle;
-
- // If necessary, throw an exception due to KeyStore operation having failed.
- InvalidKeyException e = KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(
- mKeyStore, mKey, opResult.resultCode);
- if (e != null) {
- throw e;
- }
-
- if (mOperationToken == null) {
- throw new ProviderException("Keystore returned null operation token");
- }
- if (mOperationHandle == 0) {
- throw new ProviderException("Keystore returned invalid operation handle");
- }
-
- mChunkedStreamer = new KeyStoreCryptoOperationChunkedStreamer(
- new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
- mKeyStore, mOperationToken));
- }
-
- @Override
- protected void engineUpdate(byte input) {
- engineUpdate(new byte[] {input}, 0, 1);
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- try {
- ensureKeystoreOperationInitialized();
- } catch (InvalidKeyException e) {
- throw new ProviderException("Failed to reinitialize MAC", e);
- }
-
- byte[] output;
- try {
- output = mChunkedStreamer.update(input, offset, len);
- } catch (KeyStoreException e) {
- throw new ProviderException("Keystore operation failed", e);
- }
- if ((output != null) && (output.length != 0)) {
- throw new ProviderException("Update operation unexpectedly produced output");
- }
- }
-
- @Override
- protected byte[] engineDoFinal() {
- try {
- ensureKeystoreOperationInitialized();
- } catch (InvalidKeyException e) {
- throw new ProviderException("Failed to reinitialize MAC", e);
- }
-
- byte[] result;
- try {
- result = mChunkedStreamer.doFinal(
- null, 0, 0,
- null, // no signature provided -- this invocation will generate one
- null // no additional entropy needed -- HMAC is deterministic
- );
- } catch (KeyStoreException e) {
- throw new ProviderException("Keystore operation failed", e);
- }
-
- resetWhilePreservingInitState();
- return result;
- }
-
- @Override
- public void finalize() throws Throwable {
- try {
- IBinder operationToken = mOperationToken;
- if (operationToken != null) {
- mKeyStore.abort(operationToken);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public long getOperationHandle() {
- return mOperationHandle;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreKey.java
deleted file mode 100644
index e8e63105925f..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKey.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import java.security.Key;
-
-/**
- * {@link Key} backed by Android Keystore.
- *
- * @hide
- */
-public class AndroidKeyStoreKey implements Key {
- private final String mAlias;
- private final int mUid;
- private final String mAlgorithm;
-
- public AndroidKeyStoreKey(String alias, int uid, String algorithm) {
- mAlias = alias;
- mUid = uid;
- mAlgorithm = algorithm;
- }
-
- String getAlias() {
- return mAlias;
- }
-
- int getUid() {
- return mUid;
- }
-
- @Override
- public String getAlgorithm() {
- return mAlgorithm;
- }
-
- @Override
- public String getFormat() {
- // This key does not export its key material
- return null;
- }
-
- @Override
- public byte[] getEncoded() {
- // This key does not export its key material
- return null;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((mAlgorithm == null) ? 0 : mAlgorithm.hashCode());
- result = prime * result + ((mAlias == null) ? 0 : mAlias.hashCode());
- result = prime * result + mUid;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- AndroidKeyStoreKey other = (AndroidKeyStoreKey) obj;
- if (mAlgorithm == null) {
- if (other.mAlgorithm != null) {
- return false;
- }
- } else if (!mAlgorithm.equals(other.mAlgorithm)) {
- return false;
- }
- if (mAlias == null) {
- if (other.mAlias != null) {
- return false;
- }
- } else if (!mAlias.equals(other.mAlias)) {
- return false;
- }
- if (mUid != other.mUid) {
- return false;
- }
- return true;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
deleted file mode 100644
index 303b0f2c05c2..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.security.Credentials;
-import android.security.KeyStore;
-
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactorySpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-/**
- * {@link KeyFactorySpi} backed by Android KeyStore.
- *
- * @hide
- */
-public class AndroidKeyStoreKeyFactorySpi extends KeyFactorySpi {
-
- private final KeyStore mKeyStore = KeyStore.getInstance();
-
- @Override
- protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpecClass)
- throws InvalidKeySpecException {
- if (key == null) {
- throw new InvalidKeySpecException("key == null");
- } else if ((!(key instanceof AndroidKeyStorePrivateKey))
- && (!(key instanceof AndroidKeyStorePublicKey))) {
- throw new InvalidKeySpecException(
- "Unsupported key type: " + key.getClass().getName()
- + ". This KeyFactory supports only Android Keystore asymmetric keys");
- }
-
- // key is an Android Keystore private or public key
-
- if (keySpecClass == null) {
- throw new InvalidKeySpecException("keySpecClass == null");
- } else if (KeyInfo.class.equals(keySpecClass)) {
- if (!(key instanceof AndroidKeyStorePrivateKey)) {
- throw new InvalidKeySpecException(
- "Unsupported key type: " + key.getClass().getName()
- + ". KeyInfo can be obtained only for Android Keystore private keys");
- }
- AndroidKeyStorePrivateKey keystorePrivateKey = (AndroidKeyStorePrivateKey) key;
- String keyAliasInKeystore = keystorePrivateKey.getAlias();
- String entryAlias;
- if (keyAliasInKeystore.startsWith(Credentials.USER_PRIVATE_KEY)) {
- entryAlias = keyAliasInKeystore.substring(Credentials.USER_PRIVATE_KEY.length());
- } else {
- throw new InvalidKeySpecException("Invalid key alias: " + keyAliasInKeystore);
- }
- @SuppressWarnings("unchecked")
- T result = (T) AndroidKeyStoreSecretKeyFactorySpi.getKeyInfo(
- mKeyStore, entryAlias, keyAliasInKeystore, keystorePrivateKey.getUid());
- return result;
- } else if (X509EncodedKeySpec.class.equals(keySpecClass)) {
- if (!(key instanceof AndroidKeyStorePublicKey)) {
- throw new InvalidKeySpecException(
- "Unsupported key type: " + key.getClass().getName()
- + ". X509EncodedKeySpec can be obtained only for Android Keystore public"
- + " keys");
- }
- @SuppressWarnings("unchecked")
- T result = (T) new X509EncodedKeySpec(((AndroidKeyStorePublicKey) key).getEncoded());
- return result;
- } else if (PKCS8EncodedKeySpec.class.equals(keySpecClass)) {
- if (key instanceof AndroidKeyStorePrivateKey) {
- throw new InvalidKeySpecException(
- "Key material export of Android Keystore private keys is not supported");
- } else {
- throw new InvalidKeySpecException(
- "Cannot export key material of public key in PKCS#8 format."
- + " Only X.509 format (X509EncodedKeySpec) supported for public keys.");
- }
- } else if (RSAPublicKeySpec.class.equals(keySpecClass)) {
- if (key instanceof AndroidKeyStoreRSAPublicKey) {
- AndroidKeyStoreRSAPublicKey rsaKey = (AndroidKeyStoreRSAPublicKey) key;
- @SuppressWarnings("unchecked")
- T result =
- (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
- return result;
- } else {
- throw new InvalidKeySpecException(
- "Obtaining RSAPublicKeySpec not supported for " + key.getAlgorithm() + " "
- + ((key instanceof AndroidKeyStorePrivateKey) ? "private" : "public")
- + " key");
- }
- } else if (ECPublicKeySpec.class.equals(keySpecClass)) {
- if (key instanceof AndroidKeyStoreECPublicKey) {
- AndroidKeyStoreECPublicKey ecKey = (AndroidKeyStoreECPublicKey) key;
- @SuppressWarnings("unchecked")
- T result = (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
- return result;
- } else {
- throw new InvalidKeySpecException(
- "Obtaining ECPublicKeySpec not supported for " + key.getAlgorithm() + " "
- + ((key instanceof AndroidKeyStorePrivateKey) ? "private" : "public")
- + " key");
- }
- } else {
- throw new InvalidKeySpecException("Unsupported key spec: " + keySpecClass.getName());
- }
- }
-
- @Override
- protected PrivateKey engineGeneratePrivate(KeySpec spec) throws InvalidKeySpecException {
- throw new InvalidKeySpecException(
- "To generate a key pair in Android Keystore, use KeyPairGenerator initialized with"
- + " " + KeyGenParameterSpec.class.getName());
- }
-
- @Override
- protected PublicKey engineGeneratePublic(KeySpec spec) throws InvalidKeySpecException {
- throw new InvalidKeySpecException(
- "To generate a key pair in Android Keystore, use KeyPairGenerator initialized with"
- + " " + KeyGenParameterSpec.class.getName());
- }
-
- @Override
- protected Key engineTranslateKey(Key key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- } else if ((!(key instanceof AndroidKeyStorePrivateKey))
- && (!(key instanceof AndroidKeyStorePublicKey))) {
- throw new InvalidKeyException(
- "To import a key into Android Keystore, use KeyStore.setEntry");
- }
- return key;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
deleted file mode 100644
index fedde422e0be..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.security.Credentials;
-import android.security.KeyStore;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keystore.KeyGenParameterSpec;
-import android.security.keystore.KeyProperties;
-
-import libcore.util.EmptyArray;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.ProviderException;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.util.Arrays;
-
-import javax.crypto.KeyGeneratorSpi;
-import javax.crypto.SecretKey;
-
-/**
- * {@link KeyGeneratorSpi} backed by Android KeyStore.
- *
- * @hide
- */
-public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
-
- public static class AES extends AndroidKeyStoreKeyGeneratorSpi {
- public AES() {
- super(KeymasterDefs.KM_ALGORITHM_AES, 128);
- }
-
- @Override
- protected void engineInit(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- super.engineInit(params, random);
- if ((mKeySizeBits != 128) && (mKeySizeBits != 192) && (mKeySizeBits != 256)) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported key size: " + mKeySizeBits
- + ". Supported: 128, 192, 256.");
- }
- }
- }
-
- public static class DESede extends AndroidKeyStoreKeyGeneratorSpi {
- public DESede() {
- super(KeymasterDefs.KM_ALGORITHM_3DES, 168);
- }
- }
-
- protected static abstract class HmacBase extends AndroidKeyStoreKeyGeneratorSpi {
- protected HmacBase(int keymasterDigest) {
- super(KeymasterDefs.KM_ALGORITHM_HMAC,
- keymasterDigest,
- KeymasterUtils.getDigestOutputSizeBits(keymasterDigest));
- }
- }
-
- public static class HmacSHA1 extends HmacBase {
- public HmacSHA1() {
- super(KeymasterDefs.KM_DIGEST_SHA1);
- }
- }
-
- public static class HmacSHA224 extends HmacBase {
- public HmacSHA224() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_224);
- }
- }
-
- public static class HmacSHA256 extends HmacBase {
- public HmacSHA256() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_256);
- }
- }
-
- public static class HmacSHA384 extends HmacBase {
- public HmacSHA384() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_384);
- }
- }
-
- public static class HmacSHA512 extends HmacBase {
- public HmacSHA512() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_512);
- }
- }
-
- private final KeyStore mKeyStore = KeyStore.getInstance();
- private final int mKeymasterAlgorithm;
- private final int mKeymasterDigest;
- private final int mDefaultKeySizeBits;
-
- private KeyGenParameterSpec mSpec;
- private SecureRandom mRng;
-
- protected int mKeySizeBits;
- private int[] mKeymasterPurposes;
- private int[] mKeymasterBlockModes;
- private int[] mKeymasterPaddings;
- private int[] mKeymasterDigests;
-
- protected AndroidKeyStoreKeyGeneratorSpi(
- int keymasterAlgorithm,
- int defaultKeySizeBits) {
- this(keymasterAlgorithm, -1, defaultKeySizeBits);
- }
-
- protected AndroidKeyStoreKeyGeneratorSpi(
- int keymasterAlgorithm,
- int keymasterDigest,
- int defaultKeySizeBits) {
- mKeymasterAlgorithm = keymasterAlgorithm;
- mKeymasterDigest = keymasterDigest;
- mDefaultKeySizeBits = defaultKeySizeBits;
- if (mDefaultKeySizeBits <= 0) {
- throw new IllegalArgumentException("Default key size must be positive");
- }
-
- if ((mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) && (mKeymasterDigest == -1)) {
- throw new IllegalArgumentException(
- "Digest algorithm must be specified for HMAC key");
- }
- }
-
- @Override
- protected void engineInit(SecureRandom random) {
- throw new UnsupportedOperationException("Cannot initialize without a "
- + KeyGenParameterSpec.class.getName() + " parameter");
- }
-
- @Override
- protected void engineInit(int keySize, SecureRandom random) {
- throw new UnsupportedOperationException("Cannot initialize without a "
- + KeyGenParameterSpec.class.getName() + " parameter");
- }
-
- @Override
- protected void engineInit(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- resetAll();
-
- boolean success = false;
- try {
- if ((params == null) || (!(params instanceof KeyGenParameterSpec))) {
- throw new InvalidAlgorithmParameterException("Cannot initialize without a "
- + KeyGenParameterSpec.class.getName() + " parameter");
- }
- KeyGenParameterSpec spec = (KeyGenParameterSpec) params;
- if (spec.getKeystoreAlias() == null) {
- throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
- }
-
- mRng = random;
- mSpec = spec;
-
- mKeySizeBits = (spec.getKeySize() != -1) ? spec.getKeySize() : mDefaultKeySizeBits;
- if (mKeySizeBits <= 0) {
- throw new InvalidAlgorithmParameterException(
- "Key size must be positive: " + mKeySizeBits);
- } else if ((mKeySizeBits % 8) != 0) {
- throw new InvalidAlgorithmParameterException(
- "Key size must be a multiple of 8: " + mKeySizeBits);
- }
-
- try {
- mKeymasterPurposes = KeyProperties.Purpose.allToKeymaster(spec.getPurposes());
- mKeymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
- spec.getEncryptionPaddings());
- if (spec.getSignaturePaddings().length > 0) {
- throw new InvalidAlgorithmParameterException(
- "Signature paddings not supported for symmetric key algorithms");
- }
- mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
- if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
- && (spec.isRandomizedEncryptionRequired())) {
- for (int keymasterBlockMode : mKeymasterBlockModes) {
- if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(
- keymasterBlockMode)) {
- throw new InvalidAlgorithmParameterException(
- "Randomized encryption (IND-CPA) required but may be violated"
- + " by block mode: "
- + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode)
- + ". See " + KeyGenParameterSpec.class.getName()
- + " documentation.");
- }
- }
- }
- if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_3DES) {
- if (mKeySizeBits != 168) {
- throw new InvalidAlgorithmParameterException(
- "3DES key size must be 168 bits.");
- }
- }
- if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
- if (mKeySizeBits < 64 || mKeySizeBits > 512) {
- throw new InvalidAlgorithmParameterException(
- "HMAC key sizes must be within 64-512 bits, inclusive.");
- }
-
- // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm
- // implies SHA-256 digest). Because keymaster HMAC key is authorized only for
- // one digest, we don't let algorithm parameter spec override the digest implied
- // by the key. If the spec specifies digests at all, it must specify only one
- // digest, the only implied by key algorithm.
- mKeymasterDigests = new int[] {mKeymasterDigest};
- if (spec.isDigestsSpecified()) {
- // Digest(s) explicitly specified in the spec. Check that the list
- // consists of exactly one digest, the one implied by key algorithm.
- int[] keymasterDigestsFromSpec =
- KeyProperties.Digest.allToKeymaster(spec.getDigests());
- if ((keymasterDigestsFromSpec.length != 1)
- || (keymasterDigestsFromSpec[0] != mKeymasterDigest)) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported digests specification: "
- + Arrays.asList(spec.getDigests()) + ". Only "
- + KeyProperties.Digest.fromKeymaster(mKeymasterDigest)
- + " supported for this HMAC key algorithm");
- }
- }
- } else {
- // Key algorithm does not imply a digest.
- if (spec.isDigestsSpecified()) {
- mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests());
- } else {
- mKeymasterDigests = EmptyArray.INT;
- }
- }
-
- // Check that user authentication related parameters are acceptable. This method
- // will throw an IllegalStateException if there are issues (e.g., secure lock screen
- // not set up).
- KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec);
- } catch (IllegalStateException | IllegalArgumentException e) {
- throw new InvalidAlgorithmParameterException(e);
- }
-
- success = true;
- } finally {
- if (!success) {
- resetAll();
- }
- }
- }
-
- private void resetAll() {
- mSpec = null;
- mRng = null;
- mKeySizeBits = -1;
- mKeymasterPurposes = null;
- mKeymasterPaddings = null;
- mKeymasterBlockModes = null;
- }
-
- @Override
- protected SecretKey engineGenerateKey() {
- KeyGenParameterSpec spec = mSpec;
- if (spec == null) {
- throw new IllegalStateException("Not initialized");
- }
-
- KeymasterArguments args = new KeymasterArguments();
- args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
- args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
- args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
- args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
- args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
- KeymasterUtils.addUserAuthArgs(args, spec);
- KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
- args,
- mKeymasterAlgorithm,
- mKeymasterBlockModes,
- mKeymasterDigests);
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, spec.getKeyValidityStart());
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
- spec.getKeyValidityForOriginationEnd());
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
- spec.getKeyValidityForConsumptionEnd());
-
- if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
- && (!spec.isRandomizedEncryptionRequired())) {
- // Permit caller-provided IV when encrypting with this key
- args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
- }
-
- byte[] additionalEntropy =
- KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
- mRng, (mKeySizeBits + 7) / 8);
- int flags = 0;
- if (spec.isStrongBoxBacked()) {
- flags |= KeyStore.FLAG_STRONGBOX;
- }
- if (spec.isCriticalToDeviceEncryption()) {
- flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
- }
- String keyAliasInKeystore = Credentials.USER_PRIVATE_KEY + spec.getKeystoreAlias();
- KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
- boolean success = false;
- try {
- Credentials.deleteAllTypesForAlias(mKeyStore, spec.getKeystoreAlias(), spec.getUid());
- int errorCode = mKeyStore.generateKey(
- keyAliasInKeystore,
- args,
- additionalEntropy,
- spec.getUid(),
- flags,
- resultingKeyCharacteristics);
- if (errorCode != KeyStore.NO_ERROR) {
- if (errorCode == KeyStore.HARDWARE_TYPE_UNAVAILABLE) {
- throw new StrongBoxUnavailableException("Failed to generate key");
- } else {
- throw new ProviderException(
- "Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
- }
- }
- @KeyProperties.KeyAlgorithmEnum String keyAlgorithmJCA;
- try {
- keyAlgorithmJCA = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(
- mKeymasterAlgorithm, mKeymasterDigest);
- } catch (IllegalArgumentException e) {
- throw new ProviderException("Failed to obtain JCA secret key algorithm name", e);
- }
- SecretKey result = new AndroidKeyStoreSecretKey(
- keyAliasInKeystore, spec.getUid(), keyAlgorithmJCA);
- success = true;
- return result;
- } finally {
- if (!success) {
- Credentials.deleteAllTypesForAlias(
- mKeyStore, spec.getKeystoreAlias(), spec.getUid());
- }
- }
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
deleted file mode 100644
index 988838b46334..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ /dev/null
@@ -1,986 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.os.Build;
-import android.security.Credentials;
-import android.security.KeyPairGeneratorSpec;
-import android.security.KeyStore;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterCertificateChain;
-import android.security.keymaster.KeymasterDefs;
-import android.telephony.TelephonyManager;
-import android.util.ArraySet;
-
-import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
-import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
-import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
-import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
-import com.android.internal.org.bouncycastle.asn1.DERNull;
-import com.android.internal.org.bouncycastle.asn1.DERSequence;
-import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
-import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate;
-import com.android.internal.org.bouncycastle.asn1.x509.Time;
-import com.android.internal.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
-import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
-import com.android.internal.org.bouncycastle.jce.X509Principal;
-import com.android.internal.org.bouncycastle.jce.provider.X509CertificateObject;
-import com.android.internal.org.bouncycastle.x509.X509V3CertificateGenerator;
-
-import libcore.util.EmptyArray;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.nio.charset.StandardCharsets;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyPairGeneratorSpi;
-import java.security.PrivateKey;
-import java.security.ProviderException;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Provides a way to create instances of a KeyPair which will be placed in the
- * Android keystore service usable only by the application that called it. This
- * can be used in conjunction with
- * {@link java.security.KeyStore#getInstance(String)} using the
- * {@code "AndroidKeyStore"} type.
- * <p>
- * This class can not be directly instantiated and must instead be used via the
- * {@link KeyPairGenerator#getInstance(String)
- * KeyPairGenerator.getInstance("AndroidKeyStore")} API.
- *
- * @hide
- */
-public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
-
- public static class RSA extends AndroidKeyStoreKeyPairGeneratorSpi {
- public RSA() {
- super(KeymasterDefs.KM_ALGORITHM_RSA);
- }
- }
-
- public static class EC extends AndroidKeyStoreKeyPairGeneratorSpi {
- public EC() {
- super(KeymasterDefs.KM_ALGORITHM_EC);
- }
- }
-
- /*
- * These must be kept in sync with system/security/keystore/defaults.h
- */
-
- /* EC */
- private static final int EC_DEFAULT_KEY_SIZE = 256;
-
- /* RSA */
- private static final int RSA_DEFAULT_KEY_SIZE = 2048;
- private static final int RSA_MIN_KEY_SIZE = 512;
- private static final int RSA_MAX_KEY_SIZE = 8192;
-
- private static final Map<String, Integer> SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE =
- new HashMap<String, Integer>();
- private static final List<String> SUPPORTED_EC_NIST_CURVE_NAMES = new ArrayList<String>();
- private static final List<Integer> SUPPORTED_EC_NIST_CURVE_SIZES = new ArrayList<Integer>();
- static {
- // Aliases for NIST P-224
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-224", 224);
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp224r1", 224);
-
-
- // Aliases for NIST P-256
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-256", 256);
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp256r1", 256);
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("prime256v1", 256);
-
- // Aliases for NIST P-384
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-384", 384);
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp384r1", 384);
-
- // Aliases for NIST P-521
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-521", 521);
- SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp521r1", 521);
-
- SUPPORTED_EC_NIST_CURVE_NAMES.addAll(SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.keySet());
- Collections.sort(SUPPORTED_EC_NIST_CURVE_NAMES);
-
- SUPPORTED_EC_NIST_CURVE_SIZES.addAll(
- new HashSet<Integer>(SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.values()));
- Collections.sort(SUPPORTED_EC_NIST_CURVE_SIZES);
- }
-
- private final int mOriginalKeymasterAlgorithm;
-
- private KeyStore mKeyStore;
-
- private KeyGenParameterSpec mSpec;
-
- private String mEntryAlias;
- private int mEntryUid;
- private boolean mEncryptionAtRestRequired;
- private @KeyProperties.KeyAlgorithmEnum String mJcaKeyAlgorithm;
- private int mKeymasterAlgorithm = -1;
- private int mKeySizeBits;
- private SecureRandom mRng;
-
- private int[] mKeymasterPurposes;
- private int[] mKeymasterBlockModes;
- private int[] mKeymasterEncryptionPaddings;
- private int[] mKeymasterSignaturePaddings;
- private int[] mKeymasterDigests;
-
- private BigInteger mRSAPublicExponent;
-
- protected AndroidKeyStoreKeyPairGeneratorSpi(int keymasterAlgorithm) {
- mOriginalKeymasterAlgorithm = keymasterAlgorithm;
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public void initialize(int keysize, SecureRandom random) {
- throw new IllegalArgumentException(
- KeyGenParameterSpec.class.getName() + " or " + KeyPairGeneratorSpec.class.getName()
- + " required to initialize this KeyPairGenerator");
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public void initialize(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- resetAll();
-
- boolean success = false;
- try {
- if (params == null) {
- throw new InvalidAlgorithmParameterException(
- "Must supply params of type " + KeyGenParameterSpec.class.getName()
- + " or " + KeyPairGeneratorSpec.class.getName());
- }
-
- KeyGenParameterSpec spec;
- boolean encryptionAtRestRequired = false;
- int keymasterAlgorithm = mOriginalKeymasterAlgorithm;
- if (params instanceof KeyGenParameterSpec) {
- spec = (KeyGenParameterSpec) params;
- } else if (params instanceof KeyPairGeneratorSpec) {
- // Legacy/deprecated spec
- KeyPairGeneratorSpec legacySpec = (KeyPairGeneratorSpec) params;
- try {
- KeyGenParameterSpec.Builder specBuilder;
- String specKeyAlgorithm = legacySpec.getKeyType();
- if (specKeyAlgorithm != null) {
- // Spec overrides the generator's default key algorithm
- try {
- keymasterAlgorithm =
- KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(
- specKeyAlgorithm);
- } catch (IllegalArgumentException e) {
- throw new InvalidAlgorithmParameterException(
- "Invalid key type in parameters", e);
- }
- }
- switch (keymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_EC:
- specBuilder = new KeyGenParameterSpec.Builder(
- legacySpec.getKeystoreAlias(),
- KeyProperties.PURPOSE_SIGN
- | KeyProperties.PURPOSE_VERIFY);
- // Authorized to be used with any digest (including no digest).
- // MD5 was never offered for Android Keystore for ECDSA.
- specBuilder.setDigests(
- KeyProperties.DIGEST_NONE,
- KeyProperties.DIGEST_SHA1,
- KeyProperties.DIGEST_SHA224,
- KeyProperties.DIGEST_SHA256,
- KeyProperties.DIGEST_SHA384,
- KeyProperties.DIGEST_SHA512);
- break;
- case KeymasterDefs.KM_ALGORITHM_RSA:
- specBuilder = new KeyGenParameterSpec.Builder(
- legacySpec.getKeystoreAlias(),
- KeyProperties.PURPOSE_ENCRYPT
- | KeyProperties.PURPOSE_DECRYPT
- | KeyProperties.PURPOSE_SIGN
- | KeyProperties.PURPOSE_VERIFY);
- // Authorized to be used with any digest (including no digest).
- specBuilder.setDigests(
- KeyProperties.DIGEST_NONE,
- KeyProperties.DIGEST_MD5,
- KeyProperties.DIGEST_SHA1,
- KeyProperties.DIGEST_SHA224,
- KeyProperties.DIGEST_SHA256,
- KeyProperties.DIGEST_SHA384,
- KeyProperties.DIGEST_SHA512);
- // Authorized to be used with any encryption and signature padding
- // schemes (including no padding).
- specBuilder.setEncryptionPaddings(
- KeyProperties.ENCRYPTION_PADDING_NONE,
- KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
- KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
- specBuilder.setSignaturePaddings(
- KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
- KeyProperties.SIGNATURE_PADDING_RSA_PSS);
- // Disable randomized encryption requirement to support encryption
- // padding NONE above.
- specBuilder.setRandomizedEncryptionRequired(false);
- break;
- default:
- throw new ProviderException(
- "Unsupported algorithm: " + mKeymasterAlgorithm);
- }
-
- if (legacySpec.getKeySize() != -1) {
- specBuilder.setKeySize(legacySpec.getKeySize());
- }
- if (legacySpec.getAlgorithmParameterSpec() != null) {
- specBuilder.setAlgorithmParameterSpec(
- legacySpec.getAlgorithmParameterSpec());
- }
- specBuilder.setCertificateSubject(legacySpec.getSubjectDN());
- specBuilder.setCertificateSerialNumber(legacySpec.getSerialNumber());
- specBuilder.setCertificateNotBefore(legacySpec.getStartDate());
- specBuilder.setCertificateNotAfter(legacySpec.getEndDate());
- encryptionAtRestRequired = legacySpec.isEncryptionRequired();
- specBuilder.setUserAuthenticationRequired(false);
-
- spec = specBuilder.build();
- } catch (NullPointerException | IllegalArgumentException e) {
- throw new InvalidAlgorithmParameterException(e);
- }
- } else {
- throw new InvalidAlgorithmParameterException(
- "Unsupported params class: " + params.getClass().getName()
- + ". Supported: " + KeyGenParameterSpec.class.getName()
- + ", " + KeyPairGeneratorSpec.class.getName());
- }
-
- mEntryAlias = spec.getKeystoreAlias();
- mEntryUid = spec.getUid();
- mSpec = spec;
- mKeymasterAlgorithm = keymasterAlgorithm;
- mEncryptionAtRestRequired = encryptionAtRestRequired;
- mKeySizeBits = spec.getKeySize();
- initAlgorithmSpecificParameters();
- if (mKeySizeBits == -1) {
- mKeySizeBits = getDefaultKeySize(keymasterAlgorithm);
- }
- checkValidKeySize(keymasterAlgorithm, mKeySizeBits, mSpec.isStrongBoxBacked());
-
- if (spec.getKeystoreAlias() == null) {
- throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
- }
-
- String jcaKeyAlgorithm;
- try {
- jcaKeyAlgorithm = KeyProperties.KeyAlgorithm.fromKeymasterAsymmetricKeyAlgorithm(
- keymasterAlgorithm);
- mKeymasterPurposes = KeyProperties.Purpose.allToKeymaster(spec.getPurposes());
- mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
- mKeymasterEncryptionPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
- spec.getEncryptionPaddings());
- if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
- && (spec.isRandomizedEncryptionRequired())) {
- for (int keymasterPadding : mKeymasterEncryptionPaddings) {
- if (!KeymasterUtils
- .isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto(
- keymasterPadding)) {
- throw new InvalidAlgorithmParameterException(
- "Randomized encryption (IND-CPA) required but may be violated"
- + " by padding scheme: "
- + KeyProperties.EncryptionPadding.fromKeymaster(
- keymasterPadding)
- + ". See " + KeyGenParameterSpec.class.getName()
- + " documentation.");
- }
- }
- }
- mKeymasterSignaturePaddings = KeyProperties.SignaturePadding.allToKeymaster(
- spec.getSignaturePaddings());
- if (spec.isDigestsSpecified()) {
- mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests());
- } else {
- mKeymasterDigests = EmptyArray.INT;
- }
-
- // Check that user authentication related parameters are acceptable. This method
- // will throw an IllegalStateException if there are issues (e.g., secure lock screen
- // not set up).
- KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec);
- } catch (IllegalArgumentException | IllegalStateException e) {
- throw new InvalidAlgorithmParameterException(e);
- }
-
- mJcaKeyAlgorithm = jcaKeyAlgorithm;
- mRng = random;
- mKeyStore = KeyStore.getInstance();
- success = true;
- } finally {
- if (!success) {
- resetAll();
- }
- }
- }
-
- private void resetAll() {
- mEntryAlias = null;
- mEntryUid = KeyStore.UID_SELF;
- mJcaKeyAlgorithm = null;
- mKeymasterAlgorithm = -1;
- mKeymasterPurposes = null;
- mKeymasterBlockModes = null;
- mKeymasterEncryptionPaddings = null;
- mKeymasterSignaturePaddings = null;
- mKeymasterDigests = null;
- mKeySizeBits = 0;
- mSpec = null;
- mRSAPublicExponent = null;
- mEncryptionAtRestRequired = false;
- mRng = null;
- mKeyStore = null;
- }
-
- private void initAlgorithmSpecificParameters() throws InvalidAlgorithmParameterException {
- AlgorithmParameterSpec algSpecificSpec = mSpec.getAlgorithmParameterSpec();
- switch (mKeymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_RSA:
- {
- BigInteger publicExponent = null;
- if (algSpecificSpec instanceof RSAKeyGenParameterSpec) {
- RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) algSpecificSpec;
- if (mKeySizeBits == -1) {
- mKeySizeBits = rsaSpec.getKeysize();
- } else if (mKeySizeBits != rsaSpec.getKeysize()) {
- throw new InvalidAlgorithmParameterException("RSA key size must match "
- + " between " + mSpec + " and " + algSpecificSpec
- + ": " + mKeySizeBits + " vs " + rsaSpec.getKeysize());
- }
- publicExponent = rsaSpec.getPublicExponent();
- } else if (algSpecificSpec != null) {
- throw new InvalidAlgorithmParameterException(
- "RSA may only use RSAKeyGenParameterSpec");
- }
- if (publicExponent == null) {
- publicExponent = RSAKeyGenParameterSpec.F4;
- }
- if (publicExponent.compareTo(BigInteger.ZERO) < 1) {
- throw new InvalidAlgorithmParameterException(
- "RSA public exponent must be positive: " + publicExponent);
- }
- if (publicExponent.compareTo(KeymasterArguments.UINT64_MAX_VALUE) > 0) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported RSA public exponent: " + publicExponent
- + ". Maximum supported value: " + KeymasterArguments.UINT64_MAX_VALUE);
- }
- mRSAPublicExponent = publicExponent;
- break;
- }
- case KeymasterDefs.KM_ALGORITHM_EC:
- if (algSpecificSpec instanceof ECGenParameterSpec) {
- ECGenParameterSpec ecSpec = (ECGenParameterSpec) algSpecificSpec;
- String curveName = ecSpec.getName();
- Integer ecSpecKeySizeBits = SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.get(
- curveName.toLowerCase(Locale.US));
- if (ecSpecKeySizeBits == null) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported EC curve name: " + curveName
- + ". Supported: " + SUPPORTED_EC_NIST_CURVE_NAMES);
- }
- if (mKeySizeBits == -1) {
- mKeySizeBits = ecSpecKeySizeBits;
- } else if (mKeySizeBits != ecSpecKeySizeBits) {
- throw new InvalidAlgorithmParameterException("EC key size must match "
- + " between " + mSpec + " and " + algSpecificSpec
- + ": " + mKeySizeBits + " vs " + ecSpecKeySizeBits);
- }
- } else if (algSpecificSpec != null) {
- throw new InvalidAlgorithmParameterException(
- "EC may only use ECGenParameterSpec");
- }
- break;
- default:
- throw new ProviderException("Unsupported algorithm: " + mKeymasterAlgorithm);
- }
- }
-
- @Override
- public KeyPair generateKeyPair() {
- if (mKeyStore == null || mSpec == null) {
- throw new IllegalStateException("Not initialized");
- }
-
- int flags = (mEncryptionAtRestRequired) ? KeyStore.FLAG_ENCRYPTED : 0;
- if (((flags & KeyStore.FLAG_ENCRYPTED) != 0)
- && (mKeyStore.state() != KeyStore.State.UNLOCKED)) {
- throw new IllegalStateException(
- "Encryption at rest using secure lock screen credential requested for key pair"
- + ", but the user has not yet entered the credential");
- }
-
- if (mSpec.isStrongBoxBacked()) {
- flags |= KeyStore.FLAG_STRONGBOX;
- }
- if (mSpec.isCriticalToDeviceEncryption()) {
- flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
- }
-
- byte[] additionalEntropy =
- KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
- mRng, (mKeySizeBits + 7) / 8);
-
- Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias, mEntryUid);
- final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + mEntryAlias;
- boolean success = false;
- try {
- generateKeystoreKeyPair(
- privateKeyAlias, constructKeyGenerationArguments(), additionalEntropy, flags);
- KeyPair keyPair = loadKeystoreKeyPair(privateKeyAlias);
-
- storeCertificateChain(flags, createCertificateChain(privateKeyAlias, keyPair));
-
- success = true;
- return keyPair;
- } catch (ProviderException | IllegalArgumentException | DeviceIdAttestationException e) {
- if ((mSpec.getPurposes() & KeyProperties.PURPOSE_WRAP_KEY) != 0) {
- throw new SecureKeyImportUnavailableException(e);
- } else {
- throw new ProviderException(e);
- }
- } finally {
- if (!success) {
- Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias, mEntryUid);
- }
- }
- }
-
- private Iterable<byte[]> createCertificateChain(final String privateKeyAlias, KeyPair keyPair)
- throws ProviderException, DeviceIdAttestationException {
- byte[] challenge = mSpec.getAttestationChallenge();
- if (challenge != null) {
- KeymasterArguments args = new KeymasterArguments();
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_CHALLENGE, challenge);
-
- if (mSpec.isDevicePropertiesAttestationIncluded()) {
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND,
- Build.BRAND.getBytes(StandardCharsets.UTF_8));
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE,
- Build.DEVICE.getBytes(StandardCharsets.UTF_8));
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT,
- Build.PRODUCT.getBytes(StandardCharsets.UTF_8));
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER,
- Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8));
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL,
- Build.MODEL.getBytes(StandardCharsets.UTF_8));
- }
-
- int[] idTypes = mSpec.getAttestationIds();
- if (idTypes != null) {
- final Set<Integer> idTypesSet = new ArraySet<>(idTypes.length);
- for (int idType : idTypes) {
- idTypesSet.add(idType);
- }
- TelephonyManager telephonyService = null;
- if (idTypesSet.contains(AttestationUtils.ID_TYPE_IMEI)
- || idTypesSet.contains(AttestationUtils.ID_TYPE_MEID)) {
- telephonyService =
- (TelephonyManager) KeyStore.getApplicationContext().getSystemService(
- Context.TELEPHONY_SERVICE);
- if (telephonyService == null) {
- throw new DeviceIdAttestationException(
- "Unable to access telephony service");
- }
- }
- for (final Integer idType : idTypesSet) {
- switch (idType) {
- case AttestationUtils.ID_TYPE_SERIAL:
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_SERIAL,
- Build.getSerial().getBytes(StandardCharsets.UTF_8)
- );
- break;
- case AttestationUtils.ID_TYPE_IMEI: {
- final String imei = telephonyService.getImei(0);
- if (imei == null) {
- throw new DeviceIdAttestationException("Unable to retrieve IMEI");
- }
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_IMEI,
- imei.getBytes(StandardCharsets.UTF_8)
- );
- break;
- }
- case AttestationUtils.ID_TYPE_MEID: {
- final String meid = telephonyService.getMeid(0);
- if (meid == null) {
- throw new DeviceIdAttestationException("Unable to retrieve MEID");
- }
- args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MEID,
- meid.getBytes(StandardCharsets.UTF_8)
- );
- break;
- }
- case AttestationUtils.USE_INDIVIDUAL_ATTESTATION: {
- args.addBoolean(KeymasterDefs.KM_TAG_DEVICE_UNIQUE_ATTESTATION);
- break;
- }
- default:
- throw new IllegalArgumentException("Unknown device ID type " + idType);
- }
- }
- }
-
- return getAttestationChain(privateKeyAlias, keyPair, args);
- }
-
- // Very short certificate chain in the non-attestation case.
- return Collections.singleton(generateSelfSignedCertificateBytes(keyPair));
- }
-
- private void generateKeystoreKeyPair(final String privateKeyAlias, KeymasterArguments args,
- byte[] additionalEntropy, final int flags) throws ProviderException {
- KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
- int errorCode = mKeyStore.generateKey(privateKeyAlias, args, additionalEntropy,
- mEntryUid, flags, resultingKeyCharacteristics);
- if (errorCode != KeyStore.NO_ERROR) {
- if (errorCode == KeyStore.HARDWARE_TYPE_UNAVAILABLE) {
- throw new StrongBoxUnavailableException("Failed to generate key pair");
- } else {
- throw new ProviderException(
- "Failed to generate key pair", KeyStore.getKeyStoreException(errorCode));
- }
- }
- }
-
- private KeyPair loadKeystoreKeyPair(final String privateKeyAlias) throws ProviderException {
- try {
- KeyPair result = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
- mKeyStore, privateKeyAlias, mEntryUid);
- if (!mJcaKeyAlgorithm.equalsIgnoreCase(result.getPrivate().getAlgorithm())) {
- throw new ProviderException(
- "Generated key pair algorithm does not match requested algorithm: "
- + result.getPrivate().getAlgorithm() + " vs " + mJcaKeyAlgorithm);
- }
- return result;
- } catch (UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
- throw new ProviderException("Failed to load generated key pair from keystore", e);
- }
- }
-
- private KeymasterArguments constructKeyGenerationArguments()
- throws IllegalArgumentException, DeviceIdAttestationException {
- KeymasterArguments args = new KeymasterArguments();
- args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
- args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
- args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
- args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
- args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterEncryptionPaddings);
- args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
-
- KeymasterUtils.addUserAuthArgs(args, mSpec);
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
- mSpec.getKeyValidityForOriginationEnd());
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
- mSpec.getKeyValidityForConsumptionEnd());
- addAlgorithmSpecificParameters(args);
-
- if (mSpec.isUniqueIdIncluded()) {
- args.addBoolean(KeymasterDefs.KM_TAG_INCLUDE_UNIQUE_ID);
- }
- return args;
- }
-
- private void storeCertificateChain(final int flags, Iterable<byte[]> iterable)
- throws ProviderException {
- Iterator<byte[]> iter = iterable.iterator();
- storeCertificate(
- Credentials.USER_CERTIFICATE, iter.next(), flags, "Failed to store certificate");
-
- if (!iter.hasNext()) {
- return;
- }
-
- ByteArrayOutputStream certificateConcatenationStream = new ByteArrayOutputStream();
- while (iter.hasNext()) {
- byte[] data = iter.next();
- certificateConcatenationStream.write(data, 0, data.length);
- }
-
- storeCertificate(Credentials.CA_CERTIFICATE, certificateConcatenationStream.toByteArray(),
- flags, "Failed to store attestation CA certificate");
- }
-
- private void storeCertificate(String prefix, byte[] certificateBytes, final int flags,
- String failureMessage) throws ProviderException {
- int insertErrorCode = mKeyStore.insert(
- prefix + mEntryAlias,
- certificateBytes,
- mEntryUid,
- flags);
- if (insertErrorCode != KeyStore.NO_ERROR) {
- throw new ProviderException(failureMessage,
- KeyStore.getKeyStoreException(insertErrorCode));
- }
- }
-
- private byte[] generateSelfSignedCertificateBytes(KeyPair keyPair) throws ProviderException {
- try {
- return generateSelfSignedCertificate(keyPair.getPrivate(), keyPair.getPublic())
- .getEncoded();
- } catch (IOException | CertificateParsingException e) {
- throw new ProviderException("Failed to generate self-signed certificate", e);
- } catch (CertificateEncodingException e) {
- throw new ProviderException(
- "Failed to obtain encoded form of self-signed certificate", e);
- }
- }
-
- private Iterable<byte[]> getAttestationChain(String privateKeyAlias,
- KeyPair keyPair, KeymasterArguments args)
- throws ProviderException {
- final KeymasterCertificateChain outChain = new KeymasterCertificateChain();
- final int errorCode;
- if (mSpec.isDevicePropertiesAttestationIncluded()
- && mSpec.getAttestationChallenge() == null) {
- throw new ProviderException("An attestation challenge must be provided when requesting "
- + "device properties attestation.");
- }
- errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain);
- if (errorCode != KeyStore.NO_ERROR) {
- throw new ProviderException("Failed to generate attestation certificate chain",
- KeyStore.getKeyStoreException(errorCode));
- }
- Collection<byte[]> chain = outChain.getCertificates();
- if (chain.size() < 2) {
- throw new ProviderException("Attestation certificate chain contained "
- + chain.size() + " entries. At least two are required.");
- }
- return chain;
- }
-
- private void addAlgorithmSpecificParameters(KeymasterArguments keymasterArgs) {
- switch (mKeymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_RSA:
- keymasterArgs.addUnsignedLong(
- KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, mRSAPublicExponent);
- break;
- case KeymasterDefs.KM_ALGORITHM_EC:
- break;
- default:
- throw new ProviderException("Unsupported algorithm: " + mKeymasterAlgorithm);
- }
- }
-
- private X509Certificate generateSelfSignedCertificate(PrivateKey privateKey,
- PublicKey publicKey) throws CertificateParsingException, IOException {
- String signatureAlgorithm =
- getCertificateSignatureAlgorithm(mKeymasterAlgorithm, mKeySizeBits, mSpec);
- if (signatureAlgorithm == null) {
- // Key cannot be used to sign a certificate
- return generateSelfSignedCertificateWithFakeSignature(publicKey);
- } else {
- // Key can be used to sign a certificate
- try {
- return generateSelfSignedCertificateWithValidSignature(
- privateKey, publicKey, signatureAlgorithm);
- } catch (Exception e) {
- // Failed to generate the self-signed certificate with valid signature. Fall back
- // to generating a self-signed certificate with a fake signature. This is done for
- // all exception types because we prefer key pair generation to succeed and end up
- // producing a self-signed certificate with an invalid signature to key pair
- // generation failing.
- return generateSelfSignedCertificateWithFakeSignature(publicKey);
- }
- }
- }
-
- @SuppressWarnings("deprecation")
- private X509Certificate generateSelfSignedCertificateWithValidSignature(
- PrivateKey privateKey, PublicKey publicKey, String signatureAlgorithm) throws Exception {
- final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
- certGen.setPublicKey(publicKey);
- certGen.setSerialNumber(mSpec.getCertificateSerialNumber());
- certGen.setSubjectDN(mSpec.getCertificateSubject());
- certGen.setIssuerDN(mSpec.getCertificateSubject());
- certGen.setNotBefore(mSpec.getCertificateNotBefore());
- certGen.setNotAfter(mSpec.getCertificateNotAfter());
- certGen.setSignatureAlgorithm(signatureAlgorithm);
- return certGen.generate(privateKey);
- }
-
- @SuppressWarnings("deprecation")
- private X509Certificate generateSelfSignedCertificateWithFakeSignature(
- PublicKey publicKey) throws IOException, CertificateParsingException {
- V3TBSCertificateGenerator tbsGenerator = new V3TBSCertificateGenerator();
- ASN1ObjectIdentifier sigAlgOid;
- AlgorithmIdentifier sigAlgId;
- byte[] signature;
- switch (mKeymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_EC:
- sigAlgOid = X9ObjectIdentifiers.ecdsa_with_SHA256;
- sigAlgId = new AlgorithmIdentifier(sigAlgOid);
- ASN1EncodableVector v = new ASN1EncodableVector();
- v.add(new ASN1Integer(BigInteger.valueOf(0)));
- v.add(new ASN1Integer(BigInteger.valueOf(0)));
- signature = new DERSequence().getEncoded();
- break;
- case KeymasterDefs.KM_ALGORITHM_RSA:
- sigAlgOid = PKCSObjectIdentifiers.sha256WithRSAEncryption;
- sigAlgId = new AlgorithmIdentifier(sigAlgOid, DERNull.INSTANCE);
- signature = new byte[1];
- break;
- default:
- throw new ProviderException("Unsupported key algorithm: " + mKeymasterAlgorithm);
- }
-
- try (ASN1InputStream publicKeyInfoIn = new ASN1InputStream(publicKey.getEncoded())) {
- tbsGenerator.setSubjectPublicKeyInfo(
- SubjectPublicKeyInfo.getInstance(publicKeyInfoIn.readObject()));
- }
- tbsGenerator.setSerialNumber(new ASN1Integer(mSpec.getCertificateSerialNumber()));
- X509Principal subject =
- new X509Principal(mSpec.getCertificateSubject().getEncoded());
- tbsGenerator.setSubject(subject);
- tbsGenerator.setIssuer(subject);
- tbsGenerator.setStartDate(new Time(mSpec.getCertificateNotBefore()));
- tbsGenerator.setEndDate(new Time(mSpec.getCertificateNotAfter()));
- tbsGenerator.setSignature(sigAlgId);
- TBSCertificate tbsCertificate = tbsGenerator.generateTBSCertificate();
-
- ASN1EncodableVector result = new ASN1EncodableVector();
- result.add(tbsCertificate);
- result.add(sigAlgId);
- result.add(new DERBitString(signature));
- return new X509CertificateObject(Certificate.getInstance(new DERSequence(result)));
- }
-
- private static int getDefaultKeySize(int keymasterAlgorithm) {
- switch (keymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_EC:
- return EC_DEFAULT_KEY_SIZE;
- case KeymasterDefs.KM_ALGORITHM_RSA:
- return RSA_DEFAULT_KEY_SIZE;
- default:
- throw new ProviderException("Unsupported algorithm: " + keymasterAlgorithm);
- }
- }
-
- private static void checkValidKeySize(
- int keymasterAlgorithm,
- int keySize,
- boolean isStrongBoxBacked)
- throws InvalidAlgorithmParameterException {
- switch (keymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_EC:
- if (isStrongBoxBacked && keySize != 256) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported StrongBox EC key size: "
- + keySize + " bits. Supported: 256");
- }
- if (!SUPPORTED_EC_NIST_CURVE_SIZES.contains(keySize)) {
- throw new InvalidAlgorithmParameterException("Unsupported EC key size: "
- + keySize + " bits. Supported: " + SUPPORTED_EC_NIST_CURVE_SIZES);
- }
- break;
- case KeymasterDefs.KM_ALGORITHM_RSA:
- if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
- throw new InvalidAlgorithmParameterException("RSA key size must be >= "
- + RSA_MIN_KEY_SIZE + " and <= " + RSA_MAX_KEY_SIZE);
- }
- break;
- default:
- throw new ProviderException("Unsupported algorithm: " + keymasterAlgorithm);
- }
- }
-
- /**
- * Returns the {@code Signature} algorithm to be used for signing a certificate using the
- * specified key or {@code null} if the key cannot be used for signing a certificate.
- */
- @Nullable
- private static String getCertificateSignatureAlgorithm(
- int keymasterAlgorithm,
- int keySizeBits,
- KeyGenParameterSpec spec) {
- // Constraints:
- // 1. Key must be authorized for signing without user authentication.
- // 2. Signature digest must be one of key's authorized digests.
- // 3. For RSA keys, the digest output size must not exceed modulus size minus space overhead
- // of RSA PKCS#1 signature padding scheme (about 30 bytes).
- // 4. For EC keys, the there is no point in using a digest whose output size is longer than
- // key/field size because the digest will be truncated to that size.
-
- if ((spec.getPurposes() & KeyProperties.PURPOSE_SIGN) == 0) {
- // Key not authorized for signing
- return null;
- }
- if (spec.isUserAuthenticationRequired()) {
- // Key not authorized for use without user authentication
- return null;
- }
- if (!spec.isDigestsSpecified()) {
- // Key not authorized for any digests -- can't sign
- return null;
- }
- switch (keymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_EC:
- {
- Set<Integer> availableKeymasterDigests = getAvailableKeymasterSignatureDigests(
- spec.getDigests(),
- AndroidKeyStoreBCWorkaroundProvider.getSupportedEcdsaSignatureDigests());
-
- int bestKeymasterDigest = -1;
- int bestDigestOutputSizeBits = -1;
- for (int keymasterDigest : availableKeymasterDigests) {
- int outputSizeBits = KeymasterUtils.getDigestOutputSizeBits(keymasterDigest);
- if (outputSizeBits == keySizeBits) {
- // Perfect match -- use this digest
- bestKeymasterDigest = keymasterDigest;
- bestDigestOutputSizeBits = outputSizeBits;
- break;
- }
- // Not a perfect match -- check against the best digest so far
- if (bestKeymasterDigest == -1) {
- // First digest tested -- definitely the best so far
- bestKeymasterDigest = keymasterDigest;
- bestDigestOutputSizeBits = outputSizeBits;
- } else {
- // Prefer output size to be as close to key size as possible, with output
- // sizes larger than key size preferred to those smaller than key size.
- if (bestDigestOutputSizeBits < keySizeBits) {
- // Output size of the best digest so far is smaller than key size.
- // Anything larger is a win.
- if (outputSizeBits > bestDigestOutputSizeBits) {
- bestKeymasterDigest = keymasterDigest;
- bestDigestOutputSizeBits = outputSizeBits;
- }
- } else {
- // Output size of the best digest so far is larger than key size.
- // Anything smaller is a win, as long as it's not smaller than key size.
- if ((outputSizeBits < bestDigestOutputSizeBits)
- && (outputSizeBits >= keySizeBits)) {
- bestKeymasterDigest = keymasterDigest;
- bestDigestOutputSizeBits = outputSizeBits;
- }
- }
- }
- }
- if (bestKeymasterDigest == -1) {
- return null;
- }
- return KeyProperties.Digest.fromKeymasterToSignatureAlgorithmDigest(
- bestKeymasterDigest) + "WithECDSA";
- }
- case KeymasterDefs.KM_ALGORITHM_RSA:
- {
- // Check whether this key is authorized for PKCS#1 signature padding.
- // We use Bouncy Castle to generate self-signed RSA certificates. Bouncy Castle
- // only supports RSA certificates signed using PKCS#1 padding scheme. The key needs
- // to be authorized for PKCS#1 padding or padding NONE which means any padding.
- boolean pkcs1SignaturePaddingSupported =
- com.android.internal.util.ArrayUtils.contains(
- KeyProperties.SignaturePadding.allToKeymaster(
- spec.getSignaturePaddings()),
- KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
- if (!pkcs1SignaturePaddingSupported) {
- // Key not authorized for PKCS#1 signature padding -- can't sign
- return null;
- }
-
- Set<Integer> availableKeymasterDigests = getAvailableKeymasterSignatureDigests(
- spec.getDigests(),
- AndroidKeyStoreBCWorkaroundProvider.getSupportedEcdsaSignatureDigests());
-
- // The amount of space available for the digest is less than modulus size by about
- // 30 bytes because padding must be at least 11 bytes long (00 || 01 || PS || 00,
- // where PS must be at least 8 bytes long), and then there's also the 15--19 bytes
- // overhead (depending the on chosen digest) for encoding digest OID and digest
- // value in DER.
- int maxDigestOutputSizeBits = keySizeBits - 30 * 8;
- int bestKeymasterDigest = -1;
- int bestDigestOutputSizeBits = -1;
- for (int keymasterDigest : availableKeymasterDigests) {
- int outputSizeBits = KeymasterUtils.getDigestOutputSizeBits(keymasterDigest);
- if (outputSizeBits > maxDigestOutputSizeBits) {
- // Digest too long (signature generation will fail) -- skip
- continue;
- }
- if (bestKeymasterDigest == -1) {
- // First digest tested -- definitely the best so far
- bestKeymasterDigest = keymasterDigest;
- bestDigestOutputSizeBits = outputSizeBits;
- } else {
- // The longer the better
- if (outputSizeBits > bestDigestOutputSizeBits) {
- bestKeymasterDigest = keymasterDigest;
- bestDigestOutputSizeBits = outputSizeBits;
- }
- }
- }
- if (bestKeymasterDigest == -1) {
- return null;
- }
- return KeyProperties.Digest.fromKeymasterToSignatureAlgorithmDigest(
- bestKeymasterDigest) + "WithRSA";
- }
- default:
- throw new ProviderException("Unsupported algorithm: " + keymasterAlgorithm);
- }
- }
-
- private static Set<Integer> getAvailableKeymasterSignatureDigests(
- @KeyProperties.DigestEnum String[] authorizedKeyDigests,
- @KeyProperties.DigestEnum String[] supportedSignatureDigests) {
- Set<Integer> authorizedKeymasterKeyDigests = new HashSet<Integer>();
- for (int keymasterDigest : KeyProperties.Digest.allToKeymaster(authorizedKeyDigests)) {
- authorizedKeymasterKeyDigests.add(keymasterDigest);
- }
- Set<Integer> supportedKeymasterSignatureDigests = new HashSet<Integer>();
- for (int keymasterDigest
- : KeyProperties.Digest.allToKeymaster(supportedSignatureDigests)) {
- supportedKeymasterSignatureDigests.add(keymasterDigest);
- }
- Set<Integer> result = new HashSet<Integer>(supportedKeymasterSignatureDigests);
- result.retainAll(authorizedKeymasterKeyDigests);
- return result;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreLoadStoreParameter.java b/keystore/java/android/security/keystore/AndroidKeyStoreLoadStoreParameter.java
deleted file mode 100644
index 45d579e371c6..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreLoadStoreParameter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import java.security.KeyStore;
-import java.security.KeyStore.ProtectionParameter;
-
-class AndroidKeyStoreLoadStoreParameter implements KeyStore.LoadStoreParameter {
-
- private final int mUid;
-
- AndroidKeyStoreLoadStoreParameter(int uid) {
- mUid = uid;
- }
-
- @Override
- public ProtectionParameter getProtectionParameter() {
- return null;
- }
-
- int getUid() {
- return mUid;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 087151711138..ecb082e71321 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -20,30 +20,13 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.security.KeyStore;
-import android.security.keymaster.ExportResult;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterDefs;
import java.io.IOException;
-import java.security.KeyFactory;
-import java.security.KeyPair;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
-import java.security.ProviderException;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.Signature;
-import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.Mac;
@@ -57,117 +40,10 @@ import javax.crypto.Mac;
public class AndroidKeyStoreProvider extends Provider {
private static final String PROVIDER_NAME = "AndroidKeyStore";
- // IMPLEMENTATION NOTE: Class names are hard-coded in this provider to avoid loading these
- // classes when this provider is instantiated and installed early on during each app's
- // initialization process.
- //
- // Crypto operations operating on the AndroidKeyStore keys must not be offered by this provider.
- // Instead, they need to be offered by AndroidKeyStoreBCWorkaroundProvider. See its Javadoc
- // for details.
-
- private static final String PACKAGE_NAME = "android.security.keystore";
-
- private static final String DESEDE_SYSTEM_PROPERTY =
- "ro.hardware.keystore_desede";
-
/** @hide */
- public AndroidKeyStoreProvider() {
- this(PROVIDER_NAME);
- }
-
- /** @hide **/
- public AndroidKeyStoreProvider(String providerName) {
- super(providerName, 1.0, "Android KeyStore security provider");
-
- boolean supports3DES = "true".equals(android.os.SystemProperties.get(DESEDE_SYSTEM_PROPERTY));
-
- // java.security.KeyStore
- put("KeyStore." + providerName, PACKAGE_NAME + ".AndroidKeyStoreSpi");
-
- // java.security.KeyPairGenerator
- put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$EC");
- put("KeyPairGenerator.RSA", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
-
- // java.security.KeyFactory
- putKeyFactoryImpl("EC");
- putKeyFactoryImpl("RSA");
-
- // javax.crypto.KeyGenerator
- put("KeyGenerator.AES", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$AES");
- put("KeyGenerator.HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA1");
- put("KeyGenerator.HmacSHA224", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA224");
- put("KeyGenerator.HmacSHA256", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA256");
- put("KeyGenerator.HmacSHA384", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA384");
- put("KeyGenerator.HmacSHA512", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA512");
-
- if (supports3DES) {
- put("KeyGenerator.DESede", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$DESede");
- }
-
- // java.security.SecretKeyFactory
- putSecretKeyFactoryImpl("AES");
- if (supports3DES) {
- putSecretKeyFactoryImpl("DESede");
- }
- putSecretKeyFactoryImpl("HmacSHA1");
- putSecretKeyFactoryImpl("HmacSHA224");
- putSecretKeyFactoryImpl("HmacSHA256");
- putSecretKeyFactoryImpl("HmacSHA384");
- putSecretKeyFactoryImpl("HmacSHA512");
- }
-
- /**
- * This function indicates whether or not Keystore 2.0 is enabled. Some parts of the
- * Keystore SPI must behave subtly differently when Keystore 2.0 is enabled. However,
- * the platform property that indicates that Keystore 2.0 is enabled is not readable
- * by applications. So we set this value when {@code install()} is called because it
- * is called by zygote, which can access Keystore2Properties.
- *
- * This function can be removed once the transition to Keystore 2.0 is complete.
- * b/171305684
- *
- * @return true if Keystore 2.0 is enabled.
- * @hide
- */
- public static boolean isKeystore2Enabled() {
- return android.security.keystore2.AndroidKeyStoreProvider.isInstalled();
- }
-
- /**
- * Installs a new instance of this provider (and the
- * {@link AndroidKeyStoreBCWorkaroundProvider}).
- * @hide
- */
- public static void install() {
- Provider[] providers = Security.getProviders();
- int bcProviderIndex = -1;
- for (int i = 0; i < providers.length; i++) {
- Provider provider = providers[i];
- if ("BC".equals(provider.getName())) {
- bcProviderIndex = i;
- break;
- }
- }
-
- Security.addProvider(new AndroidKeyStoreProvider());
- Provider workaroundProvider = new AndroidKeyStoreBCWorkaroundProvider();
- if (bcProviderIndex != -1) {
- // Bouncy Castle provider found -- install the workaround provider above it.
- // insertProviderAt uses 1-based positions.
- Security.insertProviderAt(workaroundProvider, bcProviderIndex + 1);
- } else {
- // Bouncy Castle provider not found -- install the workaround provider at lowest
- // priority.
- Security.addProvider(workaroundProvider);
- }
- }
-
- private void putSecretKeyFactoryImpl(String algorithm) {
- put("SecretKeyFactory." + algorithm, PACKAGE_NAME + ".AndroidKeyStoreSecretKeyFactorySpi");
- }
-
- private void putKeyFactoryImpl(String algorithm) {
- put("KeyFactory." + algorithm, PACKAGE_NAME + ".AndroidKeyStoreKeyFactorySpi");
+ public AndroidKeyStoreProvider(@NonNull String name) {
+ super(name, 1.0, "Android KeyStore security provider");
+ throw new IllegalStateException("Should not be instantiated.");
}
/**
@@ -189,229 +65,7 @@ public class AndroidKeyStoreProvider extends Provider {
if (cryptoPrimitive == null) {
throw new NullPointerException();
}
- Object spi;
- if (cryptoPrimitive instanceof Signature) {
- spi = ((Signature) cryptoPrimitive).getCurrentSpi();
- } else if (cryptoPrimitive instanceof Mac) {
- spi = ((Mac) cryptoPrimitive).getCurrentSpi();
- } else if (cryptoPrimitive instanceof Cipher) {
- spi = ((Cipher) cryptoPrimitive).getCurrentSpi();
- } else {
- throw new IllegalArgumentException("Unsupported crypto primitive: " + cryptoPrimitive
- + ". Supported: Signature, Mac, Cipher");
- }
- if (spi == null) {
- throw new IllegalStateException("Crypto primitive not initialized");
- } else if (!(spi instanceof KeyStoreCryptoOperation)) {
- throw new IllegalArgumentException(
- "Crypto primitive not backed by AndroidKeyStore provider: " + cryptoPrimitive
- + ", spi: " + spi);
- }
- return ((KeyStoreCryptoOperation) spi).getOperationHandle();
- }
-
- /** @hide **/
- @NonNull
- public static AndroidKeyStorePublicKey getAndroidKeyStorePublicKey(
- @NonNull String alias,
- int uid,
- @NonNull @KeyProperties.KeyAlgorithmEnum String keyAlgorithm,
- @NonNull byte[] x509EncodedForm) {
- PublicKey publicKey;
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
- publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedForm));
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(
- "Failed to obtain " + keyAlgorithm + " KeyFactory", e);
- } catch (InvalidKeySpecException e) {
- throw new ProviderException("Invalid X.509 encoding of public key", e);
- }
- if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
- return new AndroidKeyStoreECPublicKey(alias, uid, (ECPublicKey) publicKey);
- } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
- return new AndroidKeyStoreRSAPublicKey(alias, uid, (RSAPublicKey) publicKey);
- } else {
- throw new ProviderException("Unsupported Android Keystore public key algorithm: "
- + keyAlgorithm);
- }
- }
-
- @NonNull
- private static AndroidKeyStorePrivateKey getAndroidKeyStorePrivateKey(
- @NonNull AndroidKeyStorePublicKey publicKey) {
- String keyAlgorithm = publicKey.getAlgorithm();
- if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
- return new AndroidKeyStoreECPrivateKey(
- publicKey.getAlias(), publicKey.getUid(), ((ECKey) publicKey).getParams());
- } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
- return new AndroidKeyStoreRSAPrivateKey(
- publicKey.getAlias(), publicKey.getUid(), ((RSAKey) publicKey).getModulus());
- } else {
- throw new ProviderException("Unsupported Android Keystore public key algorithm: "
- + keyAlgorithm);
- }
- }
-
- @NonNull
- private static KeyCharacteristics getKeyCharacteristics(@NonNull KeyStore keyStore,
- @NonNull String alias, int uid)
- throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
- KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
- int errorCode = keyStore.getKeyCharacteristics(
- alias, null, null, uid, keyCharacteristics);
- if (errorCode == KeyStore.KEY_PERMANENTLY_INVALIDATED) {
- throw (KeyPermanentlyInvalidatedException)
- new KeyPermanentlyInvalidatedException(
- "User changed or deleted their auth credentials",
- KeyStore.getKeyStoreException(errorCode));
- }
- if (errorCode != KeyStore.NO_ERROR) {
- throw (UnrecoverableKeyException)
- new UnrecoverableKeyException("Failed to obtain information about key")
- .initCause(KeyStore.getKeyStoreException(errorCode));
- }
- return keyCharacteristics;
- }
-
- @NonNull
- private static AndroidKeyStorePublicKey loadAndroidKeyStorePublicKeyFromKeystore(
- @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid,
- KeyCharacteristics keyCharacteristics)
- throws UnrecoverableKeyException {
- ExportResult exportResult = keyStore.exportKey(
- privateKeyAlias, KeymasterDefs.KM_KEY_FORMAT_X509, null, null, uid);
- if (exportResult.resultCode != KeyStore.NO_ERROR) {
- throw (UnrecoverableKeyException)
- new UnrecoverableKeyException("Failed to obtain X.509 form of public key")
- .initCause(KeyStore.getKeyStoreException(exportResult.resultCode));
- }
- final byte[] x509EncodedPublicKey = exportResult.exportData;
-
- Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
- if (keymasterAlgorithm == null) {
- throw new UnrecoverableKeyException("Key algorithm unknown");
- }
-
- String jcaKeyAlgorithm;
- try {
- jcaKeyAlgorithm = KeyProperties.KeyAlgorithm.fromKeymasterAsymmetricKeyAlgorithm(
- keymasterAlgorithm);
- } catch (IllegalArgumentException e) {
- throw (UnrecoverableKeyException)
- new UnrecoverableKeyException("Failed to load private key")
- .initCause(e);
- }
-
- return AndroidKeyStoreProvider.getAndroidKeyStorePublicKey(
- privateKeyAlias, uid, jcaKeyAlgorithm, x509EncodedPublicKey);
- }
-
- /** @hide **/
- @NonNull
- public static AndroidKeyStorePublicKey loadAndroidKeyStorePublicKeyFromKeystore(
- @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
- throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
- return loadAndroidKeyStorePublicKeyFromKeystore(keyStore, privateKeyAlias, uid,
- getKeyCharacteristics(keyStore, privateKeyAlias, uid));
- }
-
- @NonNull
- private static KeyPair loadAndroidKeyStoreKeyPairFromKeystore(
- @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid,
- @NonNull KeyCharacteristics keyCharacteristics)
- throws UnrecoverableKeyException {
- AndroidKeyStorePublicKey publicKey =
- loadAndroidKeyStorePublicKeyFromKeystore(keyStore, privateKeyAlias, uid,
- keyCharacteristics);
- AndroidKeyStorePrivateKey privateKey =
- AndroidKeyStoreProvider.getAndroidKeyStorePrivateKey(publicKey);
- return new KeyPair(publicKey, privateKey);
- }
-
- /** @hide **/
- @NonNull
- public static KeyPair loadAndroidKeyStoreKeyPairFromKeystore(
- @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
- throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
- return loadAndroidKeyStoreKeyPairFromKeystore(keyStore, privateKeyAlias, uid,
- getKeyCharacteristics(keyStore, privateKeyAlias, uid));
- }
-
- @NonNull
- private static AndroidKeyStorePrivateKey loadAndroidKeyStorePrivateKeyFromKeystore(
- @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid,
- @NonNull KeyCharacteristics keyCharacteristics)
- throws UnrecoverableKeyException {
- KeyPair keyPair = loadAndroidKeyStoreKeyPairFromKeystore(keyStore, privateKeyAlias, uid,
- keyCharacteristics);
- return (AndroidKeyStorePrivateKey) keyPair.getPrivate();
- }
-
- /** @hide **/
- @NonNull
- public static AndroidKeyStorePrivateKey loadAndroidKeyStorePrivateKeyFromKeystore(
- @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
- throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
- return loadAndroidKeyStorePrivateKeyFromKeystore(keyStore, privateKeyAlias, uid,
- getKeyCharacteristics(keyStore, privateKeyAlias, uid));
- }
-
- @NonNull
- private static AndroidKeyStoreSecretKey loadAndroidKeyStoreSecretKeyFromKeystore(
- @NonNull String secretKeyAlias, int uid, @NonNull KeyCharacteristics keyCharacteristics)
- throws UnrecoverableKeyException {
- Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
- if (keymasterAlgorithm == null) {
- throw new UnrecoverableKeyException("Key algorithm unknown");
- }
-
- List<Integer> keymasterDigests = keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST);
- int keymasterDigest;
- if (keymasterDigests.isEmpty()) {
- keymasterDigest = -1;
- } else {
- // More than one digest can be permitted for this key. Use the first one to form the
- // JCA key algorithm name.
- keymasterDigest = keymasterDigests.get(0);
- }
-
- @KeyProperties.KeyAlgorithmEnum String keyAlgorithmString;
- try {
- keyAlgorithmString = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(
- keymasterAlgorithm, keymasterDigest);
- } catch (IllegalArgumentException e) {
- throw (UnrecoverableKeyException)
- new UnrecoverableKeyException("Unsupported secret key type").initCause(e);
- }
-
- return new AndroidKeyStoreSecretKey(secretKeyAlias, uid, keyAlgorithmString);
- }
-
- /** @hide **/
- @NonNull
- public static AndroidKeyStoreKey loadAndroidKeyStoreKeyFromKeystore(
- @NonNull KeyStore keyStore, @NonNull String userKeyAlias, int uid)
- throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
- KeyCharacteristics keyCharacteristics = getKeyCharacteristics(keyStore, userKeyAlias, uid);
-
- Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
- if (keymasterAlgorithm == null) {
- throw new UnrecoverableKeyException("Key algorithm unknown");
- }
-
- if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC ||
- keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_AES ||
- keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_3DES) {
- return loadAndroidKeyStoreSecretKeyFromKeystore(userKeyAlias, uid,
- keyCharacteristics);
- } else if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_RSA ||
- keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC) {
- return loadAndroidKeyStorePrivateKeyFromKeystore(keyStore, userKeyAlias, uid,
- keyCharacteristics);
- } else {
- throw new UnrecoverableKeyException("Key algorithm unknown");
- }
+ return 0;
}
/**
@@ -434,13 +88,9 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull
public static java.security.KeyStore getKeyStoreForUid(int uid)
throws KeyStoreException, NoSuchProviderException {
- final java.security.KeyStore.LoadStoreParameter loadParameter;
- if (android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) {
- loadParameter = new android.security.keystore2.AndroidKeyStoreLoadStoreParameter(
- KeyProperties.legacyUidToNamespace(uid));
- } else {
- loadParameter = new AndroidKeyStoreLoadStoreParameter(uid);
- }
+ final java.security.KeyStore.LoadStoreParameter loadParameter =
+ new android.security.keystore2.AndroidKeyStoreLoadStoreParameter(
+ KeyProperties.legacyUidToNamespace(uid));
java.security.KeyStore result = java.security.KeyStore.getInstance(PROVIDER_NAME);
try {
result.load(loadParameter);
diff --git a/keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java b/keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java
deleted file mode 100644
index 4194780906b7..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import java.security.PublicKey;
-import java.util.Arrays;
-
-/**
- * {@link PublicKey} backed by Android Keystore.
- *
- * @hide
- */
-public class AndroidKeyStorePublicKey extends AndroidKeyStoreKey implements PublicKey {
-
- private final byte[] mEncoded;
-
- public AndroidKeyStorePublicKey(String alias, int uid, String algorithm, byte[] x509EncodedForm) {
- super(alias, uid, algorithm);
- mEncoded = ArrayUtils.cloneIfNotEmpty(x509EncodedForm);
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return ArrayUtils.cloneIfNotEmpty(mEncoded);
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + Arrays.hashCode(mEncoded);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- AndroidKeyStorePublicKey other = (AndroidKeyStorePublicKey) obj;
- if (!Arrays.equals(mEncoded, other.mEncoded)) {
- return false;
- }
- return true;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
deleted file mode 100644
index 2ae68fa80117..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.security.KeyStore;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.ProviderException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-import java.security.spec.MGF1ParameterSpec;
-
-import javax.crypto.Cipher;
-import javax.crypto.CipherSpi;
-import javax.crypto.spec.OAEPParameterSpec;
-import javax.crypto.spec.PSource;
-
-/**
- * Base class for {@link CipherSpi} providing Android KeyStore backed RSA encryption/decryption.
- *
- * @hide
- */
-abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase {
-
- /**
- * Raw RSA cipher without any padding.
- */
- public static final class NoPadding extends AndroidKeyStoreRSACipherSpi {
- public NoPadding() {
- super(KeymasterDefs.KM_PAD_NONE);
- }
-
- @Override
- protected boolean adjustConfigForEncryptingWithPrivateKey() {
- // RSA encryption with no padding using private key is a way to implement raw RSA
- // signatures which JCA does not expose via Signature. We thus have to support this.
- setKeymasterPurposeOverride(KeymasterDefs.KM_PURPOSE_SIGN);
- return true;
- }
-
- @Override
- protected void initAlgorithmSpecificParameters() throws InvalidKeyException {}
-
- @Override
- protected void initAlgorithmSpecificParameters(@Nullable AlgorithmParameterSpec params)
- throws InvalidAlgorithmParameterException {
- if (params != null) {
- throw new InvalidAlgorithmParameterException(
- "Unexpected parameters: " + params + ". No parameters supported");
- }
- }
-
- @Override
- protected void initAlgorithmSpecificParameters(@Nullable AlgorithmParameters params)
- throws InvalidAlgorithmParameterException {
-
- if (params != null) {
- throw new InvalidAlgorithmParameterException(
- "Unexpected parameters: " + params + ". No parameters supported");
- }
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- return null;
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForBegin() {
- return 0;
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForFinish() {
- return 0;
- }
- }
-
- /**
- * RSA cipher with PKCS#1 v1.5 encryption padding.
- */
- public static final class PKCS1Padding extends AndroidKeyStoreRSACipherSpi {
- public PKCS1Padding() {
- super(KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
- }
-
- @Override
- protected boolean adjustConfigForEncryptingWithPrivateKey() {
- // RSA encryption with PCKS#1 padding using private key is a way to implement RSA
- // signatures with PKCS#1 padding. We have to support this for legacy reasons.
- setKeymasterPurposeOverride(KeymasterDefs.KM_PURPOSE_SIGN);
- setKeymasterPaddingOverride(KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
- return true;
- }
-
- @Override
- protected void initAlgorithmSpecificParameters() throws InvalidKeyException {}
-
- @Override
- protected void initAlgorithmSpecificParameters(@Nullable AlgorithmParameterSpec params)
- throws InvalidAlgorithmParameterException {
- if (params != null) {
- throw new InvalidAlgorithmParameterException(
- "Unexpected parameters: " + params + ". No parameters supported");
- }
- }
-
- @Override
- protected void initAlgorithmSpecificParameters(@Nullable AlgorithmParameters params)
- throws InvalidAlgorithmParameterException {
-
- if (params != null) {
- throw new InvalidAlgorithmParameterException(
- "Unexpected parameters: " + params + ". No parameters supported");
- }
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- return null;
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForBegin() {
- return 0;
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForFinish() {
- return (isEncrypting()) ? getModulusSizeBytes() : 0;
- }
- }
-
- /**
- * RSA cipher with OAEP encryption padding. Only SHA-1 based MGF1 is supported as MGF.
- */
- abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi {
-
- private static final String MGF_ALGORITGM_MGF1 = "MGF1";
-
- private int mKeymasterDigest = -1;
- private int mDigestOutputSizeBytes;
-
- OAEPWithMGF1Padding(int keymasterDigest) {
- super(KeymasterDefs.KM_PAD_RSA_OAEP);
- mKeymasterDigest = keymasterDigest;
- mDigestOutputSizeBytes =
- (KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8;
- }
-
- @Override
- protected final void initAlgorithmSpecificParameters() throws InvalidKeyException {}
-
- @Override
- protected final void initAlgorithmSpecificParameters(
- @Nullable AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException {
- if (params == null) {
- return;
- }
-
- if (!(params instanceof OAEPParameterSpec)) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported parameter spec: " + params
- + ". Only OAEPParameterSpec supported");
- }
- OAEPParameterSpec spec = (OAEPParameterSpec) params;
- if (!MGF_ALGORITGM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported MGF: " + spec.getMGFAlgorithm()
- + ". Only " + MGF_ALGORITGM_MGF1 + " supported");
- }
- String jcaDigest = spec.getDigestAlgorithm();
- int keymasterDigest;
- try {
- keymasterDigest = KeyProperties.Digest.toKeymaster(jcaDigest);
- } catch (IllegalArgumentException e) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported digest: " + jcaDigest, e);
- }
- switch (keymasterDigest) {
- case KeymasterDefs.KM_DIGEST_SHA1:
- case KeymasterDefs.KM_DIGEST_SHA_2_224:
- case KeymasterDefs.KM_DIGEST_SHA_2_256:
- case KeymasterDefs.KM_DIGEST_SHA_2_384:
- case KeymasterDefs.KM_DIGEST_SHA_2_512:
- // Permitted.
- break;
- default:
- throw new InvalidAlgorithmParameterException(
- "Unsupported digest: " + jcaDigest);
- }
- AlgorithmParameterSpec mgfParams = spec.getMGFParameters();
- if (mgfParams == null) {
- throw new InvalidAlgorithmParameterException("MGF parameters must be provided");
- }
- // Check whether MGF parameters match the OAEPParameterSpec
- if (!(mgfParams instanceof MGF1ParameterSpec)) {
- throw new InvalidAlgorithmParameterException("Unsupported MGF parameters"
- + ": " + mgfParams + ". Only MGF1ParameterSpec supported");
- }
- MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) mgfParams;
- String mgf1JcaDigest = mgfSpec.getDigestAlgorithm();
- if (!KeyProperties.DIGEST_SHA1.equalsIgnoreCase(mgf1JcaDigest)) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported MGF1 digest: " + mgf1JcaDigest
- + ". Only " + KeyProperties.DIGEST_SHA1 + " supported");
- }
- PSource pSource = spec.getPSource();
- if (!(pSource instanceof PSource.PSpecified)) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported source of encoding input P: " + pSource
- + ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported");
- }
- PSource.PSpecified pSourceSpecified = (PSource.PSpecified) pSource;
- byte[] pSourceValue = pSourceSpecified.getValue();
- if ((pSourceValue != null) && (pSourceValue.length > 0)) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported source of encoding input P: " + pSource
- + ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported");
- }
- mKeymasterDigest = keymasterDigest;
- mDigestOutputSizeBytes =
- (KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8;
- }
-
- @Override
- protected final void initAlgorithmSpecificParameters(@Nullable AlgorithmParameters params)
- throws InvalidAlgorithmParameterException {
- if (params == null) {
- return;
- }
-
- OAEPParameterSpec spec;
- try {
- spec = params.getParameterSpec(OAEPParameterSpec.class);
- } catch (InvalidParameterSpecException e) {
- throw new InvalidAlgorithmParameterException("OAEP parameters required"
- + ", but not found in parameters: " + params, e);
- }
- if (spec == null) {
- throw new InvalidAlgorithmParameterException("OAEP parameters required"
- + ", but not provided in parameters: " + params);
- }
- initAlgorithmSpecificParameters(spec);
- }
-
- @Override
- protected final AlgorithmParameters engineGetParameters() {
- OAEPParameterSpec spec =
- new OAEPParameterSpec(
- KeyProperties.Digest.fromKeymaster(mKeymasterDigest),
- MGF_ALGORITGM_MGF1,
- MGF1ParameterSpec.SHA1,
- PSource.PSpecified.DEFAULT);
- try {
- AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP");
- params.init(spec);
- return params;
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(
- "Failed to obtain OAEP AlgorithmParameters", e);
- } catch (InvalidParameterSpecException e) {
- throw new ProviderException(
- "Failed to initialize OAEP AlgorithmParameters with an IV",
- e);
- }
- }
-
- @Override
- protected final void addAlgorithmSpecificParametersToBegin(
- KeymasterArguments keymasterArgs) {
- super.addAlgorithmSpecificParametersToBegin(keymasterArgs);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- }
-
- @Override
- protected final void loadAlgorithmSpecificParametersFromBeginResult(
- @NonNull KeymasterArguments keymasterArgs) {
- super.loadAlgorithmSpecificParametersFromBeginResult(keymasterArgs);
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForBegin() {
- return 0;
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForFinish() {
- return (isEncrypting()) ? mDigestOutputSizeBytes : 0;
- }
- }
-
- public static class OAEPWithSHA1AndMGF1Padding extends OAEPWithMGF1Padding {
- public OAEPWithSHA1AndMGF1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA1);
- }
- }
-
- public static class OAEPWithSHA224AndMGF1Padding extends OAEPWithMGF1Padding {
- public OAEPWithSHA224AndMGF1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_224);
- }
- }
-
- public static class OAEPWithSHA256AndMGF1Padding extends OAEPWithMGF1Padding {
- public OAEPWithSHA256AndMGF1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_256);
- }
- }
-
- public static class OAEPWithSHA384AndMGF1Padding extends OAEPWithMGF1Padding {
- public OAEPWithSHA384AndMGF1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_384);
- }
- }
-
- public static class OAEPWithSHA512AndMGF1Padding extends OAEPWithMGF1Padding {
- public OAEPWithSHA512AndMGF1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_512);
- }
- }
-
- private final int mKeymasterPadding;
- private int mKeymasterPaddingOverride;
-
- private int mModulusSizeBytes = -1;
-
- AndroidKeyStoreRSACipherSpi(int keymasterPadding) {
- mKeymasterPadding = keymasterPadding;
- }
-
- @Override
- protected final void initKey(int opmode, Key key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("Unsupported key: null");
- }
- if (!KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(key.getAlgorithm())) {
- throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm()
- + ". Only " + KeyProperties.KEY_ALGORITHM_RSA + " supported");
- }
- AndroidKeyStoreKey keystoreKey;
- if (key instanceof AndroidKeyStorePrivateKey) {
- keystoreKey = (AndroidKeyStoreKey) key;
- } else if (key instanceof AndroidKeyStorePublicKey) {
- keystoreKey = (AndroidKeyStoreKey) key;
- } else {
- throw new InvalidKeyException("Unsupported key type: " + key);
- }
-
- if (keystoreKey instanceof PrivateKey) {
- // Private key
- switch (opmode) {
- case Cipher.DECRYPT_MODE:
- case Cipher.UNWRAP_MODE:
- // Permitted
- break;
- case Cipher.ENCRYPT_MODE:
- case Cipher.WRAP_MODE:
- if (!adjustConfigForEncryptingWithPrivateKey()) {
- throw new InvalidKeyException(
- "RSA private keys cannot be used with " + opmodeToString(opmode)
- + " and padding "
- + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding)
- + ". Only RSA public keys supported for this mode");
- }
- break;
- default:
- throw new InvalidKeyException(
- "RSA private keys cannot be used with opmode: " + opmode);
- }
- } else {
- // Public key
- switch (opmode) {
- case Cipher.ENCRYPT_MODE:
- case Cipher.WRAP_MODE:
- // Permitted
- break;
- case Cipher.DECRYPT_MODE:
- case Cipher.UNWRAP_MODE:
- throw new InvalidKeyException(
- "RSA public keys cannot be used with " + opmodeToString(opmode)
- + " and padding "
- + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding)
- + ". Only RSA private keys supported for this opmode.");
- // break;
- default:
- throw new InvalidKeyException(
- "RSA public keys cannot be used with " + opmodeToString(opmode));
- }
- }
-
- KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
- int errorCode = getKeyStore().getKeyCharacteristics(
- keystoreKey.getAlias(), null, null, keystoreKey.getUid(), keyCharacteristics);
- if (errorCode != KeyStore.NO_ERROR) {
- throw getKeyStore().getInvalidKeyException(
- keystoreKey.getAlias(), keystoreKey.getUid(), errorCode);
- }
- long keySizeBits = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
- if (keySizeBits == -1) {
- throw new InvalidKeyException("Size of key not known");
- } else if (keySizeBits > Integer.MAX_VALUE) {
- throw new InvalidKeyException("Key too large: " + keySizeBits + " bits");
- }
- mModulusSizeBytes = (int) ((keySizeBits + 7) / 8);
-
- setKey(keystoreKey);
- }
-
- /**
- * Adjusts the configuration of this cipher for encrypting using the private key.
- *
- * <p>The default implementation does nothing and refuses to adjust the configuration.
- *
- * @return {@code true} if the configuration has been adjusted, {@code false} if encrypting
- * using private key is not permitted for this cipher.
- */
- protected boolean adjustConfigForEncryptingWithPrivateKey() {
- return false;
- }
-
- @Override
- protected final void resetAll() {
- mModulusSizeBytes = -1;
- mKeymasterPaddingOverride = -1;
- super.resetAll();
- }
-
- @Override
- protected final void resetWhilePreservingInitState() {
- super.resetWhilePreservingInitState();
- }
-
- @Override
- protected void addAlgorithmSpecificParametersToBegin(
- @NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- int keymasterPadding = getKeymasterPaddingOverride();
- if (keymasterPadding == -1) {
- keymasterPadding = mKeymasterPadding;
- }
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, keymasterPadding);
- int purposeOverride = getKeymasterPurposeOverride();
- if ((purposeOverride != -1)
- && ((purposeOverride == KeymasterDefs.KM_PURPOSE_SIGN)
- || (purposeOverride == KeymasterDefs.KM_PURPOSE_VERIFY))) {
- // Keymaster sign/verify requires digest to be specified. For raw sign/verify it's NONE.
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_NONE);
- }
- }
-
- @Override
- protected void loadAlgorithmSpecificParametersFromBeginResult(
- @NonNull KeymasterArguments keymasterArgs) {
- }
-
- @Override
- protected final int engineGetBlockSize() {
- // Not a block cipher, according to the RI
- return 0;
- }
-
- @Override
- protected final byte[] engineGetIV() {
- // IV never used
- return null;
- }
-
- @Override
- protected final int engineGetOutputSize(int inputLen) {
- return getModulusSizeBytes();
- }
-
- protected final int getModulusSizeBytes() {
- if (mModulusSizeBytes == -1) {
- throw new IllegalStateException("Not initialized");
- }
- return mModulusSizeBytes;
- }
-
- /**
- * Overrides the default padding of the crypto operation.
- */
- protected final void setKeymasterPaddingOverride(int keymasterPadding) {
- mKeymasterPaddingOverride = keymasterPadding;
- }
-
- protected final int getKeymasterPaddingOverride() {
- return mKeymasterPaddingOverride;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSAPrivateKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSAPrivateKey.java
deleted file mode 100644
index adb39222e076..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSAPrivateKey.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import java.math.BigInteger;
-import java.security.PrivateKey;
-import java.security.interfaces.RSAKey;
-
-/**
- * RSA private key (instance of {@link PrivateKey} and {@link RSAKey}) backed by keystore.
- *
- * @hide
- */
-public class AndroidKeyStoreRSAPrivateKey extends AndroidKeyStorePrivateKey implements RSAKey {
-
- private final BigInteger mModulus;
-
- public AndroidKeyStoreRSAPrivateKey(String alias, int uid, BigInteger modulus) {
- super(alias, uid, KeyProperties.KEY_ALGORITHM_RSA);
- mModulus = modulus;
- }
-
- @Override
- public BigInteger getModulus() {
- return mModulus;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSAPublicKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSAPublicKey.java
deleted file mode 100644
index d85aaceb98e3..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSAPublicKey.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import java.math.BigInteger;
-import java.security.interfaces.RSAPublicKey;
-
-/**
- * {@link RSAPublicKey} backed by Android Keystore.
- *
- * @hide
- */
-public class AndroidKeyStoreRSAPublicKey extends AndroidKeyStorePublicKey implements RSAPublicKey {
- private final BigInteger mModulus;
- private final BigInteger mPublicExponent;
-
- public AndroidKeyStoreRSAPublicKey(String alias, int uid, byte[] x509EncodedForm, BigInteger modulus,
- BigInteger publicExponent) {
- super(alias, uid, KeyProperties.KEY_ALGORITHM_RSA, x509EncodedForm);
- mModulus = modulus;
- mPublicExponent = publicExponent;
- }
-
- public AndroidKeyStoreRSAPublicKey(String alias, int uid, RSAPublicKey info) {
- this(alias, uid, info.getEncoded(), info.getModulus(), info.getPublicExponent());
- if (!"X.509".equalsIgnoreCase(info.getFormat())) {
- throw new IllegalArgumentException(
- "Unsupported key export format: " + info.getFormat());
- }
- }
-
- @Override
- public BigInteger getModulus() {
- return mModulus;
- }
-
- @Override
- public BigInteger getPublicExponent() {
- return mPublicExponent;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java
deleted file mode 100644
index ecfc97ed7141..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.annotation.NonNull;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-
-import java.security.InvalidKeyException;
-import java.security.SignatureSpi;
-
-/**
- * Base class for {@link SignatureSpi} providing Android KeyStore backed RSA signatures.
- *
- * @hide
- */
-abstract class AndroidKeyStoreRSASignatureSpi extends AndroidKeyStoreSignatureSpiBase {
-
- abstract static class PKCS1Padding extends AndroidKeyStoreRSASignatureSpi {
- PKCS1Padding(int keymasterDigest) {
- super(keymasterDigest, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForSign() {
- // No entropy required for this deterministic signature scheme.
- return 0;
- }
- }
-
- public static final class NONEWithPKCS1Padding extends PKCS1Padding {
- public NONEWithPKCS1Padding() {
- super(KeymasterDefs.KM_DIGEST_NONE);
- }
- }
-
- public static final class MD5WithPKCS1Padding extends PKCS1Padding {
- public MD5WithPKCS1Padding() {
- super(KeymasterDefs.KM_DIGEST_MD5);
- }
- }
-
- public static final class SHA1WithPKCS1Padding extends PKCS1Padding {
- public SHA1WithPKCS1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA1);
- }
- }
-
- public static final class SHA224WithPKCS1Padding extends PKCS1Padding {
- public SHA224WithPKCS1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_224);
- }
- }
-
- public static final class SHA256WithPKCS1Padding extends PKCS1Padding {
- public SHA256WithPKCS1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_256);
- }
- }
-
- public static final class SHA384WithPKCS1Padding extends PKCS1Padding {
- public SHA384WithPKCS1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_384);
- }
- }
-
- public static final class SHA512WithPKCS1Padding extends PKCS1Padding {
- public SHA512WithPKCS1Padding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_512);
- }
- }
-
- abstract static class PSSPadding extends AndroidKeyStoreRSASignatureSpi {
- private static final int SALT_LENGTH_BYTES = 20;
-
- PSSPadding(int keymasterDigest) {
- super(keymasterDigest, KeymasterDefs.KM_PAD_RSA_PSS);
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForSign() {
- return SALT_LENGTH_BYTES;
- }
- }
-
- public static final class SHA1WithPSSPadding extends PSSPadding {
- public SHA1WithPSSPadding() {
- super(KeymasterDefs.KM_DIGEST_SHA1);
- }
- }
-
- public static final class SHA224WithPSSPadding extends PSSPadding {
- public SHA224WithPSSPadding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_224);
- }
- }
-
- public static final class SHA256WithPSSPadding extends PSSPadding {
- public SHA256WithPSSPadding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_256);
- }
- }
-
- public static final class SHA384WithPSSPadding extends PSSPadding {
- public SHA384WithPSSPadding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_384);
- }
- }
-
- public static final class SHA512WithPSSPadding extends PSSPadding {
- public SHA512WithPSSPadding() {
- super(KeymasterDefs.KM_DIGEST_SHA_2_512);
- }
- }
-
- private final int mKeymasterDigest;
- private final int mKeymasterPadding;
-
- AndroidKeyStoreRSASignatureSpi(int keymasterDigest, int keymasterPadding) {
- mKeymasterDigest = keymasterDigest;
- mKeymasterPadding = keymasterPadding;
- }
-
- @Override
- protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException {
- if (!KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(key.getAlgorithm())) {
- throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm()
- + ". Only" + KeyProperties.KEY_ALGORITHM_RSA + " supported");
- }
- super.initKey(key);
- }
-
- @Override
- protected final void resetAll() {
- super.resetAll();
- }
-
- @Override
- protected final void resetWhilePreservingInitState() {
- super.resetWhilePreservingInitState();
- }
-
- @Override
- protected final void addAlgorithmSpecificParametersToBegin(
- @NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
deleted file mode 100644
index d2678c71813c..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.security.Credentials;
-import android.security.GateKeeper;
-import android.security.KeyStore;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterDefs;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.ProviderException;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * {@link SecretKeyFactorySpi} backed by Android Keystore.
- *
- * @hide
- */
-public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
-
- private final KeyStore mKeyStore = KeyStore.getInstance();
-
- @Override
- protected KeySpec engineGetKeySpec(SecretKey key,
- @SuppressWarnings("rawtypes") Class keySpecClass) throws InvalidKeySpecException {
- if (keySpecClass == null) {
- throw new InvalidKeySpecException("keySpecClass == null");
- }
- if (!(key instanceof AndroidKeyStoreSecretKey)) {
- throw new InvalidKeySpecException("Only Android KeyStore secret keys supported: " +
- ((key != null) ? key.getClass().getName() : "null"));
- }
- if (SecretKeySpec.class.isAssignableFrom(keySpecClass)) {
- throw new InvalidKeySpecException(
- "Key material export of Android KeyStore keys is not supported");
- }
- if (!KeyInfo.class.equals(keySpecClass)) {
- throw new InvalidKeySpecException("Unsupported key spec: " + keySpecClass.getName());
- }
- AndroidKeyStoreKey keystoreKey = (AndroidKeyStoreKey) key;
- String keyAliasInKeystore = keystoreKey.getAlias();
- String entryAlias;
- if (keyAliasInKeystore.startsWith(Credentials.USER_PRIVATE_KEY)) {
- entryAlias = keyAliasInKeystore.substring(Credentials.USER_PRIVATE_KEY.length());
- } else if (keyAliasInKeystore.startsWith(Credentials.USER_SECRET_KEY)){
- // key has legacy prefix
- entryAlias = keyAliasInKeystore.substring(Credentials.USER_SECRET_KEY.length());
- } else {
- throw new InvalidKeySpecException("Invalid key alias: " + keyAliasInKeystore);
- }
-
- return getKeyInfo(mKeyStore, entryAlias, keyAliasInKeystore, keystoreKey.getUid());
- }
-
- static KeyInfo getKeyInfo(KeyStore keyStore, String entryAlias, String keyAliasInKeystore,
- int keyUid) {
- KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
- int errorCode = keyStore.getKeyCharacteristics(
- keyAliasInKeystore, null, null, keyUid, keyCharacteristics);
- if (errorCode != KeyStore.NO_ERROR) {
- throw new ProviderException("Failed to obtain information about key."
- + " Keystore error: " + errorCode);
- }
-
- boolean insideSecureHardware;
- @KeyProperties.OriginEnum int origin;
- int keySize;
- @KeyProperties.PurposeEnum int purposes;
- String[] encryptionPaddings;
- String[] signaturePaddings;
- @KeyProperties.DigestEnum String[] digests;
- @KeyProperties.BlockModeEnum String[] blockModes;
- int keymasterSwEnforcedUserAuthenticators;
- int keymasterHwEnforcedUserAuthenticators;
- List<BigInteger> keymasterSecureUserIds;
- try {
- if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
- insideSecureHardware = true;
- origin = KeyProperties.Origin.fromKeymaster(
- keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
- } else if (keyCharacteristics.swEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
- insideSecureHardware = false;
- origin = KeyProperties.Origin.fromKeymaster(
- keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
- } else {
- throw new ProviderException("Key origin not available");
- }
- long keySizeUnsigned =
- keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
- if (keySizeUnsigned == -1) {
- throw new ProviderException("Key size not available");
- } else if (keySizeUnsigned > Integer.MAX_VALUE) {
- throw new ProviderException("Key too large: " + keySizeUnsigned + " bits");
- }
- keySize = (int) keySizeUnsigned;
- purposes = KeyProperties.Purpose.allFromKeymaster(
- keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PURPOSE));
-
- List<String> encryptionPaddingsList = new ArrayList<String>();
- List<String> signaturePaddingsList = new ArrayList<String>();
- // Keymaster stores both types of paddings in the same array -- we split it into two.
- for (int keymasterPadding : keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PADDING)) {
- try {
- @KeyProperties.EncryptionPaddingEnum String jcaPadding =
- KeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
- encryptionPaddingsList.add(jcaPadding);
- } catch (IllegalArgumentException e) {
- try {
- @KeyProperties.SignaturePaddingEnum String padding =
- KeyProperties.SignaturePadding.fromKeymaster(keymasterPadding);
- signaturePaddingsList.add(padding);
- } catch (IllegalArgumentException e2) {
- throw new ProviderException(
- "Unsupported encryption padding: " + keymasterPadding);
- }
- }
-
- }
- encryptionPaddings =
- encryptionPaddingsList.toArray(new String[encryptionPaddingsList.size()]);
- signaturePaddings =
- signaturePaddingsList.toArray(new String[signaturePaddingsList.size()]);
-
- digests = KeyProperties.Digest.allFromKeymaster(
- keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST));
- blockModes = KeyProperties.BlockMode.allFromKeymaster(
- keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_BLOCK_MODE));
- keymasterSwEnforcedUserAuthenticators =
- keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
- keymasterHwEnforcedUserAuthenticators =
- keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
- keymasterSecureUserIds =
- keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
- } catch (IllegalArgumentException e) {
- throw new ProviderException("Unsupported key characteristic", e);
- }
-
- Date keyValidityStart = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME);
- Date keyValidityForOriginationEnd =
- keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME);
- Date keyValidityForConsumptionEnd =
- keyCharacteristics.getDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME);
- boolean userAuthenticationRequired =
- !keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
- long userAuthenticationValidityDurationSeconds =
- keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, 0);
- if (userAuthenticationValidityDurationSeconds > Integer.MAX_VALUE) {
- throw new ProviderException("User authentication timeout validity too long: "
- + userAuthenticationValidityDurationSeconds + " seconds");
- }
- boolean userAuthenticationRequirementEnforcedBySecureHardware = (userAuthenticationRequired)
- && (keymasterHwEnforcedUserAuthenticators != 0)
- && (keymasterSwEnforcedUserAuthenticators == 0);
- boolean userAuthenticationValidWhileOnBody =
- keyCharacteristics.hwEnforced.getBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
- boolean trustedUserPresenceRequired =
- keyCharacteristics.hwEnforced.getBoolean(
- KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
-
- boolean invalidatedByBiometricEnrollment = false;
- if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_BIOMETRIC
- || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_BIOMETRIC) {
- // Fingerprint-only key; will be invalidated if the root SID isn't in the SID list.
- invalidatedByBiometricEnrollment = keymasterSecureUserIds != null
- && !keymasterSecureUserIds.isEmpty()
- && !keymasterSecureUserIds.contains(getGateKeeperSecureUserId());
- }
-
- boolean userConfirmationRequired = keyCharacteristics.hwEnforced.getBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
-
- return new KeyInfo(entryAlias,
- insideSecureHardware,
- origin,
- keySize,
- keyValidityStart,
- keyValidityForOriginationEnd,
- keyValidityForConsumptionEnd,
- purposes,
- encryptionPaddings,
- signaturePaddings,
- digests,
- blockModes,
- userAuthenticationRequired,
- (int) userAuthenticationValidityDurationSeconds,
- keymasterHwEnforcedUserAuthenticators,
- userAuthenticationRequirementEnforcedBySecureHardware,
- userAuthenticationValidWhileOnBody,
- trustedUserPresenceRequired,
- invalidatedByBiometricEnrollment,
- userConfirmationRequired,
- // Keystore 1.0 does not tell us the exact security level of the key
- // so we report an unknown but secure security level.
- insideSecureHardware ? KeyProperties.SECURITY_LEVEL_UNKNOWN_SECURE
- : KeyProperties.SECURITY_LEVEL_SOFTWARE,
- KeyProperties.UNRESTRICTED_USAGE_COUNT);
- }
-
- private static BigInteger getGateKeeperSecureUserId() throws ProviderException {
- try {
- return BigInteger.valueOf(GateKeeper.getSecureUserId());
- } catch (IllegalStateException e) {
- throw new ProviderException("Failed to get GateKeeper secure user ID", e);
- }
- }
-
- @Override
- protected SecretKey engineGenerateSecret(KeySpec keySpec) throws InvalidKeySpecException {
- throw new InvalidKeySpecException(
- "To generate secret key in Android Keystore, use KeyGenerator initialized with "
- + KeyGenParameterSpec.class.getName());
- }
-
- @Override
- protected SecretKey engineTranslateKey(SecretKey key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- } else if (!(key instanceof AndroidKeyStoreSecretKey)) {
- throw new InvalidKeyException(
- "To import a secret key into Android Keystore, use KeyStore.setEntry");
- }
-
- return key;
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSignatureSpiBase.java b/keystore/java/android/security/keystore/AndroidKeyStoreSignatureSpiBase.java
deleted file mode 100644
index da47b6bde69a..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSignatureSpiBase.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.annotation.CallSuper;
-import android.annotation.NonNull;
-import android.os.IBinder;
-import android.security.KeyStore;
-import android.security.KeyStoreException;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keymaster.OperationResult;
-
-import libcore.util.EmptyArray;
-
-import java.nio.ByteBuffer;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.PrivateKey;
-import java.security.ProviderException;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.SignatureException;
-import java.security.SignatureSpi;
-
-/**
- * Base class for {@link SignatureSpi} implementations of Android KeyStore backed ciphers.
- *
- * @hide
- */
-abstract class AndroidKeyStoreSignatureSpiBase extends SignatureSpi
- implements KeyStoreCryptoOperation {
- private final KeyStore mKeyStore;
-
- // Fields below are populated by SignatureSpi.engineInitSign/engineInitVerify and KeyStore.begin
- // and should be preserved after SignatureSpi.engineSign/engineVerify finishes.
- private boolean mSigning;
- private AndroidKeyStoreKey mKey;
-
- /**
- * Token referencing this operation inside keystore service. It is initialized by
- * {@code engineInitSign}/{@code engineInitVerify} and is invalidated when
- * {@code engineSign}/{@code engineVerify} succeeds and on some error conditions in between.
- */
- private IBinder mOperationToken;
- private long mOperationHandle;
- private KeyStoreCryptoOperationStreamer mMessageStreamer;
-
- /**
- * Encountered exception which could not be immediately thrown because it was encountered inside
- * a method that does not throw checked exception. This exception will be thrown from
- * {@code engineSign} or {@code engineVerify}. Once such an exception is encountered,
- * {@code engineUpdate} starts ignoring input data.
- */
- private Exception mCachedException;
-
- AndroidKeyStoreSignatureSpiBase() {
- mKeyStore = KeyStore.getInstance();
- }
-
- @Override
- protected final void engineInitSign(PrivateKey key) throws InvalidKeyException {
- engineInitSign(key, null);
- }
-
- @Override
- protected final void engineInitSign(PrivateKey privateKey, SecureRandom random)
- throws InvalidKeyException {
- resetAll();
-
- boolean success = false;
- try {
- if (privateKey == null) {
- throw new InvalidKeyException("Unsupported key: null");
- }
- AndroidKeyStoreKey keystoreKey;
- if (privateKey instanceof AndroidKeyStorePrivateKey) {
- keystoreKey = (AndroidKeyStoreKey) privateKey;
- } else {
- throw new InvalidKeyException("Unsupported private key type: " + privateKey);
- }
- mSigning = true;
- initKey(keystoreKey);
- appRandom = random;
- ensureKeystoreOperationInitialized();
- success = true;
- } finally {
- if (!success) {
- resetAll();
- }
- }
- }
-
- @Override
- protected final void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
- resetAll();
-
- boolean success = false;
- try {
- if (publicKey == null) {
- throw new InvalidKeyException("Unsupported key: null");
- }
- AndroidKeyStoreKey keystoreKey;
- if (publicKey instanceof AndroidKeyStorePublicKey) {
- keystoreKey = (AndroidKeyStorePublicKey) publicKey;
- } else {
- throw new InvalidKeyException("Unsupported public key type: " + publicKey);
- }
- mSigning = false;
- initKey(keystoreKey);
- appRandom = null;
- ensureKeystoreOperationInitialized();
- success = true;
- } finally {
- if (!success) {
- resetAll();
- }
- }
- }
-
- /**
- * Configures this signature instance to use the provided key.
- *
- * @throws InvalidKeyException if the {@code key} is not suitable.
- */
- @CallSuper
- protected void initKey(AndroidKeyStoreKey key) throws InvalidKeyException {
- mKey = key;
- }
-
- /**
- * Resets this cipher to its pristine pre-init state. This must be equivalent to obtaining a new
- * cipher instance.
- *
- * <p>Subclasses storing additional state should override this method, reset the additional
- * state, and then chain to superclass.
- */
- @CallSuper
- protected void resetAll() {
- IBinder operationToken = mOperationToken;
- if (operationToken != null) {
- mOperationToken = null;
- mKeyStore.abort(operationToken);
- }
- mSigning = false;
- mKey = null;
- appRandom = null;
- mOperationToken = null;
- mOperationHandle = 0;
- mMessageStreamer = null;
- mCachedException = null;
- }
-
- /**
- * Resets this cipher while preserving the initialized state. This must be equivalent to
- * rolling back the cipher's state to just after the most recent {@code engineInit} completed
- * successfully.
- *
- * <p>Subclasses storing additional post-init state should override this method, reset the
- * additional state, and then chain to superclass.
- */
- @CallSuper
- protected void resetWhilePreservingInitState() {
- IBinder operationToken = mOperationToken;
- if (operationToken != null) {
- mOperationToken = null;
- mKeyStore.abort(operationToken);
- }
- mOperationHandle = 0;
- mMessageStreamer = null;
- mCachedException = null;
- }
-
- private void ensureKeystoreOperationInitialized() throws InvalidKeyException {
- if (mMessageStreamer != null) {
- return;
- }
- if (mCachedException != null) {
- return;
- }
- if (mKey == null) {
- throw new IllegalStateException("Not initialized");
- }
-
- KeymasterArguments keymasterInputArgs = new KeymasterArguments();
- addAlgorithmSpecificParametersToBegin(keymasterInputArgs);
-
- OperationResult opResult = mKeyStore.begin(
- mKey.getAlias(),
- mSigning ? KeymasterDefs.KM_PURPOSE_SIGN : KeymasterDefs.KM_PURPOSE_VERIFY,
- true, // permit aborting this operation if keystore runs out of resources
- keymasterInputArgs,
- null, // no additional entropy for begin -- only finish might need some
- mKey.getUid());
- if (opResult == null) {
- throw new KeyStoreConnectException();
- }
-
- // Store operation token and handle regardless of the error code returned by KeyStore to
- // ensure that the operation gets aborted immediately if the code below throws an exception.
- mOperationToken = opResult.token;
- mOperationHandle = opResult.operationHandle;
-
- // If necessary, throw an exception due to KeyStore operation having failed.
- InvalidKeyException e = KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(
- mKeyStore, mKey, opResult.resultCode);
- if (e != null) {
- throw e;
- }
-
- if (mOperationToken == null) {
- throw new ProviderException("Keystore returned null operation token");
- }
- if (mOperationHandle == 0) {
- throw new ProviderException("Keystore returned invalid operation handle");
- }
-
- mMessageStreamer = createMainDataStreamer(mKeyStore, opResult.token);
- }
-
- /**
- * Creates a streamer which sends the message to be signed/verified into the provided KeyStore
- *
- * <p>This implementation returns a working streamer.
- */
- @NonNull
- protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
- KeyStore keyStore, IBinder operationToken) {
- return new KeyStoreCryptoOperationChunkedStreamer(
- new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
- keyStore, operationToken));
- }
-
- @Override
- public final long getOperationHandle() {
- return mOperationHandle;
- }
-
- @Override
- protected final void engineUpdate(byte[] b, int off, int len) throws SignatureException {
- if (mCachedException != null) {
- throw new SignatureException(mCachedException);
- }
-
- try {
- ensureKeystoreOperationInitialized();
- } catch (InvalidKeyException e) {
- throw new SignatureException(e);
- }
-
- if (len == 0) {
- return;
- }
-
- byte[] output;
- try {
- output = mMessageStreamer.update(b, off, len);
- } catch (KeyStoreException e) {
- throw new SignatureException(e);
- }
-
- if (output.length != 0) {
- throw new ProviderException(
- "Update operation unexpectedly produced output: " + output.length + " bytes");
- }
- }
-
- @Override
- protected final void engineUpdate(byte b) throws SignatureException {
- engineUpdate(new byte[] {b}, 0, 1);
- }
-
- @Override
- protected final void engineUpdate(ByteBuffer input) {
- byte[] b;
- int off;
- int len = input.remaining();
- if (input.hasArray()) {
- b = input.array();
- off = input.arrayOffset() + input.position();
- input.position(input.limit());
- } else {
- b = new byte[len];
- off = 0;
- input.get(b);
- }
-
- try {
- engineUpdate(b, off, len);
- } catch (SignatureException e) {
- mCachedException = e;
- }
- }
-
- @Override
- protected final int engineSign(byte[] out, int outOffset, int outLen)
- throws SignatureException {
- return super.engineSign(out, outOffset, outLen);
- }
-
- @Override
- protected final byte[] engineSign() throws SignatureException {
- if (mCachedException != null) {
- throw new SignatureException(mCachedException);
- }
-
- byte[] signature;
- try {
- ensureKeystoreOperationInitialized();
-
- byte[] additionalEntropy =
- KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
- appRandom, getAdditionalEntropyAmountForSign());
- signature = mMessageStreamer.doFinal(
- EmptyArray.BYTE, 0, 0,
- null, // no signature provided -- it'll be generated by this invocation
- additionalEntropy);
- } catch (InvalidKeyException | KeyStoreException e) {
- throw new SignatureException(e);
- }
-
- resetWhilePreservingInitState();
- return signature;
- }
-
- @Override
- protected final boolean engineVerify(byte[] signature) throws SignatureException {
- if (mCachedException != null) {
- throw new SignatureException(mCachedException);
- }
-
- try {
- ensureKeystoreOperationInitialized();
- } catch (InvalidKeyException e) {
- throw new SignatureException(e);
- }
-
- boolean verified;
- try {
- byte[] output = mMessageStreamer.doFinal(
- EmptyArray.BYTE, 0, 0,
- signature,
- null // no additional entropy needed -- verification is deterministic
- );
- if (output.length != 0) {
- throw new ProviderException(
- "Signature verification unexpected produced output: " + output.length
- + " bytes");
- }
- verified = true;
- } catch (KeyStoreException e) {
- switch (e.getErrorCode()) {
- case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
- verified = false;
- break;
- default:
- throw new SignatureException(e);
- }
- }
-
- resetWhilePreservingInitState();
- return verified;
- }
-
- @Override
- protected final boolean engineVerify(byte[] sigBytes, int offset, int len)
- throws SignatureException {
- return engineVerify(ArrayUtils.subarray(sigBytes, offset, len));
- }
-
- @Deprecated
- @Override
- protected final Object engineGetParameter(String param) throws InvalidParameterException {
- throw new InvalidParameterException();
- }
-
- @Deprecated
- @Override
- protected final void engineSetParameter(String param, Object value)
- throws InvalidParameterException {
- throw new InvalidParameterException();
- }
-
- protected final KeyStore getKeyStore() {
- return mKeyStore;
- }
-
- /**
- * Returns {@code true} if this signature is initialized for signing, {@code false} if this
- * signature is initialized for verification.
- */
- protected final boolean isSigning() {
- return mSigning;
- }
-
- // The methods below need to be implemented by subclasses.
-
- /**
- * Returns the amount of additional entropy (in bytes) to be provided to the KeyStore's
- * {@code finish} operation when generating a signature.
- *
- * <p>This value should match (or exceed) the amount of Shannon entropy of the produced
- * signature assuming the key and the message are known. For example, for ECDSA signature this
- * should be the size of {@code R}, whereas for the RSA signature with PKCS#1 padding this
- * should be {@code 0}.
- */
- protected abstract int getAdditionalEntropyAmountForSign();
-
- /**
- * Invoked to add algorithm-specific parameters for the KeyStore's {@code begin} operation.
- *
- * @param keymasterArgs keystore/keymaster arguments to be populated with algorithm-specific
- * parameters.
- */
- protected abstract void addAlgorithmSpecificParametersToBegin(
- @NonNull KeymasterArguments keymasterArgs);
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
deleted file mode 100644
index 51c42520ccc9..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ /dev/null
@@ -1,1112 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.security.Credentials;
-import android.security.GateKeeper;
-import android.security.KeyStore;
-import android.security.KeyStoreParameter;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keystore.KeyPermanentlyInvalidatedException;
-import android.security.keystore.KeyProperties;
-import android.security.keystore.KeyProtection;
-import android.security.keystore.SecureKeyImportUnavailableException;
-import android.security.keystore.WrappedKeyEntry;
-import android.util.Log;
-
-import libcore.util.EmptyArray;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.Key;
-import java.security.KeyStore.Entry;
-import java.security.KeyStore.LoadStoreParameter;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.KeyStore.ProtectionParameter;
-import java.security.KeyStore.SecretKeyEntry;
-import java.security.KeyStoreException;
-import java.security.KeyStoreSpi;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.ProviderException;
-import java.security.PublicKey;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.crypto.SecretKey;
-
-/**
- * A java.security.KeyStore interface for the Android KeyStore. An instance of
- * it can be created via the {@link java.security.KeyStore#getInstance(String)
- * KeyStore.getInstance("AndroidKeyStore")} interface. This returns a
- * java.security.KeyStore backed by this "AndroidKeyStore" implementation.
- * <p>
- * This is built on top of Android's keystore daemon. The convention of alias
- * use is:
- * <p>
- * PrivateKeyEntry will have a Credentials.USER_PRIVATE_KEY as the private key,
- * Credentials.USER_CERTIFICATE as the first certificate in the chain (the one
- * that corresponds to the private key), and then a Credentials.CA_CERTIFICATE
- * entry which will have the rest of the chain concatenated in BER format.
- * <p>
- * TrustedCertificateEntry will just have a Credentials.CA_CERTIFICATE entry
- * with a single certificate.
- *
- * @hide
- */
-public class AndroidKeyStoreSpi extends KeyStoreSpi {
- public static final String NAME = "AndroidKeyStore";
-
- private KeyStore mKeyStore;
- private int mUid = KeyStore.UID_SELF;
-
- @Override
- public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException,
- UnrecoverableKeyException {
- String userKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
- AndroidKeyStoreKey key;
- if (!mKeyStore.contains(userKeyAlias, mUid)) {
- // try legacy prefix for backward compatibility
- userKeyAlias = Credentials.USER_SECRET_KEY + alias;
- if (!mKeyStore.contains(userKeyAlias, mUid)) return null;
- }
- try {
- key = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(mKeyStore,
- userKeyAlias,
- mUid);
- } catch (KeyPermanentlyInvalidatedException e) {
- throw new UnrecoverableKeyException(e.getMessage());
- }
- return key;
- }
-
- @Override
- public Certificate[] engineGetCertificateChain(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
-
- final X509Certificate leaf = (X509Certificate) engineGetCertificate(alias);
- if (leaf == null) {
- return null;
- }
-
- final Certificate[] caList;
-
- // Suppress the key not found warning for this call. It seems that this error is exclusively
- // being thrown when there is a self signed certificate chain, so when the keystore service
- // attempts to query for the CA details, it obviously fails to find them and returns a
- // key not found exception. This is WAI, and throwing a stack trace here can be very
- // misleading since the trace is not clear.
- final byte[] caBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias,
- mUid,
- true /* suppressKeyNotFoundWarning */);
- if (caBytes != null) {
- final Collection<X509Certificate> caChain = toCertificates(caBytes);
-
- caList = new Certificate[caChain.size() + 1];
-
- final Iterator<X509Certificate> it = caChain.iterator();
- int i = 1;
- while (it.hasNext()) {
- caList[i++] = it.next();
- }
- } else {
- caList = new Certificate[1];
- }
-
- caList[0] = leaf;
-
- return caList;
- }
-
- @Override
- public Certificate engineGetCertificate(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
-
- byte[] encodedCert = mKeyStore.get(Credentials.USER_CERTIFICATE + alias, mUid);
- if (encodedCert != null) {
- return getCertificateForPrivateKeyEntry(alias, encodedCert);
- }
-
- encodedCert = mKeyStore.get(Credentials.CA_CERTIFICATE + alias, mUid);
- if (encodedCert != null) {
- return getCertificateForTrustedCertificateEntry(encodedCert);
- }
-
- // This entry/alias does not contain a certificate.
- return null;
- }
-
- private Certificate getCertificateForTrustedCertificateEntry(byte[] encodedCert) {
- // For this certificate there shouldn't be a private key in this KeyStore entry. Thus,
- // there's no need to wrap this certificate as opposed to the certificate associated with
- // a private key entry.
- return toCertificate(encodedCert);
- }
-
- private Certificate getCertificateForPrivateKeyEntry(String alias, byte[] encodedCert) {
- // All crypto algorithms offered by Android Keystore for its private keys must also
- // be offered for the corresponding public keys stored in the Android Keystore. The
- // complication is that the underlying keystore service operates only on full key pairs,
- // rather than just public keys or private keys. As a result, Android Keystore-backed
- // crypto can only be offered for public keys for which keystore contains the
- // corresponding private key. This is not the case for certificate-only entries (e.g.,
- // trusted certificates).
- //
- // getCertificate().getPublicKey() is the only way to obtain the public key
- // corresponding to the private key stored in the KeyStore. Thus, we need to make sure
- // that the returned public key points to the underlying key pair / private key
- // when available.
-
- X509Certificate cert = toCertificate(encodedCert);
- if (cert == null) {
- // Failed to parse the certificate.
- return null;
- }
-
- String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
- if (mKeyStore.contains(privateKeyAlias, mUid)) {
- // As expected, keystore contains the private key corresponding to this public key. Wrap
- // the certificate so that its getPublicKey method returns an Android Keystore
- // PublicKey. This key will delegate crypto operations involving this public key to
- // Android Keystore when higher-priority providers do not offer these crypto
- // operations for this key.
- return wrapIntoKeyStoreCertificate(privateKeyAlias, mUid, cert);
- } else {
- // This KeyStore entry/alias is supposed to contain the private key corresponding to
- // the public key in this certificate, but it does not for some reason. It's probably a
- // bug. Let other providers handle crypto operations involving the public key returned
- // by this certificate's getPublicKey.
- return cert;
- }
- }
-
- /**
- * Wraps the provided cerificate into {@link KeyStoreX509Certificate} so that the public key
- * returned by the certificate contains information about the alias of the private key in
- * keystore. This is needed so that Android Keystore crypto operations using public keys can
- * find out which key alias to use. These operations cannot work without an alias.
- */
- private static KeyStoreX509Certificate wrapIntoKeyStoreCertificate(
- String privateKeyAlias, int uid, X509Certificate certificate) {
- return (certificate != null)
- ? new KeyStoreX509Certificate(privateKeyAlias, uid, certificate) : null;
- }
-
- private static X509Certificate toCertificate(byte[] bytes) {
- try {
- final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- return (X509Certificate) certFactory.generateCertificate(
- new ByteArrayInputStream(bytes));
- } catch (CertificateException e) {
- Log.w(NAME, "Couldn't parse certificate in keystore", e);
- return null;
- }
- }
-
- @SuppressWarnings("unchecked")
- private static Collection<X509Certificate> toCertificates(byte[] bytes) {
- try {
- final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- return (Collection<X509Certificate>) certFactory.generateCertificates(
- new ByteArrayInputStream(bytes));
- } catch (CertificateException e) {
- Log.w(NAME, "Couldn't parse certificates in keystore", e);
- return new ArrayList<X509Certificate>();
- }
- }
-
- private Date getModificationDate(String alias) {
- final long epochMillis = mKeyStore.getmtime(alias, mUid);
- if (epochMillis == -1L) {
- return null;
- }
-
- return new Date(epochMillis);
- }
-
- @Override
- public Date engineGetCreationDate(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
-
- Date d = getModificationDate(Credentials.USER_PRIVATE_KEY + alias);
- if (d != null) {
- return d;
- }
-
- d = getModificationDate(Credentials.USER_SECRET_KEY + alias);
- if (d != null) {
- return d;
- }
-
- d = getModificationDate(Credentials.USER_CERTIFICATE + alias);
- if (d != null) {
- return d;
- }
-
- return getModificationDate(Credentials.CA_CERTIFICATE + alias);
- }
-
- @Override
- public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
- throws KeyStoreException {
- if ((password != null) && (password.length > 0)) {
- throw new KeyStoreException("entries cannot be protected with passwords");
- }
-
- if (key instanceof PrivateKey) {
- setPrivateKeyEntry(alias, (PrivateKey) key, chain, null);
- } else if (key instanceof SecretKey) {
- setSecretKeyEntry(alias, (SecretKey) key, null);
- } else {
- throw new KeyStoreException("Only PrivateKey and SecretKey are supported");
- }
- }
-
- private static KeyProtection getLegacyKeyProtectionParameter(PrivateKey key)
- throws KeyStoreException {
- String keyAlgorithm = key.getAlgorithm();
- KeyProtection.Builder specBuilder;
- if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
- specBuilder =
- new KeyProtection.Builder(
- KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY);
- // Authorized to be used with any digest (including no digest).
- // MD5 was never offered for Android Keystore for ECDSA.
- specBuilder.setDigests(
- KeyProperties.DIGEST_NONE,
- KeyProperties.DIGEST_SHA1,
- KeyProperties.DIGEST_SHA224,
- KeyProperties.DIGEST_SHA256,
- KeyProperties.DIGEST_SHA384,
- KeyProperties.DIGEST_SHA512);
- } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
- specBuilder =
- new KeyProtection.Builder(
- KeyProperties.PURPOSE_ENCRYPT
- | KeyProperties.PURPOSE_DECRYPT
- | KeyProperties.PURPOSE_SIGN
- | KeyProperties.PURPOSE_VERIFY);
- // Authorized to be used with any digest (including no digest).
- specBuilder.setDigests(
- KeyProperties.DIGEST_NONE,
- KeyProperties.DIGEST_MD5,
- KeyProperties.DIGEST_SHA1,
- KeyProperties.DIGEST_SHA224,
- KeyProperties.DIGEST_SHA256,
- KeyProperties.DIGEST_SHA384,
- KeyProperties.DIGEST_SHA512);
- // Authorized to be used with any encryption and signature padding
- // schemes (including no padding).
- specBuilder.setEncryptionPaddings(
- KeyProperties.ENCRYPTION_PADDING_NONE,
- KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
- KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
- specBuilder.setSignaturePaddings(
- KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
- KeyProperties.SIGNATURE_PADDING_RSA_PSS);
- // Disable randomized encryption requirement to support encryption
- // padding NONE above.
- specBuilder.setRandomizedEncryptionRequired(false);
- } else {
- throw new KeyStoreException("Unsupported key algorithm: " + keyAlgorithm);
- }
- specBuilder.setUserAuthenticationRequired(false);
-
- return specBuilder.build();
- }
-
- private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain,
- java.security.KeyStore.ProtectionParameter param) throws KeyStoreException {
- int flags = 0;
- KeyProtection spec;
- if (param == null) {
- spec = getLegacyKeyProtectionParameter(key);
- } else if (param instanceof KeyStoreParameter) {
- spec = getLegacyKeyProtectionParameter(key);
- KeyStoreParameter legacySpec = (KeyStoreParameter) param;
- if (legacySpec.isEncryptionRequired()) {
- flags = KeyStore.FLAG_ENCRYPTED;
- }
- } else if (param instanceof KeyProtection) {
- spec = (KeyProtection) param;
- if (spec.isCriticalToDeviceEncryption()) {
- flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
- }
-
- if (spec.isStrongBoxBacked()) {
- flags |= KeyStore.FLAG_STRONGBOX;
- }
- } else {
- throw new KeyStoreException(
- "Unsupported protection parameter class:" + param.getClass().getName()
- + ". Supported: " + KeyProtection.class.getName() + ", "
- + KeyStoreParameter.class.getName());
- }
-
- // Make sure the chain exists since this is a PrivateKey
- if ((chain == null) || (chain.length == 0)) {
- throw new KeyStoreException("Must supply at least one Certificate with PrivateKey");
- }
-
- // Do chain type checking.
- X509Certificate[] x509chain = new X509Certificate[chain.length];
- for (int i = 0; i < chain.length; i++) {
- if (!"X.509".equals(chain[i].getType())) {
- throw new KeyStoreException("Certificates must be in X.509 format: invalid cert #"
- + i);
- }
-
- if (!(chain[i] instanceof X509Certificate)) {
- throw new KeyStoreException("Certificates must be in X.509 format: invalid cert #"
- + i);
- }
-
- x509chain[i] = (X509Certificate) chain[i];
- }
-
- final byte[] userCertBytes;
- try {
- userCertBytes = x509chain[0].getEncoded();
- } catch (CertificateEncodingException e) {
- throw new KeyStoreException("Failed to encode certificate #0", e);
- }
-
- /*
- * If we have a chain, store it in the CA certificate slot for this
- * alias as concatenated DER-encoded certificates. These can be
- * deserialized by {@link CertificateFactory#generateCertificates}.
- */
- final byte[] chainBytes;
- if (chain.length > 1) {
- /*
- * The chain is passed in as {user_cert, ca_cert_1, ca_cert_2, ...}
- * so we only need the certificates starting at index 1.
- */
- final byte[][] certsBytes = new byte[x509chain.length - 1][];
- int totalCertLength = 0;
- for (int i = 0; i < certsBytes.length; i++) {
- try {
- certsBytes[i] = x509chain[i + 1].getEncoded();
- totalCertLength += certsBytes[i].length;
- } catch (CertificateEncodingException e) {
- throw new KeyStoreException("Failed to encode certificate #" + i, e);
- }
- }
-
- /*
- * Serialize this into one byte array so we can later call
- * CertificateFactory#generateCertificates to recover them.
- */
- chainBytes = new byte[totalCertLength];
- int outputOffset = 0;
- for (int i = 0; i < certsBytes.length; i++) {
- final int certLength = certsBytes[i].length;
- System.arraycopy(certsBytes[i], 0, chainBytes, outputOffset, certLength);
- outputOffset += certLength;
- certsBytes[i] = null;
- }
- } else {
- chainBytes = null;
- }
-
- final String pkeyAlias;
- if (key instanceof AndroidKeyStorePrivateKey) {
- pkeyAlias = ((AndroidKeyStoreKey) key).getAlias();
- } else {
- pkeyAlias = null;
- }
-
- byte[] pkcs8EncodedPrivateKeyBytes;
- KeymasterArguments importArgs;
- final boolean shouldReplacePrivateKey;
- if (pkeyAlias != null && pkeyAlias.startsWith(Credentials.USER_PRIVATE_KEY)) {
- final String keySubalias = pkeyAlias.substring(Credentials.USER_PRIVATE_KEY.length());
- if (!alias.equals(keySubalias)) {
- throw new KeyStoreException("Can only replace keys with same alias: " + alias
- + " != " + keySubalias);
- }
- shouldReplacePrivateKey = false;
- importArgs = null;
- pkcs8EncodedPrivateKeyBytes = null;
- } else {
- shouldReplacePrivateKey = true;
- // Make sure the PrivateKey format is the one we support.
- final String keyFormat = key.getFormat();
- if ((keyFormat == null) || (!"PKCS#8".equals(keyFormat))) {
- throw new KeyStoreException(
- "Unsupported private key export format: " + keyFormat
- + ". Only private keys which export their key material in PKCS#8 format are"
- + " supported.");
- }
-
- // Make sure we can actually encode the key.
- pkcs8EncodedPrivateKeyBytes = key.getEncoded();
- if (pkcs8EncodedPrivateKeyBytes == null) {
- throw new KeyStoreException("Private key did not export any key material");
- }
-
- importArgs = new KeymasterArguments();
- try {
- importArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM,
- KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(
- key.getAlgorithm()));
- @KeyProperties.PurposeEnum int purposes = spec.getPurposes();
- importArgs.addEnums(KeymasterDefs.KM_TAG_PURPOSE,
- KeyProperties.Purpose.allToKeymaster(purposes));
- if (spec.isDigestsSpecified()) {
- importArgs.addEnums(KeymasterDefs.KM_TAG_DIGEST,
- KeyProperties.Digest.allToKeymaster(spec.getDigests()));
- }
-
- importArgs.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE,
- KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes()));
- int[] keymasterEncryptionPaddings =
- KeyProperties.EncryptionPadding.allToKeymaster(
- spec.getEncryptionPaddings());
- if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0)
- && (spec.isRandomizedEncryptionRequired())) {
- for (int keymasterPadding : keymasterEncryptionPaddings) {
- if (!KeymasterUtils
- .isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto(
- keymasterPadding)) {
- throw new KeyStoreException(
- "Randomized encryption (IND-CPA) required but is violated by"
- + " encryption padding mode: "
- + KeyProperties.EncryptionPadding.fromKeymaster(
- keymasterPadding)
- + ". See KeyProtection documentation.");
- }
- }
- }
- importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
- importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING,
- KeyProperties.SignaturePadding.allToKeymaster(spec.getSignaturePaddings()));
- KeymasterUtils.addUserAuthArgs(importArgs, spec);
- importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
- spec.getKeyValidityStart());
- importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
- spec.getKeyValidityForOriginationEnd());
- importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
- spec.getKeyValidityForConsumptionEnd());
- } catch (IllegalArgumentException | IllegalStateException e) {
- throw new KeyStoreException(e);
- }
- }
-
-
- boolean success = false;
- try {
- // Store the private key, if necessary
- if (shouldReplacePrivateKey) {
- // Delete the stored private key and any related entries before importing the
- // provided key
- Credentials.deleteAllTypesForAlias(mKeyStore, alias, mUid);
- KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
- int errorCode = mKeyStore.importKey(
- Credentials.USER_PRIVATE_KEY + alias,
- importArgs,
- KeymasterDefs.KM_KEY_FORMAT_PKCS8,
- pkcs8EncodedPrivateKeyBytes,
- mUid,
- flags,
- resultingKeyCharacteristics);
- if (errorCode != KeyStore.NO_ERROR) {
- throw new KeyStoreException("Failed to store private key",
- KeyStore.getKeyStoreException(errorCode));
- }
- } else {
- // Keep the stored private key around -- delete all other entry types
- Credentials.deleteCertificateTypesForAlias(mKeyStore, alias, mUid);
- Credentials.deleteLegacyKeyForAlias(mKeyStore, alias, mUid);
- }
-
- // Store the leaf certificate
- int errorCode = mKeyStore.insert(Credentials.USER_CERTIFICATE + alias, userCertBytes,
- mUid, flags);
- if (errorCode != KeyStore.NO_ERROR) {
- throw new KeyStoreException("Failed to store certificate #0",
- KeyStore.getKeyStoreException(errorCode));
- }
-
- // Store the certificate chain
- errorCode = mKeyStore.insert(Credentials.CA_CERTIFICATE + alias, chainBytes,
- mUid, flags);
- if (errorCode != KeyStore.NO_ERROR) {
- throw new KeyStoreException("Failed to store certificate chain",
- KeyStore.getKeyStoreException(errorCode));
- }
- success = true;
- } finally {
- if (!success) {
- if (shouldReplacePrivateKey) {
- Credentials.deleteAllTypesForAlias(mKeyStore, alias, mUid);
- } else {
- Credentials.deleteCertificateTypesForAlias(mKeyStore, alias, mUid);
- Credentials.deleteLegacyKeyForAlias(mKeyStore, alias, mUid);
- }
- }
- }
- }
-
- private void setSecretKeyEntry(String entryAlias, SecretKey key,
- java.security.KeyStore.ProtectionParameter param)
- throws KeyStoreException {
- if ((param != null) && (!(param instanceof KeyProtection))) {
- throw new KeyStoreException(
- "Unsupported protection parameter class: " + param.getClass().getName()
- + ". Supported: " + KeyProtection.class.getName());
- }
- KeyProtection params = (KeyProtection) param;
-
- if (key instanceof AndroidKeyStoreSecretKey) {
- // KeyStore-backed secret key. It cannot be duplicated into another entry and cannot
- // overwrite its own entry.
- String keyAliasInKeystore = ((AndroidKeyStoreSecretKey) key).getAlias();
- if (keyAliasInKeystore == null) {
- throw new KeyStoreException("KeyStore-backed secret key does not have an alias");
- }
- String keyAliasPrefix = Credentials.USER_PRIVATE_KEY;
- if (!keyAliasInKeystore.startsWith(keyAliasPrefix)) {
- // try legacy prefix
- keyAliasPrefix = Credentials.USER_SECRET_KEY;
- if (!keyAliasInKeystore.startsWith(keyAliasPrefix)) {
- throw new KeyStoreException("KeyStore-backed secret key has invalid alias: "
- + keyAliasInKeystore);
- }
- }
- String keyEntryAlias =
- keyAliasInKeystore.substring(keyAliasPrefix.length());
- if (!entryAlias.equals(keyEntryAlias)) {
- throw new KeyStoreException("Can only replace KeyStore-backed keys with same"
- + " alias: " + entryAlias + " != " + keyEntryAlias);
- }
- // This is the entry where this key is already stored. No need to do anything.
- if (params != null) {
- throw new KeyStoreException("Modifying KeyStore-backed key using protection"
- + " parameters not supported");
- }
- return;
- }
-
- if (params == null) {
- throw new KeyStoreException(
- "Protection parameters must be specified when importing a symmetric key");
- }
-
- // Not a KeyStore-backed secret key -- import its key material into keystore.
- String keyExportFormat = key.getFormat();
- if (keyExportFormat == null) {
- throw new KeyStoreException(
- "Only secret keys that export their key material are supported");
- } else if (!"RAW".equals(keyExportFormat)) {
- throw new KeyStoreException(
- "Unsupported secret key material export format: " + keyExportFormat);
- }
- byte[] keyMaterial = key.getEncoded();
- if (keyMaterial == null) {
- throw new KeyStoreException("Key did not export its key material despite supporting"
- + " RAW format export");
- }
-
- KeymasterArguments args = new KeymasterArguments();
- try {
- int keymasterAlgorithm =
- KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(key.getAlgorithm());
- args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm);
-
- int[] keymasterDigests;
- if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
- // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm
- // implies SHA-256 digest). Because keymaster HMAC key is authorized only for one
- // digest, we don't let import parameters override the digest implied by the key.
- // If the parameters specify digests at all, they must specify only one digest, the
- // only implied by key algorithm.
- int keymasterImpliedDigest =
- KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm());
- if (keymasterImpliedDigest == -1) {
- throw new ProviderException(
- "HMAC key algorithm digest unknown for key algorithm "
- + key.getAlgorithm());
- }
- keymasterDigests = new int[] {keymasterImpliedDigest};
- if (params.isDigestsSpecified()) {
- // Digest(s) explicitly specified in params -- check that the list consists of
- // exactly one digest, the one implied by key algorithm.
- int[] keymasterDigestsFromParams =
- KeyProperties.Digest.allToKeymaster(params.getDigests());
- if ((keymasterDigestsFromParams.length != 1)
- || (keymasterDigestsFromParams[0] != keymasterImpliedDigest)) {
- throw new KeyStoreException(
- "Unsupported digests specification: "
- + Arrays.asList(params.getDigests()) + ". Only "
- + KeyProperties.Digest.fromKeymaster(keymasterImpliedDigest)
- + " supported for HMAC key algorithm " + key.getAlgorithm());
- }
- }
- } else {
- // Key algorithm does not imply a digest.
- if (params.isDigestsSpecified()) {
- keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests());
- } else {
- keymasterDigests = EmptyArray.INT;
- }
- }
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
-
- @KeyProperties.PurposeEnum int purposes = params.getPurposes();
- int[] keymasterBlockModes =
- KeyProperties.BlockMode.allToKeymaster(params.getBlockModes());
- if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0)
- && (params.isRandomizedEncryptionRequired())) {
- for (int keymasterBlockMode : keymasterBlockModes) {
- if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(
- keymasterBlockMode)) {
- throw new KeyStoreException(
- "Randomized encryption (IND-CPA) required but may be violated by"
- + " block mode: "
- + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode)
- + ". See KeyProtection documentation.");
- }
- }
- }
- args.addEnums(KeymasterDefs.KM_TAG_PURPOSE,
- KeyProperties.Purpose.allToKeymaster(purposes));
- args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
- if (params.getSignaturePaddings().length > 0) {
- throw new KeyStoreException("Signature paddings not supported for symmetric keys");
- }
- int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
- params.getEncryptionPaddings());
- args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
- KeymasterUtils.addUserAuthArgs(args, params);
- KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
- args,
- keymasterAlgorithm,
- keymasterBlockModes,
- keymasterDigests);
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
- params.getKeyValidityStart());
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
- params.getKeyValidityForOriginationEnd());
- args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
- params.getKeyValidityForConsumptionEnd());
-
- if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0)
- && (!params.isRandomizedEncryptionRequired())) {
- // Permit caller-provided IV when encrypting with this key
- args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
- }
- } catch (IllegalArgumentException | IllegalStateException e) {
- throw new KeyStoreException(e);
- }
- int flags = 0;
- if (params.isCriticalToDeviceEncryption()) {
- flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
- }
- if (params.isStrongBoxBacked()) {
- flags |= KeyStore.FLAG_STRONGBOX;
- }
-
- Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias, mUid);
- String keyAliasInKeystore = Credentials.USER_PRIVATE_KEY + entryAlias;
- int errorCode = mKeyStore.importKey(
- keyAliasInKeystore,
- args,
- KeymasterDefs.KM_KEY_FORMAT_RAW,
- keyMaterial,
- mUid,
- flags,
- new KeyCharacteristics());
- if (errorCode != KeyStore.NO_ERROR) {
- throw new KeyStoreException("Failed to import secret key. Keystore error code: "
- + errorCode);
- }
- }
-
- private void setWrappedKeyEntry(String alias, WrappedKeyEntry entry,
- java.security.KeyStore.ProtectionParameter param) throws KeyStoreException {
- if (param != null) {
- throw new KeyStoreException("Protection parameters are specified inside wrapped keys");
- }
-
- byte[] maskingKey = new byte[32];
-
-
- KeymasterArguments args = new KeymasterArguments();
- String[] parts = entry.getTransformation().split("/");
-
- String algorithm = parts[0];
- if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) {
- args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) {
- args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- }
-
- if (parts.length > 1) {
- String mode = parts[1];
- if (KeyProperties.BLOCK_MODE_ECB.equalsIgnoreCase(mode)) {
- args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
- } else if (KeyProperties.BLOCK_MODE_CBC.equalsIgnoreCase(mode)) {
- args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CBC);
- } else if (KeyProperties.BLOCK_MODE_CTR.equalsIgnoreCase(mode)) {
- args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
- } else if (KeyProperties.BLOCK_MODE_GCM.equalsIgnoreCase(mode)) {
- args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
- }
- }
-
- if (parts.length > 2) {
- String padding = parts[2];
- if (KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(padding)) {
- // Noop
- } else if (KeyProperties.ENCRYPTION_PADDING_PKCS7.equalsIgnoreCase(padding)) {
- args.addEnums(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_PKCS7);
- } else if (KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(padding)) {
- args.addEnums(KeymasterDefs.KM_TAG_PADDING,
- KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
- } else if (KeyProperties.ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(padding)) {
- args.addEnums(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_OAEP);
- }
- }
-
- KeyGenParameterSpec spec = (KeyGenParameterSpec) entry.getAlgorithmParameterSpec();
- if (spec.isDigestsSpecified()) {
- String digest = spec.getDigests()[0];
- if (KeyProperties.DIGEST_NONE.equalsIgnoreCase(digest)) {
- // Noop
- } else if (KeyProperties.DIGEST_MD5.equalsIgnoreCase(digest)) {
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_MD5);
- } else if (KeyProperties.DIGEST_SHA1.equalsIgnoreCase(digest)) {
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA1);
- } else if (KeyProperties.DIGEST_SHA224.equalsIgnoreCase(digest)) {
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_224);
- } else if (KeyProperties.DIGEST_SHA256.equalsIgnoreCase(digest)) {
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_256);
- } else if (KeyProperties.DIGEST_SHA384.equalsIgnoreCase(digest)) {
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_384);
- } else if (KeyProperties.DIGEST_SHA512.equalsIgnoreCase(digest)) {
- args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_512);
- }
- }
-
- int errorCode = mKeyStore.importWrappedKey(
- Credentials.USER_PRIVATE_KEY + alias,
- entry.getWrappedKeyBytes(),
- Credentials.USER_PRIVATE_KEY + entry.getWrappingKeyAlias(),
- maskingKey,
- args,
- GateKeeper.getSecureUserId(),
- 0, // FIXME fingerprint id?
- mUid,
- new KeyCharacteristics());
- if (errorCode == KeymasterDefs.KM_ERROR_UNIMPLEMENTED) {
- throw new SecureKeyImportUnavailableException("Could not import wrapped key");
- } else if (errorCode != KeyStore.NO_ERROR) {
- throw new KeyStoreException("Failed to import wrapped key. Keystore error code: "
- + errorCode);
- }
- }
-
- @Override
- public void engineSetKeyEntry(String alias, byte[] userKey, Certificate[] chain)
- throws KeyStoreException {
- throw new KeyStoreException("Operation not supported because key encoding is unknown");
- }
-
- @Override
- public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
- if (isKeyEntry(alias)) {
- throw new KeyStoreException("Entry exists and is not a trusted certificate");
- }
-
- // We can't set something to null.
- if (cert == null) {
- throw new NullPointerException("cert == null");
- }
-
- final byte[] encoded;
- try {
- encoded = cert.getEncoded();
- } catch (CertificateEncodingException e) {
- throw new KeyStoreException(e);
- }
-
- if (!mKeyStore.put(Credentials.CA_CERTIFICATE + alias, encoded, mUid, KeyStore.FLAG_NONE)) {
- throw new KeyStoreException("Couldn't insert certificate; is KeyStore initialized?");
- }
- }
-
- @Override
- public void engineDeleteEntry(String alias) throws KeyStoreException {
- if (!Credentials.deleteAllTypesForAlias(mKeyStore, alias, mUid)) {
- throw new KeyStoreException("Failed to delete entry: " + alias);
- }
- }
-
- private Set<String> getUniqueAliases() {
- final String[] rawAliases = mKeyStore.list("", mUid);
- if (rawAliases == null) {
- return new HashSet<String>();
- }
-
- final Set<String> aliases = new HashSet<String>(rawAliases.length);
- for (String alias : rawAliases) {
- final int idx = alias.indexOf('_');
- if ((idx == -1) || (alias.length() <= idx)) {
- Log.e(NAME, "invalid alias: " + alias);
- continue;
- }
-
- aliases.add(new String(alias.substring(idx + 1)));
- }
-
- return aliases;
- }
-
- @Override
- public Enumeration<String> engineAliases() {
- return Collections.enumeration(getUniqueAliases());
- }
-
- @Override
- public boolean engineContainsAlias(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
-
- return mKeyStore.contains(Credentials.USER_PRIVATE_KEY + alias, mUid)
- || mKeyStore.contains(Credentials.USER_SECRET_KEY + alias, mUid)
- || mKeyStore.contains(Credentials.USER_CERTIFICATE + alias, mUid)
- || mKeyStore.contains(Credentials.CA_CERTIFICATE + alias, mUid);
- }
-
- @Override
- public int engineSize() {
- return getUniqueAliases().size();
- }
-
- @Override
- public boolean engineIsKeyEntry(String alias) {
- return isKeyEntry(alias);
- }
-
- private boolean isKeyEntry(String alias) {
- return mKeyStore.contains(Credentials.USER_PRIVATE_KEY + alias, mUid) ||
- mKeyStore.contains(Credentials.USER_SECRET_KEY + alias, mUid);
- }
-
-
- private boolean isCertificateEntry(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
-
- return mKeyStore.contains(Credentials.CA_CERTIFICATE + alias, mUid);
- }
-
- @Override
- public boolean engineIsCertificateEntry(String alias) {
- return !isKeyEntry(alias) && isCertificateEntry(alias);
- }
-
- @Override
- public String engineGetCertificateAlias(Certificate cert) {
- if (cert == null) {
- return null;
- }
- if (!"X.509".equalsIgnoreCase(cert.getType())) {
- // Only X.509 certificates supported
- return null;
- }
- byte[] targetCertBytes;
- try {
- targetCertBytes = cert.getEncoded();
- } catch (CertificateEncodingException e) {
- return null;
- }
- if (targetCertBytes == null) {
- return null;
- }
-
- final Set<String> nonCaEntries = new HashSet<String>();
-
- /*
- * First scan the PrivateKeyEntry types. The KeyStoreSpi documentation
- * says to only compare the first certificate in the chain which is
- * equivalent to the USER_CERTIFICATE prefix for the Android keystore
- * convention.
- */
- final String[] certAliases = mKeyStore.list(Credentials.USER_CERTIFICATE, mUid);
- if (certAliases != null) {
- for (String alias : certAliases) {
- final byte[] certBytes = mKeyStore.get(Credentials.USER_CERTIFICATE + alias, mUid);
- if (certBytes == null) {
- continue;
- }
-
- nonCaEntries.add(alias);
-
- if (Arrays.equals(certBytes, targetCertBytes)) {
- return alias;
- }
- }
- }
-
- /*
- * Look at all the TrustedCertificateEntry types. Skip all the
- * PrivateKeyEntry we looked at above.
- */
- final String[] caAliases = mKeyStore.list(Credentials.CA_CERTIFICATE, mUid);
- if (certAliases != null) {
- for (String alias : caAliases) {
- if (nonCaEntries.contains(alias)) {
- continue;
- }
-
- final byte[] certBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias, mUid);
- if (certBytes == null) {
- continue;
- }
-
- if (Arrays.equals(certBytes, targetCertBytes)) {
- return alias;
- }
- }
- }
-
- return null;
- }
-
- @Override
- public void engineStore(OutputStream stream, char[] password) throws IOException,
- NoSuchAlgorithmException, CertificateException {
- throw new UnsupportedOperationException("Can not serialize AndroidKeyStore to OutputStream");
- }
-
- @Override
- public void engineLoad(InputStream stream, char[] password) throws IOException,
- NoSuchAlgorithmException, CertificateException {
- if (stream != null) {
- throw new IllegalArgumentException("InputStream not supported");
- }
-
- if (password != null) {
- throw new IllegalArgumentException("password not supported");
- }
-
- // Unfortunate name collision.
- mKeyStore = KeyStore.getInstance();
- mUid = KeyStore.UID_SELF;
- }
-
- @Override
- public void engineLoad(LoadStoreParameter param) throws IOException,
- NoSuchAlgorithmException, CertificateException {
- int uid = KeyStore.UID_SELF;
- if (param != null) {
- if (param instanceof AndroidKeyStoreLoadStoreParameter) {
- uid = ((AndroidKeyStoreLoadStoreParameter) param).getUid();
- } else {
- throw new IllegalArgumentException(
- "Unsupported param type: " + param.getClass());
- }
- }
- mKeyStore = KeyStore.getInstance();
- mUid = uid;
- }
-
- @Override
- public void engineSetEntry(String alias, Entry entry, ProtectionParameter param)
- throws KeyStoreException {
- if (entry == null) {
- throw new KeyStoreException("entry == null");
- }
-
- Credentials.deleteAllTypesForAlias(mKeyStore, alias, mUid);
-
- if (entry instanceof java.security.KeyStore.TrustedCertificateEntry) {
- java.security.KeyStore.TrustedCertificateEntry trE =
- (java.security.KeyStore.TrustedCertificateEntry) entry;
- engineSetCertificateEntry(alias, trE.getTrustedCertificate());
- return;
- }
-
- if (entry instanceof PrivateKeyEntry) {
- PrivateKeyEntry prE = (PrivateKeyEntry) entry;
- setPrivateKeyEntry(alias, prE.getPrivateKey(), prE.getCertificateChain(), param);
- } else if (entry instanceof SecretKeyEntry) {
- SecretKeyEntry secE = (SecretKeyEntry) entry;
- setSecretKeyEntry(alias, secE.getSecretKey(), param);
- } else if (entry instanceof WrappedKeyEntry) {
- WrappedKeyEntry wke = (WrappedKeyEntry) entry;
- setWrappedKeyEntry(alias, wke, param);
- } else {
- throw new KeyStoreException(
- "Entry must be a PrivateKeyEntry, SecretKeyEntry or TrustedCertificateEntry"
- + "; was " + entry);
- }
- }
-
- /**
- * {@link X509Certificate} which returns {@link AndroidKeyStorePublicKey} from
- * {@link #getPublicKey()}. This is so that crypto operations on these public keys contain
- * can find out which keystore private key entry to use. This is needed so that Android Keystore
- * crypto operations using public keys can find out which key alias to use. These operations
- * require an alias.
- */
- static class KeyStoreX509Certificate extends DelegatingX509Certificate {
- private final String mPrivateKeyAlias;
- private final int mPrivateKeyUid;
- KeyStoreX509Certificate(String privateKeyAlias, int privateKeyUid,
- X509Certificate delegate) {
- super(delegate);
- mPrivateKeyAlias = privateKeyAlias;
- mPrivateKeyUid = privateKeyUid;
- }
-
- @Override
- public PublicKey getPublicKey() {
- PublicKey original = super.getPublicKey();
- return AndroidKeyStoreProvider.getAndroidKeyStorePublicKey(
- mPrivateKeyAlias, mPrivateKeyUid,
- original.getAlgorithm(), original.getEncoded());
- }
- }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
deleted file mode 100644
index 1f1d36fa4405..000000000000
--- a/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-import java.util.Arrays;
-
-import javax.crypto.CipherSpi;
-import javax.crypto.spec.IvParameterSpec;
-
-/**
- * Base class for Android Keystore unauthenticated AES {@link CipherSpi} implementations.
- *
- * @hide
- */
-class AndroidKeyStoreUnauthenticatedAESCipherSpi extends AndroidKeyStoreCipherSpiBase {
-
- abstract static class ECB extends AndroidKeyStoreUnauthenticatedAESCipherSpi {
- protected ECB(int keymasterPadding) {
- super(KeymasterDefs.KM_MODE_ECB, keymasterPadding, false);
- }
-
- public static class NoPadding extends ECB {
- public NoPadding() {
- super(KeymasterDefs.KM_PAD_NONE);
- }
- }
-
- public static class PKCS7Padding extends ECB {
- public PKCS7Padding() {
- super(KeymasterDefs.KM_PAD_PKCS7);
- }
- }
- }
-
- abstract static class CBC extends AndroidKeyStoreUnauthenticatedAESCipherSpi {
- protected CBC(int keymasterPadding) {
- super(KeymasterDefs.KM_MODE_CBC, keymasterPadding, true);
- }
-
- public static class NoPadding extends CBC {
- public NoPadding() {
- super(KeymasterDefs.KM_PAD_NONE);
- }
- }
-
- public static class PKCS7Padding extends CBC {
- public PKCS7Padding() {
- super(KeymasterDefs.KM_PAD_PKCS7);
- }
- }
- }
-
- abstract static class CTR extends AndroidKeyStoreUnauthenticatedAESCipherSpi {
- protected CTR(int keymasterPadding) {
- super(KeymasterDefs.KM_MODE_CTR, keymasterPadding, true);
- }
-
- public static class NoPadding extends CTR {
- public NoPadding() {
- super(KeymasterDefs.KM_PAD_NONE);
- }
- }
- }
-
- private static final int BLOCK_SIZE_BYTES = 16;
-
- private final int mKeymasterBlockMode;
- private final int mKeymasterPadding;
- /** Whether this transformation requires an IV. */
- private final boolean mIvRequired;
-
- private byte[] mIv;
-
- /** Whether the current {@code #mIv} has been used by the underlying crypto operation. */
- private boolean mIvHasBeenUsed;
-
- AndroidKeyStoreUnauthenticatedAESCipherSpi(
- int keymasterBlockMode,
- int keymasterPadding,
- boolean ivRequired) {
- mKeymasterBlockMode = keymasterBlockMode;
- mKeymasterPadding = keymasterPadding;
- mIvRequired = ivRequired;
- }
-
- @Override
- protected final void resetAll() {
- mIv = null;
- mIvHasBeenUsed = false;
- super.resetAll();
- }
-
- @Override
- protected final void resetWhilePreservingInitState() {
- super.resetWhilePreservingInitState();
- }
-
- @Override
- protected final void initKey(int opmode, Key key) throws InvalidKeyException {
- if (!(key instanceof AndroidKeyStoreSecretKey)) {
- throw new InvalidKeyException(
- "Unsupported key: " + ((key != null) ? key.getClass().getName() : "null"));
- }
- if (!KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(key.getAlgorithm())) {
- throw new InvalidKeyException(
- "Unsupported key algorithm: " + key.getAlgorithm() + ". Only " +
- KeyProperties.KEY_ALGORITHM_AES + " supported");
- }
- setKey((AndroidKeyStoreSecretKey) key);
- }
-
- @Override
- protected final void initAlgorithmSpecificParameters() throws InvalidKeyException {
- if (!mIvRequired) {
- return;
- }
-
- // IV is used
- if (!isEncrypting()) {
- throw new InvalidKeyException("IV required when decrypting"
- + ". Use IvParameterSpec or AlgorithmParameters to provide it.");
- }
- }
-
- @Override
- protected final void initAlgorithmSpecificParameters(AlgorithmParameterSpec params)
- throws InvalidAlgorithmParameterException {
- if (!mIvRequired) {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("Unsupported parameters: " + params);
- }
- return;
- }
-
- // IV is used
- if (params == null) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException(
- "IvParameterSpec must be provided when decrypting");
- }
- return;
- }
- if (!(params instanceof IvParameterSpec)) {
- throw new InvalidAlgorithmParameterException("Only IvParameterSpec supported");
- }
- mIv = ((IvParameterSpec) params).getIV();
- if (mIv == null) {
- throw new InvalidAlgorithmParameterException("Null IV in IvParameterSpec");
- }
- }
-
- @Override
- protected final void initAlgorithmSpecificParameters(AlgorithmParameters params)
- throws InvalidAlgorithmParameterException {
- if (!mIvRequired) {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("Unsupported parameters: " + params);
- }
- return;
- }
-
- // IV is used
- if (params == null) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException("IV required when decrypting"
- + ". Use IvParameterSpec or AlgorithmParameters to provide it.");
- }
- return;
- }
-
- if (!"AES".equalsIgnoreCase(params.getAlgorithm())) {
- throw new InvalidAlgorithmParameterException(
- "Unsupported AlgorithmParameters algorithm: " + params.getAlgorithm()
- + ". Supported: AES");
- }
-
- IvParameterSpec ivSpec;
- try {
- ivSpec = params.getParameterSpec(IvParameterSpec.class);
- } catch (InvalidParameterSpecException e) {
- if (!isEncrypting()) {
- // IV must be provided by the caller
- throw new InvalidAlgorithmParameterException("IV required when decrypting"
- + ", but not found in parameters: " + params, e);
- }
- mIv = null;
- return;
- }
- mIv = ivSpec.getIV();
- if (mIv == null) {
- throw new InvalidAlgorithmParameterException("Null IV in AlgorithmParameters");
- }
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForBegin() {
- if ((mIvRequired) && (mIv == null) && (isEncrypting())) {
- // IV will need to be generated
- return BLOCK_SIZE_BYTES;
- }
-
- return 0;
- }
-
- @Override
- protected final int getAdditionalEntropyAmountForFinish() {
- return 0;
- }
-
- @Override
- protected final void addAlgorithmSpecificParametersToBegin(
- @NonNull KeymasterArguments keymasterArgs) {
- if ((isEncrypting()) && (mIvRequired) && (mIvHasBeenUsed)) {
- // IV is being reused for encryption: this violates security best practices.
- throw new IllegalStateException(
- "IV has already been used. Reusing IV in encryption mode violates security best"
- + " practices.");
- }
-
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
- keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
- if ((mIvRequired) && (mIv != null)) {
- keymasterArgs.addBytes(KeymasterDefs.KM_TAG_NONCE, mIv);
- }
- }
-
- @Override
- protected final void loadAlgorithmSpecificParametersFromBeginResult(
- @NonNull KeymasterArguments keymasterArgs) {
- mIvHasBeenUsed = true;
-
- // NOTE: Keymaster doesn't always return an IV, even if it's used.
- byte[] returnedIv = keymasterArgs.getBytes(KeymasterDefs.KM_TAG_NONCE, null);
- if ((returnedIv != null) && (returnedIv.length == 0)) {
- returnedIv = null;
- }
-
- if (mIvRequired) {
- if (mIv == null) {
- mIv = returnedIv;
- } else if ((returnedIv != null) && (!Arrays.equals(returnedIv, mIv))) {
- throw new ProviderException("IV in use differs from provided IV");
- }
- } else {
- if (returnedIv != null) {
- throw new ProviderException(
- "IV in use despite IV not being used by this transformation");
- }
- }
- }
-
- @Override
- protected final int engineGetBlockSize() {
- return BLOCK_SIZE_BYTES;
- }
-
- @Override
- protected final int engineGetOutputSize(int inputLen) {
- return inputLen + 3 * BLOCK_SIZE_BYTES;
- }
-
- @Override
- protected final byte[] engineGetIV() {
- return ArrayUtils.cloneIfNotEmpty(mIv);
- }
-
- @Nullable
- @Override
- protected final AlgorithmParameters engineGetParameters() {
- if (!mIvRequired) {
- return null;
- }
- if ((mIv != null) && (mIv.length > 0)) {
- try {
- AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
- params.init(new IvParameterSpec(mIv));
- return params;
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(
- "Failed to obtain AES AlgorithmParameters", e);
- } catch (InvalidParameterSpecException e) {
- throw new ProviderException(
- "Failed to initialize AES AlgorithmParameters with an IV",
- e);
- }
- }
- return null;
- }
-}
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index ec3b102c5af9..66d842ec5614 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -34,9 +34,11 @@ import java.nio.charset.StandardCharsets;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.SecureRandom;
+import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.ECGenParameterSpec;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Random;
import java.util.Set;
@@ -248,8 +250,9 @@ public abstract class AttestationUtils {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
+ Certificate[] certs = keyStore.getCertificateChain(keystoreAlias);
X509Certificate[] certificateChain =
- (X509Certificate[]) keyStore.getCertificateChain(keystoreAlias);
+ Arrays.copyOf(certs, certs.length, X509Certificate[].class);
keyStore.deleteEntry(keystoreAlias);
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 9ca551b26aab..1f9022b4ad3d 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -446,13 +446,6 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
@UnsupportedAppUsage
@Deprecated
public int getUid() {
- if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
- // If Keystore2 has not been enabled we have to behave as if mNamespace is actually
- // a UID, because we are still being used with the old Keystore SPI.
- // TODO This if statement and body can be removed when the Keystore 2 migration is
- // complete. b/171563717
- return mNamespace;
- }
try {
return KeyProperties.namespaceToLegacyUid(mNamespace);
} catch (IllegalArgumentException e) {
@@ -1021,14 +1014,6 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
@NonNull
@Deprecated
public Builder setUid(int uid) {
- if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
- // If Keystore2 has not been enabled we have to behave as if mNamespace is actually
- // a UID, because we are still being used with the old Keystore SPI.
- // TODO This if statement and body can be removed when the Keystore 2 migration is
- // complete. b/171563717
- mNamespace = uid;
- return this;
- }
mNamespace = KeyProperties.legacyUidToNamespace(uid);
return this;
}
@@ -1666,9 +1651,10 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
* Set whether this key is critical to the device encryption flow
*
* This is a special flag only available to system servers to indicate the current key
- * is part of the device encryption flow.
+ * is part of the device encryption flow. Setting this flag causes the key to not
+ * be cryptographically bound to the LSKF even if the key is otherwise authentication
+ * bound.
*
- * @see android.security.KeyStore#FLAG_CRITICAL_TO_DEVICE_ENCRYPTION
* @hide
*/
public Builder setCriticalToDeviceEncryption(boolean critical) {
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index fe92270ca508..c14c3c534cf4 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -24,6 +24,7 @@ import android.app.KeyguardManager;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
import android.security.GateKeeper;
+import android.security.keystore2.KeymasterUtils;
import java.security.Key;
import java.security.KeyStore.ProtectionParameter;
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
deleted file mode 100644
index 2c0f40d528d2..000000000000
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.os.IBinder;
-import android.security.KeyStore;
-import android.security.KeyStoreException;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keymaster.OperationResult;
-
-import libcore.util.EmptyArray;
-
-/**
- * Helper for streaming a crypto operation's input and output via {@link KeyStore} service's
- * {@code update} and {@code finish} operations.
- *
- * <p>The helper abstracts away issues that need to be solved in most code that uses KeyStore's
- * update and finish operations. Firstly, KeyStore's update operation can consume only a limited
- * amount of data in one go because the operations are marshalled via Binder. Secondly, the update
- * operation may consume less data than provided, in which case the caller has to buffer the
- * remainder for next time. Thirdly, when the input is smaller than a threshold, skipping update
- * and passing input data directly to final improves performance. This threshold is configurable;
- * using a threshold <= 1 causes the helper act eagerly, which may be required for some types of
- * operations (e.g. ciphers).
- *
- * <p>The helper exposes {@link #update(byte[], int, int) update} and
- * {@link #doFinal(byte[], int, int, byte[], byte[]) doFinal} operations which can be used to
- * conveniently implement various JCA crypto primitives.
- *
- * <p>Bidirectional chunked streaming of data via a KeyStore crypto operation is abstracted away as
- * a {@link Stream} to avoid having this class deal with operation tokens and occasional additional
- * parameters to {@code update} and {@code final} operations.
- *
- * @hide
- */
-class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationStreamer {
-
- /**
- * Bidirectional chunked data stream over a KeyStore crypto operation.
- */
- interface Stream {
- /**
- * Returns the result of the KeyStore {@code update} operation or null if keystore couldn't
- * be reached.
- */
- OperationResult update(byte[] input);
-
- /**
- * Returns the result of the KeyStore {@code finish} operation or null if keystore couldn't
- * be reached.
- */
- OperationResult finish(byte[] input, byte[] siganture, byte[] additionalEntropy);
- }
-
- // Binder buffer is about 1MB, but it's shared between all active transactions of the process.
- // Thus, it's safer to use a much smaller upper bound.
- private static final int DEFAULT_CHUNK_SIZE_MAX = 64 * 1024;
- // The chunk buffer will be sent to update until its size under this threshold.
- // This threshold should be <= the max input allowed for finish.
- // Setting this threshold <= 1 will effectivley disable buffering between updates.
- private static final int DEFAULT_CHUNK_SIZE_THRESHOLD = 2 * 1024;
-
- private final Stream mKeyStoreStream;
- private final int mChunkSizeMax;
- private final int mChunkSizeThreshold;
- private final byte[] mChunk;
- private int mChunkLength = 0;
- private long mConsumedInputSizeBytes;
- private long mProducedOutputSizeBytes;
-
- KeyStoreCryptoOperationChunkedStreamer(Stream operation) {
- this(operation, DEFAULT_CHUNK_SIZE_THRESHOLD, DEFAULT_CHUNK_SIZE_MAX);
- }
-
- KeyStoreCryptoOperationChunkedStreamer(Stream operation, int chunkSizeThreshold) {
- this(operation, chunkSizeThreshold, DEFAULT_CHUNK_SIZE_MAX);
- }
-
- KeyStoreCryptoOperationChunkedStreamer(Stream operation, int chunkSizeThreshold,
- int chunkSizeMax) {
- mKeyStoreStream = operation;
- mChunkSizeMax = chunkSizeMax;
- if (chunkSizeThreshold <= 0) {
- mChunkSizeThreshold = 1;
- } else if (chunkSizeThreshold > chunkSizeMax) {
- mChunkSizeThreshold = chunkSizeMax;
- } else {
- mChunkSizeThreshold = chunkSizeThreshold;
- }
- mChunk = new byte[mChunkSizeMax];
- }
-
- public byte[] update(byte[] input, int inputOffset, int inputLength) throws KeyStoreException {
- if (inputLength == 0 || input == null) {
- // No input provided
- return EmptyArray.BYTE;
- }
- if (inputLength < 0 || inputOffset < 0 || (inputOffset + inputLength) > input.length) {
- throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR,
- "Input offset and length out of bounds of input array");
- }
-
- byte[] output = EmptyArray.BYTE;
-
- while (inputLength > 0 || mChunkLength >= mChunkSizeThreshold) {
- int inputConsumed = ArrayUtils.copy(input, inputOffset, mChunk, mChunkLength,
- inputLength);
- inputLength -= inputConsumed;
- inputOffset += inputConsumed;
- mChunkLength += inputConsumed;
- mConsumedInputSizeBytes += inputConsumed;
-
- if (mChunkLength > mChunkSizeMax) {
- throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH,
- "Chunk size exceeded max chunk size. Max: " + mChunkSizeMax
- + " Actual: " + mChunkLength);
- }
-
- if (mChunkLength >= mChunkSizeThreshold) {
- OperationResult opResult = mKeyStoreStream.update(
- ArrayUtils.subarray(mChunk, 0, mChunkLength));
-
- if (opResult == null) {
- throw new KeyStoreConnectException();
- } else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw KeyStore.getKeyStoreException(opResult.resultCode);
- }
- if (opResult.inputConsumed <= 0) {
- throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH,
- "Keystore consumed 0 of " + mChunkLength + " bytes provided.");
- } else if (opResult.inputConsumed > mChunkLength) {
- throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR,
- "Keystore consumed more input than provided. Provided: "
- + mChunkLength + ", consumed: " + opResult.inputConsumed);
- }
- mChunkLength -= opResult.inputConsumed;
-
- if (mChunkLength > 0) {
- // Partialy consumed, shift chunk contents
- ArrayUtils.copy(mChunk, opResult.inputConsumed, mChunk, 0, mChunkLength);
- }
-
- if ((opResult.output != null) && (opResult.output.length > 0)) {
- // Output was produced
- mProducedOutputSizeBytes += opResult.output.length;
- output = ArrayUtils.concat(output, opResult.output);
- }
- }
- }
- return output;
- }
-
- public byte[] doFinal(byte[] input, int inputOffset, int inputLength,
- byte[] signature, byte[] additionalEntropy) throws KeyStoreException {
- byte[] output = update(input, inputOffset, inputLength);
- byte[] finalChunk = ArrayUtils.subarray(mChunk, 0, mChunkLength);
- OperationResult opResult = mKeyStoreStream.finish(finalChunk, signature, additionalEntropy);
-
- if (opResult == null) {
- throw new KeyStoreConnectException();
- } else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw KeyStore.getKeyStoreException(opResult.resultCode);
- }
- // If no error, assume all input consumed
- mConsumedInputSizeBytes += finalChunk.length;
-
- if ((opResult.output != null) && (opResult.output.length > 0)) {
- mProducedOutputSizeBytes += opResult.output.length;
- output = ArrayUtils.concat(output, opResult.output);
- }
-
- return output;
- }
-
- @Override
- public long getConsumedInputSizeBytes() {
- return mConsumedInputSizeBytes;
- }
-
- @Override
- public long getProducedOutputSizeBytes() {
- return mProducedOutputSizeBytes;
- }
-
- /**
- * Main data stream via a KeyStore streaming operation.
- *
- * <p>For example, for an encryption operation, this is the stream through which plaintext is
- * provided and ciphertext is obtained.
- */
- public static class MainDataStream implements Stream {
-
- private final KeyStore mKeyStore;
- private final IBinder mOperationToken;
-
- public MainDataStream(KeyStore keyStore, IBinder operationToken) {
- mKeyStore = keyStore;
- mOperationToken = operationToken;
- }
-
- @Override
- public OperationResult update(byte[] input) {
- return mKeyStore.update(mOperationToken, null, input);
- }
-
- @Override
- public OperationResult finish(byte[] input, byte[] signature, byte[] additionalEntropy) {
- return mKeyStore.finish(mOperationToken, null, input, signature, additionalEntropy);
- }
- }
-}
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java
deleted file mode 100644
index 062c2d42b3b5..000000000000
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.security.KeyStore;
-import android.security.KeyStoreException;
-
-/**
- * Helper for streaming a crypto operation's input and output via {@link KeyStore} service's
- * {@code update} and {@code finish} operations.
- *
- * <p>The helper abstracts away to issues that need to be solved in most code that uses KeyStore's
- * update and finish operations. Firstly, KeyStore's update operation can consume only a limited
- * amount of data in one go because the operations are marshalled via Binder. Secondly, the update
- * operation may consume less data than provided, in which case the caller has to buffer the
- * remainder for next time. The helper exposes {@link #update(byte[], int, int) update} and
- * {@link #doFinal(byte[], int, int, byte[], byte[]) doFinal} operations which can be used to
- * conveniently implement various JCA crypto primitives.
- *
- * @hide
- */
-interface KeyStoreCryptoOperationStreamer {
- byte[] update(byte[] input, int inputOffset, int inputLength) throws KeyStoreException;
- byte[] doFinal(byte[] input, int inputOffset, int inputLength, byte[] signature,
- byte[] additionalEntropy) throws KeyStoreException;
- long getConsumedInputSizeBytes();
- long getProducedOutputSizeBytes();
-}
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java
deleted file mode 100644
index c82b6e6bc6fe..000000000000
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.security.KeyStore;
-import android.security.keymaster.KeymasterDefs;
-
-import libcore.util.EmptyArray;
-
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.SecureRandom;
-
-/**
- * Assorted utility methods for implementing crypto operations on top of KeyStore.
- *
- * @hide
- */
-abstract class KeyStoreCryptoOperationUtils {
-
- private static volatile SecureRandom sRng;
-
- private KeyStoreCryptoOperationUtils() {}
-
- /**
- * Returns the {@link InvalidKeyException} to be thrown by the {@code init} method of
- * the crypto operation in response to {@code KeyStore.begin} operation or {@code null} if
- * the {@code init} method should succeed.
- */
- static InvalidKeyException getInvalidKeyExceptionForInit(
- KeyStore keyStore, AndroidKeyStoreKey key, int beginOpResultCode) {
- if (beginOpResultCode == KeyStore.NO_ERROR) {
- return null;
- }
-
- // An error occurred. However, some errors should not lead to init throwing an exception.
- // See below.
- InvalidKeyException e =
- keyStore.getInvalidKeyException(key.getAlias(), key.getUid(), beginOpResultCode);
- switch (beginOpResultCode) {
- case KeyStore.OP_AUTH_NEEDED:
- // Operation needs to be authorized by authenticating the user. Don't throw an
- // exception is such authentication is possible for this key
- // (UserNotAuthenticatedException). An example of when it's not possible is where
- // the key is permanently invalidated (KeyPermanentlyInvalidatedException).
- if (e instanceof UserNotAuthenticatedException) {
- return null;
- }
- break;
- }
- return e;
- }
-
- /**
- * Returns the exception to be thrown by the {@code Cipher.init} method of the crypto operation
- * in response to {@code KeyStore.begin} operation or {@code null} if the {@code init} method
- * should succeed.
- */
- public static GeneralSecurityException getExceptionForCipherInit(
- KeyStore keyStore, AndroidKeyStoreKey key, int beginOpResultCode) {
- if (beginOpResultCode == KeyStore.NO_ERROR) {
- return null;
- }
-
- // Cipher-specific cases
- switch (beginOpResultCode) {
- case KeymasterDefs.KM_ERROR_INVALID_NONCE:
- return new InvalidAlgorithmParameterException("Invalid IV");
- case KeymasterDefs.KM_ERROR_CALLER_NONCE_PROHIBITED:
- return new InvalidAlgorithmParameterException("Caller-provided IV not permitted");
- }
-
- // General cases
- return getInvalidKeyExceptionForInit(keyStore, key, beginOpResultCode);
- }
-
- /**
- * Returns the requested number of random bytes to mix into keystore/keymaster RNG.
- *
- * @param rng RNG from which to obtain the random bytes or {@code null} for the platform-default
- * RNG.
- */
- static byte[] getRandomBytesToMixIntoKeystoreRng(SecureRandom rng, int sizeBytes) {
- if (sizeBytes <= 0) {
- return EmptyArray.BYTE;
- }
- if (rng == null) {
- rng = getRng();
- }
- byte[] result = new byte[sizeBytes];
- rng.nextBytes(result);
- return result;
- }
-
- private static SecureRandom getRng() {
- // IMPLEMENTATION NOTE: It's OK to share a SecureRandom instance because SecureRandom is
- // required to be thread-safe.
- if (sRng == null) {
- sRng = new SecureRandom();
- }
- return sRng;
- }
-}
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
deleted file mode 100644
index 670ef5e32f0c..000000000000
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.security.keystore;
-
-import android.hardware.biometrics.BiometricManager;
-import android.security.GateKeeper;
-import android.security.KeyStore;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterDefs;
-
-import java.security.ProviderException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @hide
- */
-public abstract class KeymasterUtils {
-
- private KeymasterUtils() {}
-
- public static int getDigestOutputSizeBits(int keymasterDigest) {
- switch (keymasterDigest) {
- case KeymasterDefs.KM_DIGEST_NONE:
- return -1;
- case KeymasterDefs.KM_DIGEST_MD5:
- return 128;
- case KeymasterDefs.KM_DIGEST_SHA1:
- return 160;
- case KeymasterDefs.KM_DIGEST_SHA_2_224:
- return 224;
- case KeymasterDefs.KM_DIGEST_SHA_2_256:
- return 256;
- case KeymasterDefs.KM_DIGEST_SHA_2_384:
- return 384;
- case KeymasterDefs.KM_DIGEST_SHA_2_512:
- return 512;
- default:
- throw new IllegalArgumentException("Unknown digest: " + keymasterDigest);
- }
- }
-
- public static boolean isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(
- int keymasterBlockMode) {
- switch (keymasterBlockMode) {
- case KeymasterDefs.KM_MODE_ECB:
- return false;
- case KeymasterDefs.KM_MODE_CBC:
- case KeymasterDefs.KM_MODE_CTR:
- case KeymasterDefs.KM_MODE_GCM:
- return true;
- default:
- throw new IllegalArgumentException("Unsupported block mode: " + keymasterBlockMode);
- }
- }
-
- public static boolean isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto(
- int keymasterPadding) {
- switch (keymasterPadding) {
- case KeymasterDefs.KM_PAD_NONE:
- return false;
- case KeymasterDefs.KM_PAD_RSA_OAEP:
- case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
- return true;
- default:
- throw new IllegalArgumentException(
- "Unsupported asymmetric encryption padding scheme: " + keymasterPadding);
- }
- }
-
- private static void addSids(KeymasterArguments args, UserAuthArgs spec) {
- // If both biometric and credential are accepted, then just use the root sid from gatekeeper
- if (spec.getUserAuthenticationType() == (KeyProperties.AUTH_BIOMETRIC_STRONG
- | KeyProperties.AUTH_DEVICE_CREDENTIAL)) {
- if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
- args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
- KeymasterArguments.toUint64(spec.getBoundToSpecificSecureUserId()));
- } else {
- // The key is authorized for use for the specified amount of time after the user has
- // authenticated. Whatever unlocks the secure lock screen should authorize this key.
- args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
- KeymasterArguments.toUint64(getRootSid()));
- }
- } else {
- List<Long> sids = new ArrayList<>();
- if ((spec.getUserAuthenticationType() & KeyProperties.AUTH_BIOMETRIC_STRONG) != 0) {
- final BiometricManager bm = KeyStore.getApplicationContext()
- .getSystemService(BiometricManager.class);
-
- // TODO: Restore permission check in getAuthenticatorIds once the ID is no longer
- // needed here.
-
- final long[] biometricSids = bm.getAuthenticatorIds();
-
- if (biometricSids.length == 0) {
- throw new IllegalStateException(
- "At least one biometric must be enrolled to create keys requiring user"
- + " authentication for every use");
- }
-
- if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
- sids.add(spec.getBoundToSpecificSecureUserId());
- } else if (spec.isInvalidatedByBiometricEnrollment()) {
- // The biometric-only SIDs will change on biometric enrollment or removal of all
- // enrolled templates, invalidating the key.
- for (long sid : biometricSids) {
- sids.add(sid);
- }
- } else {
- // The root SID will *not* change on fingerprint enrollment, or removal of all
- // enrolled fingerprints, allowing the key to remain valid.
- sids.add(getRootSid());
- }
- } else if ((spec.getUserAuthenticationType() & KeyProperties.AUTH_DEVICE_CREDENTIAL)
- != 0) {
- sids.add(getRootSid());
- } else {
- throw new IllegalStateException("Invalid or no authentication type specified.");
- }
-
- for (int i = 0; i < sids.size(); i++) {
- args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
- KeymasterArguments.toUint64(sids.get(i)));
- }
- }
- }
-
- /**
- * Adds keymaster arguments to express the key's authorization policy supported by user
- * authentication.
- *
- * @param args The arguments sent to keymaster that need to be populated from the spec
- * @param spec The user authentication relevant portions of the spec passed in from the caller.
- * This spec will be translated into the relevant keymaster tags to be loaded into args.
- * @throws IllegalStateException if user authentication is required but the system is in a wrong
- * state (e.g., secure lock screen not set up) for generating or importing keys that
- * require user authentication.
- */
- public static void addUserAuthArgs(KeymasterArguments args, UserAuthArgs spec) {
-
- if (spec.isUserConfirmationRequired()) {
- args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
- }
-
- if (spec.isUserPresenceRequired()) {
- args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
- }
-
- if (spec.isUnlockedDeviceRequired()) {
- args.addBoolean(KeymasterDefs.KM_TAG_UNLOCKED_DEVICE_REQUIRED);
- }
-
- if (!spec.isUserAuthenticationRequired()) {
- args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
- return;
- }
-
- if (spec.getUserAuthenticationValidityDurationSeconds() == 0) {
- // Every use of this key needs to be authorized by the user.
- addSids(args, spec);
- args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, spec.getUserAuthenticationType());
-
- if (spec.isUserAuthenticationValidWhileOnBody()) {
- throw new ProviderException("Key validity extension while device is on-body is not "
- + "supported for keys requiring fingerprint authentication");
- }
- } else {
- addSids(args, spec);
- args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, spec.getUserAuthenticationType());
- args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
- spec.getUserAuthenticationValidityDurationSeconds());
- if (spec.isUserAuthenticationValidWhileOnBody()) {
- args.addBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
- }
- }
- }
-
- /**
- * Adds {@code KM_TAG_MIN_MAC_LENGTH} tag, if necessary, to the keymaster arguments for
- * generating or importing a key. This tag may only be needed for symmetric keys (e.g., HMAC,
- * AES-GCM).
- */
- public static void addMinMacLengthAuthorizationIfNecessary(KeymasterArguments args,
- int keymasterAlgorithm,
- int[] keymasterBlockModes,
- int[] keymasterDigests) {
- switch (keymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_AES:
- if (com.android.internal.util.ArrayUtils.contains(
- keymasterBlockModes, KeymasterDefs.KM_MODE_GCM)) {
- // AES GCM key needs the minimum length of AEAD tag specified.
- args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH,
- AndroidKeyStoreAuthenticatedAESCipherSpi.GCM
- .MIN_SUPPORTED_TAG_LENGTH_BITS);
- }
- break;
- case KeymasterDefs.KM_ALGORITHM_HMAC:
- // HMAC key needs the minimum length of MAC set to the output size of the associated
- // digest. This is because we do not offer a way to generate shorter MACs and
- // don't offer a way to verify MACs (other than by generating them).
- if (keymasterDigests.length != 1) {
- throw new ProviderException(
- "Unsupported number of authorized digests for HMAC key: "
- + keymasterDigests.length
- + ". Exactly one digest must be authorized");
- }
- int keymasterDigest = keymasterDigests[0];
- int digestOutputSizeBits = getDigestOutputSizeBits(keymasterDigest);
- if (digestOutputSizeBits == -1) {
- throw new ProviderException(
- "HMAC key authorized for unsupported digest: "
- + KeyProperties.Digest.fromKeymaster(keymasterDigest));
- }
- args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, digestOutputSizeBits);
- break;
- }
- }
-
- private static long getRootSid() {
- long rootSid = GateKeeper.getSecureUserId();
- if (rootSid == 0) {
- throw new IllegalStateException("Secure lock screen must be enabled"
- + " to create keys requiring user authentication");
- }
- return rootSid;
- }
-}
diff --git a/keystore/java/android/security/keystore/SecureKeyImportUnavailableException.java b/keystore/java/android/security/keystore/SecureKeyImportUnavailableException.java
index d1cc572bdaf7..c1842b4e6d1d 100644
--- a/keystore/java/android/security/keystore/SecureKeyImportUnavailableException.java
+++ b/keystore/java/android/security/keystore/SecureKeyImportUnavailableException.java
@@ -16,8 +16,8 @@
package android.security.keystore;
-import android.security.KeyStore;
import android.security.KeyStoreException;
+import android.security.keymaster.KeymasterDefs;
import java.security.ProviderException;
@@ -31,7 +31,7 @@ public class SecureKeyImportUnavailableException extends ProviderException {
}
public SecureKeyImportUnavailableException(String message) {
- super(message, new KeyStoreException(KeyStore.HARDWARE_TYPE_UNAVAILABLE,
+ super(message, new KeyStoreException(KeymasterDefs.KM_ERROR_HARDWARE_TYPE_UNAVAILABLE,
"Secure Key Import not available"));
}
diff --git a/keystore/java/android/security/keystore/StrongBoxUnavailableException.java b/keystore/java/android/security/keystore/StrongBoxUnavailableException.java
index 6c7e9a9521e0..1f4e12edb3bf 100644
--- a/keystore/java/android/security/keystore/StrongBoxUnavailableException.java
+++ b/keystore/java/android/security/keystore/StrongBoxUnavailableException.java
@@ -16,8 +16,8 @@
package android.security.keystore;
-import android.security.KeyStore;
import android.security.KeyStoreException;
+import android.security.keymaster.KeymasterDefs;
import java.security.ProviderException;
@@ -33,7 +33,8 @@ public class StrongBoxUnavailableException extends ProviderException {
public StrongBoxUnavailableException(String message) {
super(message,
- new KeyStoreException(KeyStore.HARDWARE_TYPE_UNAVAILABLE, "No StrongBox available")
+ new KeyStoreException(KeymasterDefs.KM_ERROR_HARDWARE_TYPE_UNAVAILABLE,
+ "No StrongBox available")
);
}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java
index 0f777495a3fe..268b15bfee8c 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java
@@ -21,7 +21,6 @@ import android.security.KeyStoreException;
import android.security.KeyStoreOperation;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyStoreCryptoOperation;
-import android.security.keystore.KeymasterUtils;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java
index 1575bb411562..f1681ec1f7d2 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java
@@ -20,12 +20,10 @@ import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.SecurityLevel;
import android.security.KeyStore2;
import android.security.KeyStoreSecurityLevel;
-import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.ArrayUtils;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
-import android.security.keystore.KeymasterUtils;
import android.security.keystore.StrongBoxUnavailableException;
import android.system.keystore2.Domain;
import android.system.keystore2.IKeystoreSecurityLevel;
@@ -259,7 +257,7 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
// Check that user authentication related parameters are acceptable. This method
// will throw an IllegalStateException if there are issues (e.g., secure lock screen
// not set up).
- KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec);
+ KeyStore2ParameterUtils.addUserAuthArgs(new ArrayList<>(), spec);
} catch (IllegalStateException | IllegalArgumentException e) {
throw new InvalidAlgorithmParameterException(e);
}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index 2d8901a37c05..c26d9f583fd4 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -18,6 +18,7 @@ package android.security.keystore2;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityThread;
import android.content.Context;
import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.KeyPurpose;
@@ -28,7 +29,6 @@ import android.os.RemoteException;
import android.security.GenerateRkpKey;
import android.security.GenerateRkpKeyException;
import android.security.KeyPairGeneratorSpec;
-import android.security.KeyStore;
import android.security.KeyStore2;
import android.security.KeyStoreException;
import android.security.KeyStoreSecurityLevel;
@@ -39,7 +39,6 @@ import android.security.keystore.AttestationUtils;
import android.security.keystore.DeviceIdAttestationException;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
-import android.security.keystore.KeymasterUtils;
import android.security.keystore.SecureKeyImportUnavailableException;
import android.security.keystore.StrongBoxUnavailableException;
import android.system.keystore2.Authorization;
@@ -270,7 +269,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
// Check that user authentication related parameters are acceptable. This method
// will throw an IllegalStateException if there are issues (e.g., secure lock screen
// not set up).
- KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec);
+ KeyStore2ParameterUtils.addUserAuthArgs(new ArrayList<>(), mSpec);
} catch (IllegalArgumentException | IllegalStateException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -572,7 +571,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
AndroidKeyStorePublicKey publicKey =
AndroidKeyStoreProvider.makeAndroidKeyStorePublicKeyFromKeyEntryResponse(
descriptor, metadata, iSecurityLevel, mKeymasterAlgorithm);
- GenerateRkpKey keyGen = new GenerateRkpKey(KeyStore.getApplicationContext());
+ GenerateRkpKey keyGen = new GenerateRkpKey(ActivityThread
+ .currentApplication());
try {
if (mSpec.getAttestationChallenge() != null) {
keyGen.notifyKeyGenerated(securityLevel);
@@ -589,7 +589,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
case KeymasterDefs.KM_ERROR_HARDWARE_TYPE_UNAVAILABLE:
throw new StrongBoxUnavailableException("Failed to generated key pair.", e);
case ResponseCode.OUT_OF_KEYS:
- GenerateRkpKey keyGen = new GenerateRkpKey(KeyStore.getApplicationContext());
+ GenerateRkpKey keyGen = new GenerateRkpKey(ActivityThread
+ .currentApplication());
try {
keyGen.notifyEmpty(securityLevel);
} catch (RemoteException f) {
@@ -665,8 +666,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
if (idTypesSet.contains(AttestationUtils.ID_TYPE_IMEI)
|| idTypesSet.contains(AttestationUtils.ID_TYPE_MEID)) {
telephonyService =
- (TelephonyManager) KeyStore.getApplicationContext().getSystemService(
- Context.TELEPHONY_SERVICE);
+ (TelephonyManager) android.app.AppGlobals.getInitialApplication()
+ .getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyService == null) {
throw new DeviceIdAttestationException("Unable to access telephony service");
}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index ba6d22f681ce..89d2b743a619 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -110,23 +110,6 @@ public class AndroidKeyStoreProvider extends Provider {
putSecretKeyFactoryImpl("HmacSHA512");
}
- private static boolean sInstalled = false;
-
- /**
- * This function indicates whether or not this provider was installed. This is manly used
- * as indicator for
- * {@link android.security.keystore.AndroidKeyStoreProvider#getKeyStoreForUid(int)}
- * to whether or not to retrieve the Keystore provider by "AndroidKeyStoreLegacy".
- * This function can be removed once the transition to Keystore 2.0 is complete.
- * b/171305684
- *
- * @return true if this provider was installed.
- * @hide
- */
- public static boolean isInstalled() {
- return sInstalled;
- }
-
/**
* Installs a new instance of this provider (and the
* {@link AndroidKeyStoreBCWorkaroundProvider}).
@@ -142,7 +125,6 @@ public class AndroidKeyStoreProvider extends Provider {
break;
}
}
- sInstalled = true;
Security.addProvider(new AndroidKeyStoreProvider());
Provider workaroundProvider = new AndroidKeyStoreBCWorkaroundProvider();
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
index 6ff9432905ed..5848247809e7 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
@@ -21,7 +21,6 @@ import android.annotation.Nullable;
import android.hardware.security.keymint.KeyParameter;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyProperties;
-import android.security.keystore.KeymasterUtils;
import android.system.keystore2.Authorization;
import java.security.AlgorithmParameters;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index 32f98a2538f3..3e2fb94f0387 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -30,7 +30,6 @@ import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
-import android.security.keystore.KeymasterUtils;
import android.security.keystore.SecureKeyImportUnavailableException;
import android.security.keystore.WrappedKeyEntry;
import android.system.keystore2.AuthenticatorSpec;
diff --git a/keystore/java/android/security/keystore2/KeymasterUtils.java b/keystore/java/android/security/keystore2/KeymasterUtils.java
new file mode 100644
index 000000000000..de4696cea3ac
--- /dev/null
+++ b/keystore/java/android/security/keystore2/KeymasterUtils.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore2;
+
+import android.security.keymaster.KeymasterArguments;
+import android.security.keymaster.KeymasterDefs;
+import android.security.keystore.KeyProperties;
+
+import java.security.ProviderException;
+
+/**
+ * @hide
+ */
+public abstract class KeymasterUtils {
+
+ private KeymasterUtils() {}
+
+ /** @hide */
+ static int getDigestOutputSizeBits(int keymasterDigest) {
+ switch (keymasterDigest) {
+ case KeymasterDefs.KM_DIGEST_NONE:
+ return -1;
+ case KeymasterDefs.KM_DIGEST_MD5:
+ return 128;
+ case KeymasterDefs.KM_DIGEST_SHA1:
+ return 160;
+ case KeymasterDefs.KM_DIGEST_SHA_2_224:
+ return 224;
+ case KeymasterDefs.KM_DIGEST_SHA_2_256:
+ return 256;
+ case KeymasterDefs.KM_DIGEST_SHA_2_384:
+ return 384;
+ case KeymasterDefs.KM_DIGEST_SHA_2_512:
+ return 512;
+ default:
+ throw new IllegalArgumentException("Unknown digest: " + keymasterDigest);
+ }
+ }
+
+ /** @hide */
+ static boolean isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(
+ int keymasterBlockMode) {
+ switch (keymasterBlockMode) {
+ case KeymasterDefs.KM_MODE_ECB:
+ return false;
+ case KeymasterDefs.KM_MODE_CBC:
+ case KeymasterDefs.KM_MODE_CTR:
+ case KeymasterDefs.KM_MODE_GCM:
+ return true;
+ default:
+ throw new IllegalArgumentException("Unsupported block mode: " + keymasterBlockMode);
+ }
+ }
+
+ /** @hide */
+ static boolean isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto(
+ int keymasterPadding) {
+ switch (keymasterPadding) {
+ case KeymasterDefs.KM_PAD_NONE:
+ return false;
+ case KeymasterDefs.KM_PAD_RSA_OAEP:
+ case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
+ return true;
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported asymmetric encryption padding scheme: " + keymasterPadding);
+ }
+ }
+
+ /**
+ * Adds {@code KM_TAG_MIN_MAC_LENGTH} tag, if necessary, to the keymaster arguments for
+ * generating or importing a key. This tag may only be needed for symmetric keys (e.g., HMAC,
+ * AES-GCM).
+ */
+ public static void addMinMacLengthAuthorizationIfNecessary(KeymasterArguments args,
+ int keymasterAlgorithm,
+ int[] keymasterBlockModes,
+ int[] keymasterDigests) {
+ switch (keymasterAlgorithm) {
+ case KeymasterDefs.KM_ALGORITHM_AES:
+ if (com.android.internal.util.ArrayUtils.contains(
+ keymasterBlockModes, KeymasterDefs.KM_MODE_GCM)) {
+ // AES GCM key needs the minimum length of AEAD tag specified.
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH,
+ AndroidKeyStoreAuthenticatedAESCipherSpi.GCM
+ .MIN_SUPPORTED_TAG_LENGTH_BITS);
+ }
+ break;
+ case KeymasterDefs.KM_ALGORITHM_HMAC:
+ // HMAC key needs the minimum length of MAC set to the output size of the associated
+ // digest. This is because we do not offer a way to generate shorter MACs and
+ // don't offer a way to verify MACs (other than by generating them).
+ if (keymasterDigests.length != 1) {
+ throw new ProviderException(
+ "Unsupported number of authorized digests for HMAC key: "
+ + keymasterDigests.length
+ + ". Exactly one digest must be authorized");
+ }
+ int keymasterDigest = keymasterDigests[0];
+ int digestOutputSizeBits = getDigestOutputSizeBits(keymasterDigest);
+ if (digestOutputSizeBits == -1) {
+ throw new ProviderException(
+ "HMAC key authorized for unsupported digest: "
+ + KeyProperties.Digest.fromKeymaster(keymasterDigest));
+ }
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, digestOutputSizeBits);
+ break;
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 6edaf6fd6c35..4b4310256766 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -18,7 +18,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="pip_phone_close" msgid="5783752637260411309">"סגירה"</string>
- <string name="pip_phone_expand" msgid="2579292903468287504">"הרחב"</string>
+ <string name="pip_phone_expand" msgid="2579292903468287504">"הרחבה"</string>
<string name="pip_phone_settings" msgid="5468987116750491918">"הגדרות"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"תפריט"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> במצב תמונה בתוך תמונה"</string>
@@ -43,12 +43,12 @@
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"עליון 50%"</string>
<string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"למעלה 30%"</string>
<string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"מסך תחתון מלא"</string>
- <string name="one_handed_tutorial_title" msgid="4583241688067426350">"איך להשתמש במצב שימוש ביד אחת"</string>
+ <string name="one_handed_tutorial_title" msgid="4583241688067426350">"איך להשתמש בתכונה \'מצב שימוש ביד אחת\'"</string>
<string name="one_handed_tutorial_description" msgid="3486582858591353067">"כדי לצאת, יש להחליק למעלה מתחתית המסך או להקיש במקום כלשהו במסך מעל האפליקציה"</string>
<string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"הפעלה של מצב שימוש ביד אחת"</string>
<string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"יציאה ממצב שימוש ביד אחת"</string>
<string name="bubbles_settings_button_description" msgid="1301286017420516912">"הגדרות לבועות של <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"גלישה"</string>
+ <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"אפשרויות נוספות"</string>
<string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"הוספה בחזרה לערימה"</string>
<string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> מהאפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
<string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> מ-<xliff:g id="APP_NAME">%2$s</xliff:g> ועוד <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index fcd706f7e732..0601f153b330 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -22,7 +22,7 @@
<string name="pip_phone_settings" msgid="5468987116750491918">"Instellingen"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
<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 schakel je de functie uit."</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>
<string name="pip_pause" msgid="690688849510295232">"Onderbreken"</string>
<string name="pip_skip_to_next" msgid="8403429188794867653">"Doorgaan naar volgende"</string>
@@ -62,7 +62,7 @@
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatten met bubbels"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nieuwe gesprekken worden als zwevende iconen of bubbels getoond. Tik om een bubbel te openen. Sleep om een bubbel te verplaatsen."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Beheer bubbels wanneer je wilt"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tik op Beheren om bubbels van deze app uit te schakelen"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tik op Beheren om bubbels van deze app uit te zetten"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Geen recente bubbels"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recente bubbels en gesloten bubbels zie je hier"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 65f3d3a92476..4cf8ab476865 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -526,6 +526,10 @@ public class PhonePipMenuController implements PipMenuController {
* Handles a pointer event sent from pip input consumer.
*/
void handlePointerEvent(MotionEvent ev) {
+ if (mPipMenuView == null) {
+ return;
+ }
+
if (ev.isTouchEvent()) {
mPipMenuView.dispatchTouchEvent(ev);
} else {
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp
index bd1c154c6c5e..d7162b9872d5 100644
--- a/libs/hwui/effects/StretchEffect.cpp
+++ b/libs/hwui/effects/StretchEffect.cpp
@@ -186,8 +186,8 @@ sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapsho
float normOverScrollDistY = mStretchDirection.y();
float distanceStretchedX = CONTENT_DISTANCE_STRETCHED / (1 + abs(normOverScrollDistX));
float distanceStretchedY = CONTENT_DISTANCE_STRETCHED / (1 + abs(normOverScrollDistY));
- float inverseDistanceStretchedX = 1.f / distanceStretchedX;
- float inverseDistanceStretchedY = 1.f / distanceStretchedY;
+ float inverseDistanceStretchedX = 1.f / CONTENT_DISTANCE_STRETCHED;
+ float inverseDistanceStretchedY = 1.f / CONTENT_DISTANCE_STRETCHED;
float diffX = distanceStretchedX - CONTENT_DISTANCE_STRETCHED;
float diffY = distanceStretchedY - CONTENT_DISTANCE_STRETCHED;
diff --git a/media/java/android/media/IMediaRouterClient.aidl b/media/java/android/media/IMediaRouterClient.aidl
index 53122bb990d6..6b754e157cfb 100644
--- a/media/java/android/media/IMediaRouterClient.aidl
+++ b/media/java/android/media/IMediaRouterClient.aidl
@@ -22,6 +22,6 @@ package android.media;
oneway interface IMediaRouterClient {
void onStateChanged();
void onRestoreRoute();
- void onSelectedRouteChanged(String routeId);
+ void onGroupRouteSelected(String routeId);
void onGlobalA2dpChanged(boolean a2dpOn);
}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index dc43ad342725..480e2eaaf40f 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -122,6 +122,8 @@ public class MediaRouter {
mIsBluetoothA2dpOn = mAudioService.isBluetoothA2dpOn();
} catch (RemoteException e) {
Log.e(TAG, "Error querying Bluetooth A2DP state", e);
+ //TODO: When we reach here, mIsBluetoothA2dpOn may not be synced with
+ // mBluetoothA2dpRoute.
}
mHandler.post(new Runnable() {
@Override public void run() {
@@ -403,18 +405,18 @@ public class MediaRouter {
}
}
- void updateSelectedRouteForId(String routeId) {
- RouteInfo selectedRoute = isBluetoothA2dpOn()
+ void handleGroupRouteSelected(String routeId) {
+ RouteInfo routeToSelect = isBluetoothA2dpOn()
? mBluetoothA2dpRoute : mDefaultAudioVideo;
final int count = mRoutes.size();
for (int i = 0; i < count; i++) {
final RouteInfo route = mRoutes.get(i);
if (TextUtils.equals(route.mGlobalRouteId, routeId)) {
- selectedRoute = route;
+ routeToSelect = route;
}
}
- if (selectedRoute != mSelectedRoute) {
- selectRouteStatic(selectedRoute.mSupportedTypes, selectedRoute, false);
+ if (routeToSelect != mSelectedRoute) {
+ selectRouteStatic(routeToSelect.mSupportedTypes, routeToSelect, /*explicit=*/false);
}
}
@@ -675,10 +677,10 @@ public class MediaRouter {
}
@Override
- public void onSelectedRouteChanged(String routeId) {
+ public void onGroupRouteSelected(String groupRouteId) {
mHandler.post(() -> {
if (Client.this == mClient) {
- updateSelectedRouteForId(routeId);
+ handleGroupRouteSelected(groupRouteId);
}
});
}
@@ -689,9 +691,9 @@ public class MediaRouter {
public void onGlobalA2dpChanged(boolean a2dpOn) {
mHandler.post(() -> {
if (mSelectedRoute == mDefaultAudioVideo && a2dpOn) {
- setSelectedRoute(mBluetoothA2dpRoute, false);
+ setSelectedRoute(mBluetoothA2dpRoute, /*explicit=*/false);
} else if (mSelectedRoute == mBluetoothA2dpRoute && !a2dpOn) {
- setSelectedRoute(mDefaultAudioVideo, false);
+ setSelectedRoute(mDefaultAudioVideo, /*explicit=*/false);
}
});
}
diff --git a/native/android/OWNERS b/native/android/OWNERS
index 6f7def8bc03a..02dfd393a0b7 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -1,3 +1,5 @@
+jreck@google.com
+
per-file libandroid_net.map.txt, net.c = set noparent
per-file libandroid_net.map.txt, net.c = codewiz@google.com, jchalard@google.com, junyulai@google.com
per-file libandroid_net.map.txt, net.c = lorenzo@google.com, reminv@google.com, satk@google.com
@@ -6,3 +8,9 @@ per-file system_fonts.cpp = file:/graphics/java/android/graphics/fonts/OWNERS
per-file native_window_jni.cpp = file:/services/core/java/com/android/server/wm/OWNERS
per-file native_activity.cpp = file:/services/core/java/com/android/server/wm/OWNERS
per-file surface_control.cpp = file:/services/core/java/com/android/server/wm/OWNERS
+
+per-file choreographer.cpp = file:/graphics/java/android/graphics/OWNERS
+per-file hardware_buffer_jni.cpp = file:/graphics/java/android/graphics/OWNERS
+per-file native_window_jni.cpp = file:/graphics/java/android/graphics/OWNERS
+per-file surface_control.cpp = file:/graphics/java/android/graphics/OWNERS
+per-file surface_texture.cpp = file:/graphics/java/android/graphics/OWNERS
diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp
index 609455f27b65..5f5ebf410f21 100644
--- a/packages/Connectivity/framework/Android.bp
+++ b/packages/Connectivity/framework/Android.bp
@@ -23,26 +23,6 @@ package {
default_applicable_licenses: ["frameworks_base_license"],
}
-java_library {
- name: "framework-connectivity-protos",
- sdk_version: "module_current",
- min_sdk_version: "30",
- proto: {
- type: "nano",
- },
- srcs: [
- // TODO: consider moving relevant .proto files directly to the module directory
- ":framework-javastream-protos",
- ],
- apex_available: [
- "com.android.tethering",
- ],
- jarjar_rules: "jarjar-rules-proto.txt",
- visibility: [
- "//visibility:private",
- ],
-}
-
filegroup {
name: "framework-connectivity-internal-sources",
srcs: [
@@ -109,9 +89,6 @@ java_sdk_library {
libs: [
"unsupportedappusage",
],
- static_libs: [
- "framework-connectivity-protos",
- ],
jarjar_rules: "jarjar-rules.txt",
permitted_packages: ["android.net"],
impl_library_visibility: [
@@ -131,14 +108,16 @@ java_sdk_library {
"//packages/modules/Connectivity/Tethering/tests:__subpackages__",
"//packages/modules/Connectivity/tests:__subpackages__",
"//packages/modules/NetworkStack/tests:__subpackages__",
+ "//packages/modules/Wifi/service/tests/wifitests",
],
apex_available: [
"com.android.tethering",
],
}
-cc_defaults {
- name: "libframework-connectivity-defaults",
+cc_library_shared {
+ name: "libframework-connectivity-jni",
+ min_sdk_version: "30",
cflags: [
"-Wall",
"-Werror",
@@ -149,38 +128,19 @@ cc_defaults {
"-Wno-unguarded-availability",
"-Wthread-safety",
],
+ srcs: [
+ "jni/android_net_NetworkUtils.cpp",
+ "jni/onload.cpp",
+ ],
shared_libs: [
+ "libandroid",
"liblog",
"libnativehelper",
],
header_libs: [
"dnsproxyd_protocol_headers",
],
-}
-
-cc_library_static {
- name: "libconnectivityframeworkutils",
- defaults: ["libframework-connectivity-defaults"],
- srcs: [
- "jni/android_net_NetworkUtils.cpp",
- ],
- shared_libs: ["libandroid_net"],
- apex_available: [
- "//apex_available:platform",
- "com.android.tethering",
- ],
-}
-
-cc_library_shared {
- name: "libframework-connectivity-jni",
- min_sdk_version: "30",
- defaults: ["libframework-connectivity-defaults"],
- srcs: [
- "jni/android_net_NetworkUtils.cpp",
- "jni/onload.cpp",
- ],
- shared_libs: ["libandroid"],
- stl: "libc++_static",
+ stl: "none",
apex_available: [
"com.android.tethering",
],
diff --git a/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl b/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl
index 0d70f2a1ed2c..3495efc1f1d0 100644
--- a/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl
+++ b/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl
@@ -18,5 +18,5 @@
package android.net;
// @JavaOnlyStableParcelable only affects the parcelable when built as stable aidl (aidl_interface
-// build rule). IpPrefix is also used in cpp but only as non-stable aidl.
-@JavaOnlyStableParcelable parcelable IpPrefix cpp_header "binder/IpPrefix.h";
+// build rule).
+@JavaOnlyStableParcelable parcelable IpPrefix;
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index 7428c6e70f93..9c77c852e0d6 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -298,7 +298,6 @@ package android.net {
method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
method public int getOwnerUid();
method public int getSignalStrength();
- method @NonNull public java.util.Set<java.lang.Integer> getSubIds();
method @Nullable public android.net.TransportInfo getTransportInfo();
method public boolean hasCapability(int);
method public boolean hasTransport(int);
@@ -410,7 +409,6 @@ package android.net {
method public android.net.NetworkRequest.Builder removeTransportType(int);
method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
- method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
}
public class ParseException extends java.lang.RuntimeException {
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 5613ca1562f7..847bcbcddfb1 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -276,6 +276,7 @@ package android.net {
method @NonNull public int[] getAdministratorUids();
method @Nullable public static String getCapabilityCarrierName(int);
method @Nullable public String getSsid();
+ method @NonNull public java.util.Set<java.lang.Integer> getSubIds();
method @NonNull public int[] getTransportTypes();
method public boolean isPrivateDnsBroken();
method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
@@ -336,6 +337,7 @@ package android.net {
public static class NetworkRequest.Builder {
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
+ method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
}
public final class NetworkScore implements android.os.Parcelable {
diff --git a/packages/Connectivity/framework/jarjar-rules-proto.txt b/packages/Connectivity/framework/jarjar-rules-proto.txt
deleted file mode 100644
index 37b4dec1c331..000000000000
--- a/packages/Connectivity/framework/jarjar-rules-proto.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-keep android.net.NetworkCapabilitiesProto
-keep android.net.NetworkProto
-keep android.net.NetworkRequestProto
diff --git a/packages/Connectivity/framework/jarjar-rules.txt b/packages/Connectivity/framework/jarjar-rules.txt
index 7474c246a2ea..2e5848cb100d 100644
--- a/packages/Connectivity/framework/jarjar-rules.txt
+++ b/packages/Connectivity/framework/jarjar-rules.txt
@@ -1,11 +1,2 @@
rule com.android.net.module.util.** android.net.connectivity.framework.util.@1
rule android.net.NetworkFactory* android.net.connectivity.framework.NetworkFactory@1
-
-# TODO (b/149403767): remove the annotations from net-utils-device-common instead of here
-zap android.annotation.**
-zap com.android.net.module.annotation.**
-zap com.android.internal.annotations.**
-
-rule android.net.NetworkCapabilitiesProto* android.net.connectivity.proto.NetworkCapabilitiesProto@1
-rule android.net.NetworkProto* android.net.connectivity.proto.NetworkProto@1
-rule android.net.NetworkRequestProto* android.net.connectivity.proto.NetworkRequestProto@1
diff --git a/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
index e8bb42df6acc..9bf910b46a4a 100644
--- a/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
+++ b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
@@ -16,34 +16,19 @@
#define LOG_TAG "NetworkUtils"
-#include <vector>
-
#include <android/file_descriptor_jni.h>
#include <android/multinetwork.h>
-#include <arpa/inet.h>
#include <linux/filter.h>
-#include <linux/if_arp.h>
#include <linux/tcp.h>
-#include <net/if.h>
-#include <netinet/ether.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
+#include <netinet/in.h>
+#include <string.h>
#include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS
-#include <cutils/properties.h>
-#include <nativehelper/JNIHelp.h>
#include <nativehelper/JNIPlatformHelp.h>
-#include <nativehelper/ScopedLocalRef.h>
#include <utils/Log.h>
-#include <utils/misc.h>
#include "jni.h"
-extern "C" {
-int ifc_enable(const char *ifname);
-int ifc_disable(const char *ifname);
-}
-
#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
namespace android {
@@ -52,6 +37,9 @@ constexpr int MAXPACKETSIZE = 8 * 1024;
// FrameworkListener limits the size of commands to 4096 bytes.
constexpr int MAXCMDSIZE = 4096;
+static volatile jclass class_Network = 0;
+static volatile jmethodID method_fromNetworkHandle = 0;
+
static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
jclass clazz = env->FindClass(class_name);
LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
@@ -138,11 +126,11 @@ static jobject android_net_utils_resNetworkQuery(JNIEnv *env, jobject thiz, jlon
// Only allow dname which could be simply formatted to UTF8.
// In native layer, res_mkquery would re-format the input char array to packet.
- std::vector<char> queryname(byteCountUTF8 + 1, 0);
-
- env->GetStringUTFRegion(dname, 0, javaCharsCount, queryname.data());
+ char queryname[byteCountUTF8 + 1];
+ memset(queryname, 0, (byteCountUTF8 + 1) * sizeof(char));
- int fd = android_res_nquery(netHandle, queryname.data(), ns_class, ns_type, flags);
+ env->GetStringUTFRegion(dname, 0, javaCharsCount, queryname);
+ int fd = android_res_nquery(netHandle, queryname, ns_class, ns_type, flags);
if (fd < 0) {
jniThrowErrnoException(env, "resNetworkQuery", -fd);
@@ -170,9 +158,9 @@ static jobject android_net_utils_resNetworkSend(JNIEnv *env, jobject thiz, jlong
static jobject android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, jobject javaFd) {
int fd = AFileDescriptor_getFD(env, javaFd);
int rcode;
- std::vector<uint8_t> buf(MAXPACKETSIZE, 0);
+ uint8_t buf[MAXPACKETSIZE] = {0};
- int res = android_res_nresult(fd, &rcode, buf.data(), MAXPACKETSIZE);
+ int res = android_res_nresult(fd, &rcode, buf, MAXPACKETSIZE);
jniSetFileDescriptorOfFD(env, javaFd, -1);
if (res < 0) {
jniThrowErrnoException(env, "resNetworkResult", -res);
@@ -184,8 +172,7 @@ static jobject android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, job
jniThrowErrnoException(env, "resNetworkResult", ENOMEM);
return nullptr;
} else {
- env->SetByteArrayRegion(answer, 0, res,
- reinterpret_cast<jbyte*>(buf.data()));
+ env->SetByteArrayRegion(answer, 0, res, reinterpret_cast<jbyte*>(buf));
}
jclass class_DnsResponse = env->FindClass("android/net/DnsResolver$DnsResponse");
@@ -207,11 +194,14 @@ static jobject android_net_utils_getDnsNetwork(JNIEnv *env, jobject thiz) {
return nullptr;
}
- static jclass class_Network = MakeGlobalRefOrDie(
- env, FindClassOrDie(env, "android/net/Network"));
- static jmethodID method = env->GetStaticMethodID(class_Network, "fromNetworkHandle",
- "(J)Landroid/net/Network;");
- return env->CallStaticObjectMethod(class_Network, method, static_cast<jlong>(dnsNetHandle));
+ if (method_fromNetworkHandle == 0) {
+ // This may be called multiple times concurrently but that is fine
+ class_Network = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/net/Network"));
+ method_fromNetworkHandle = env->GetStaticMethodID(class_Network, "fromNetworkHandle",
+ "(J)Landroid/net/Network;");
+ }
+ return env->CallStaticObjectMethod(class_Network, method_fromNetworkHandle,
+ static_cast<jlong>(dnsNetHandle));
}
static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index 350b47fc6df7..b77d82154625 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -3143,18 +3143,27 @@ public class ConnectivityManager {
}
/**
- * Set a network-independent global http proxy. This is not normally what you want
- * for typical HTTP proxies - they are general network dependent. However if you're
- * doing something unusual like general internal filtering this may be useful. On
- * a private network where the proxy is not accessible, you may break HTTP using this.
+ * Set a network-independent global HTTP proxy.
*
- * @param p A {@link ProxyInfo} object defining the new global
- * HTTP proxy. A {@code null} value will clear the global HTTP proxy.
+ * This sets an HTTP proxy that applies to all networks and overrides any network-specific
+ * proxy. If set, HTTP libraries that are proxy-aware will use this global proxy when
+ * accessing any network, regardless of what the settings for that network are.
+ *
+ * Note that HTTP proxies are by nature typically network-dependent, and setting a global
+ * proxy is likely to break networking on multiple networks. This method is only meant
+ * for device policy clients looking to do general internal filtering or similar use cases.
+ *
+ * {@see #getGlobalProxy}
+ * {@see LinkProperties#getHttpProxy}
+ *
+ * @param p A {@link ProxyInfo} object defining the new global HTTP proxy. Calling this
+ * method with a {@code null} value will clear the global HTTP proxy.
* @hide
*/
+ // Used by Device Policy Manager to set the global proxy.
@SystemApi(client = MODULE_LIBRARIES)
@RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void setGlobalProxy(@Nullable ProxyInfo p) {
+ public void setGlobalProxy(@Nullable final ProxyInfo p) {
try {
mService.setGlobalProxy(p);
} catch (RemoteException e) {
diff --git a/packages/Connectivity/framework/src/android/net/DnsResolver.java b/packages/Connectivity/framework/src/android/net/DnsResolver.java
index 3f7660f5709a..dac88ad90752 100644
--- a/packages/Connectivity/framework/src/android/net/DnsResolver.java
+++ b/packages/Connectivity/framework/src/android/net/DnsResolver.java
@@ -500,7 +500,7 @@ public final class DnsResolver {
try {
resp = resNetworkResult(fd); // Closes fd, marks it invalid.
} catch (ErrnoException e) {
- Log.e(TAG, "resNetworkResult:" + e.toString());
+ Log.w(TAG, "resNetworkResult:" + e.toString());
exception = e;
}
}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index 4f95ccc8816f..a54696fd5d4a 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -2351,9 +2351,15 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Gets the subscription ID set that associated to this network or request.
+ *
+ * <p>Instances of NetworkCapabilities will only have this field populated by the system if the
+ * receiver holds the NETWORK_FACTORY permission. In all other cases, it will be the empty set.
+ *
* @return
+ * @hide
*/
@NonNull
+ @SystemApi
public Set<Integer> getSubIds() {
return new ArraySet<>(mSubIds);
}
@@ -2718,10 +2724,17 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Set the subscription ID set.
*
+ * <p>SubIds are populated in NetworkCapability instances from the system only for callers
+ * that hold the NETWORK_FACTORY permission. Similarly, the system will reject any
+ * NetworkRequests filed with a non-empty set of subIds unless the caller holds the
+ * NETWORK_FACTORY permission.
+ *
* @param subIds a set that represent the subscription IDs. Empty if clean up.
* @return this builder.
+ * @hide
*/
@NonNull
+ @SystemApi
public Builder setSubIds(@NonNull final Set<Integer> subIds) {
mCaps.setSubIds(subIds);
return this;
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index 5313f08fffbe..78e101192467 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -500,9 +500,14 @@ public class NetworkRequest implements Parcelable {
* A network will satisfy this request only if it matches one of the subIds in this set.
* An empty set matches all networks, including those without a subId.
*
+ * <p>Registering a NetworkRequest with a non-empty set of subIds requires the
+ * NETWORK_FACTORY permission.
+ *
* @param subIds A {@code Set} that represents subscription IDs.
+ * @hide
*/
@NonNull
+ @SystemApi
public Builder setSubIds(@NonNull Set<Integer> subIds) {
mNetworkCapabilities.setSubIds(subIds);
return this;
@@ -655,25 +660,6 @@ public class NetworkRequest implements Parcelable {
", " + networkCapabilities.toString() + " ]";
}
- private int typeToProtoEnum(Type t) {
- switch (t) {
- case NONE:
- return NetworkRequestProto.TYPE_NONE;
- case LISTEN:
- return NetworkRequestProto.TYPE_LISTEN;
- case TRACK_DEFAULT:
- return NetworkRequestProto.TYPE_TRACK_DEFAULT;
- case REQUEST:
- return NetworkRequestProto.TYPE_REQUEST;
- case BACKGROUND_REQUEST:
- return NetworkRequestProto.TYPE_BACKGROUND_REQUEST;
- case TRACK_SYSTEM_DEFAULT:
- return NetworkRequestProto.TYPE_TRACK_SYSTEM_DEFAULT;
- default:
- return NetworkRequestProto.TYPE_UNKNOWN;
- }
- }
-
public boolean equals(@Nullable Object obj) {
if (obj instanceof NetworkRequest == false) return false;
NetworkRequest that = (NetworkRequest)obj;
diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml
index 0bca4f4ad643..48cf339bb9d9 100644
--- a/packages/PackageInstaller/res/values-af/strings.xml
+++ b/packages/PackageInstaller/res/values-af/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Pakketinstalleerder"</string>
<string name="install" msgid="711829760615509273">"Installeer"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Dateer op"</string>
<string name="done" msgid="6632441120016885253">"Klaar"</string>
<string name="cancel" msgid="1018267193425558088">"Kanselleer"</string>
<string name="installing" msgid="4921993079741206516">"Installeer tans …"</string>
<string name="installing_app" msgid="1165095864863849422">"Installeer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
<string name="install_done" msgid="5987363587661783896">"Program geïnstalleer."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Wil jy hierdie program installeer?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Wil jy hierdie program opdateer?"</string>
<string name="install_failed" msgid="5777824004474125469">"Program nie geïnstalleer nie."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Die installering van die pakket is geblokkeer."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Program is nie geïnstalleer nie omdat pakket met \'n bestaande pakket bots."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Installeer- en deïnstalleerhandelinge word nie in Wear gesteun nie."</string>
<string name="message_staging" msgid="8032722385658438567">"Voer tans program uit …"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Onbekend"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Jou tablet word vir jou veiligheid tans nie toegelaat om onbekende programme van hierdie bron af te installeer nie. Jy kan dit in Instellings verander."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Jou TV word vir jou veiligheid tans nie toegelaat om onbekende programme van hierdie bron af te installeer nie. Jy kan dit in Instellings verander."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Jou foon word vir jou veiligheid tans nie toegelaat om onbekende programme van hierdie bron af te installeer nie. Jy kan dit in Instellings verander."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Jou foon en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou foon of verlies van data wat uit sy gebruik kan spruit."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Jou tablet en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou tablet of verlies van data wat uit sy gebruik kan spruit."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Jou TV en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou TV of verlies van data wat uit sy gebruik kan spruit."</string>
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
index 17aa400f66b7..99dfc6daab59 100644
--- a/packages/PackageInstaller/res/values-bg/strings.xml
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Пакети: Инстал. програма"</string>
<string name="install" msgid="711829760615509273">"Инсталиране"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Актуализиране"</string>
<string name="done" msgid="6632441120016885253">"Готово"</string>
<string name="cancel" msgid="1018267193425558088">"Отказ"</string>
<string name="installing" msgid="4921993079741206516">"Инсталира се..."</string>
<string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се инсталира…"</string>
<string name="install_done" msgid="5987363587661783896">"Приложението бе инсталирано."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Искате ли да инсталирате това приложение?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Искате ли да актуализирате това приложение?"</string>
<string name="install_failed" msgid="5777824004474125469">"Приложението не бе инсталирано."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирането на пакета бе блокирано."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Приложението не бе инсталирано, тъй като пакетът е в конфликт със съществуващ пакет."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Действията инсталиране и деинсталиране не се поддържат на устройства с Wear."</string>
<string name="message_staging" msgid="8032722385658438567">"Приложението се подготвя…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Неизвестно"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"От съображения за сигурност понастоящем на таблета ви не могат да се инсталират неизвестни приложения от този източник. Можете да промените това от „Настройки“."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"От съображения за сигурност понастоящем на телевизора ви не могат да се инсталират неизвестни приложения от този източник. Можете да промените това от „Настройки“."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"От съображения за сигурност понастоящем на телефона ви не могат да се инсталират неизвестни приложения от този източник. Можете да промените това от „Настройки“."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефонът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на телефона или загуба на информация вследствие на използването на приложението."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблетът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на таблета или загуба на информация вследствие на използването на приложението."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Телевизорът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на телевизора или загуба на информация вследствие на използването на приложението."</string>
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
index 22b85dd61b6d..47bca79d7ef2 100644
--- a/packages/PackageInstaller/res/values-bs/strings.xml
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Alat za instalir. paketa"</string>
<string name="install" msgid="711829760615509273">"Instaliraj"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Ažuriraj"</string>
<string name="done" msgid="6632441120016885253">"Gotovo"</string>
<string name="cancel" msgid="1018267193425558088">"Otkaži"</string>
<string name="installing" msgid="4921993079741206516">"Instaliranje…"</string>
<string name="installing_app" msgid="1165095864863849422">"Instaliranje paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Želite li instalirati ovu aplikaciju?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Želite li ažurirati ovu aplikaciju?"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje ovog paketa je blokirano."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer paket nije usaglašen s postojećim paketom."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Instaliranje/deinstaliranje nije podržano na Wearu."</string>
<string name="message_staging" msgid="8032722385658438567">"Pripremanje aplikacije…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Nepoznato"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Iz sigurnosnih razloga tablet trenutačno nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora. To možete promijeniti u Postavkama."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Iz sigurnosnih razloga televizor trenutačno nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora. To možete promijeniti u Postavkama."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Iz sigurnosnih razloga telefon trenutačno nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora. To možete promijeniti u Postavkama."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Vaši podaci na telefonu i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na telefonu ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Vaši podaci na tabletu i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na tabletu ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Vaši podaci na TV-u i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na TV-u ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml
index 231ada111557..9b711e4ad5a9 100644
--- a/packages/PackageInstaller/res/values-da/strings.xml
+++ b/packages/PackageInstaller/res/values-da/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Pakkeinstallationsprogram"</string>
<string name="install" msgid="711829760615509273">"Installer"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Opdater"</string>
<string name="done" msgid="6632441120016885253">"Udfør"</string>
<string name="cancel" msgid="1018267193425558088">"Annuller"</string>
<string name="installing" msgid="4921993079741206516">"Installerer…"</string>
<string name="installing_app" msgid="1165095864863849422">"Installerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"Appen er installeret."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Vil du installere denne app?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Vil du opdatere denne app?"</string>
<string name="install_failed" msgid="5777824004474125469">"Appen blev ikke installeret."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Pakken blev forhindret i at blive installeret."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Appen blev ikke installeret, da pakken er i strid med en eksisterende pakke."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Det er ikke muligt at installere/afinstallere på Wear."</string>
<string name="message_staging" msgid="8032722385658438567">"Forbereder appen…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Ukendt"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Af hensyn til din sikkerhed har din tablet i øjeblikket ikke tilladelse til at installere ukendte apps fra denne kilde. Du kan ændre dette i Indstillinger."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Af hensyn til din sikkerhed har dit fjernsyn i øjeblikket ikke tilladelse til at installere ukendte apps fra denne kilde. Du kan ændre dette i Indstillinger."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Af hensyn til din sikkerhed har din telefon i øjeblikket ikke tilladelse til at installere ukendte apps fra denne kilde. Du kan ændre dette i Indstillinger."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Din telefon og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på din telefon eller tab af data, der kan skyldes brug af appen."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Din tablet og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på din tablet eller tab af data, der kan skyldes brug af appen."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Dit fjernsyn og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på dit fjernsyn eller tab af data, der kan skyldes brug af appen."</string>
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
index 257f66211adf..9a46fb35bb55 100644
--- a/packages/PackageInstaller/res/values-de/strings.xml
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Paketinstallation"</string>
<string name="install" msgid="711829760615509273">"Installieren"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Aktualisieren"</string>
<string name="done" msgid="6632441120016885253">"Fertig"</string>
<string name="cancel" msgid="1018267193425558088">"Abbrechen"</string>
<string name="installing" msgid="4921993079741206516">"Wird installiert…"</string>
<string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird installiert…"</string>
<string name="install_done" msgid="5987363587661783896">"App wurde installiert."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Möchtest du diese App installieren?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Möchtest du diese App aktualisieren?"</string>
<string name="install_failed" msgid="5777824004474125469">"App wurde nicht installiert."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Die Installation des Pakets wurde blockiert."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Die App wurde nicht installiert, da das Paket in Konflikt mit einem bestehenden Paket steht."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Installations-/Deinstallationsaktion auf Android Wear nicht unterstützt."</string>
<string name="message_staging" msgid="8032722385658438567">"App wird vorbereitet…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Unbekannt"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Aus Sicherheitsgründen kannst du auf deinem Tablet keine unbekannten Apps aus dieser Quelle installieren. Das kannst du in den Einstellungen ändern."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Aus Sicherheitsgründen kannst du auf deinem Fernseher keine unbekannten Apps aus dieser Quelle installieren. Das kannst du in den Einstellungen ändern."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Aus Sicherheitsgründen kannst du auf deinem Smartphone keine unbekannten Apps aus dieser Quelle installieren. Das kannst du in den Einstellungen ändern."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Unbekannte Apps können gefährlich für dein Smartphone und deine personenbezogenen Daten sein. Wenn du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Smartphone und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Unbekannte Apps können gefährlich für dein Tablet und deine personenbezogenen Daten sein. Wenn du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Tablet und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Unbekannte Apps können gefährlich für deinen Fernseher und deine personenbezogenen Daten sein. Wenn du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Fernseher und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml
index 24b0aa78efe8..a91c8826f134 100644
--- a/packages/PackageInstaller/res/values-en-rAU/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Package installer"</string>
<string name="install" msgid="711829760615509273">"Install"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Update"</string>
<string name="done" msgid="6632441120016885253">"Done"</string>
<string name="cancel" msgid="1018267193425558088">"Cancel"</string>
<string name="installing" msgid="4921993079741206516">"Installing…"</string>
<string name="installing_app" msgid="1165095864863849422">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Install/uninstall actions not supported on Wear."</string>
<string name="message_staging" msgid="8032722385658438567">"Staging app…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Unknown"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"For your security, your tablet currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"For your security, your TV currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"For your security, your phone currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml
index 24b0aa78efe8..a91c8826f134 100644
--- a/packages/PackageInstaller/res/values-en-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Package installer"</string>
<string name="install" msgid="711829760615509273">"Install"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Update"</string>
<string name="done" msgid="6632441120016885253">"Done"</string>
<string name="cancel" msgid="1018267193425558088">"Cancel"</string>
<string name="installing" msgid="4921993079741206516">"Installing…"</string>
<string name="installing_app" msgid="1165095864863849422">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Install/uninstall actions not supported on Wear."</string>
<string name="message_staging" msgid="8032722385658438567">"Staging app…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Unknown"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"For your security, your tablet currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"For your security, your TV currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"For your security, your phone currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml
index 24b0aa78efe8..a91c8826f134 100644
--- a/packages/PackageInstaller/res/values-en-rGB/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Package installer"</string>
<string name="install" msgid="711829760615509273">"Install"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Update"</string>
<string name="done" msgid="6632441120016885253">"Done"</string>
<string name="cancel" msgid="1018267193425558088">"Cancel"</string>
<string name="installing" msgid="4921993079741206516">"Installing…"</string>
<string name="installing_app" msgid="1165095864863849422">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Install/uninstall actions not supported on Wear."</string>
<string name="message_staging" msgid="8032722385658438567">"Staging app…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Unknown"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"For your security, your tablet currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"For your security, your TV currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"For your security, your phone currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml
index 24b0aa78efe8..a91c8826f134 100644
--- a/packages/PackageInstaller/res/values-en-rIN/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Package installer"</string>
<string name="install" msgid="711829760615509273">"Install"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Update"</string>
<string name="done" msgid="6632441120016885253">"Done"</string>
<string name="cancel" msgid="1018267193425558088">"Cancel"</string>
<string name="installing" msgid="4921993079741206516">"Installing…"</string>
<string name="installing_app" msgid="1165095864863849422">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Install/uninstall actions not supported on Wear."</string>
<string name="message_staging" msgid="8032722385658438567">"Staging app…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Unknown"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"For your security, your tablet currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"For your security, your TV currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"For your security, your phone currently isn’t allowed to install unknown apps from this source. You can change this in Settings."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml
index 79136ee00a6d..6a7bddc6e030 100644
--- a/packages/PackageInstaller/res/values-en-rXC/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎Package installer‎‏‎‎‏‎"</string>
<string name="install" msgid="711829760615509273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎Install‎‏‎‎‏‎"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎Update‎‏‎‎‏‎"</string>
<string name="done" msgid="6632441120016885253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‎Done‎‏‎‎‏‎"</string>
<string name="cancel" msgid="1018267193425558088">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎Cancel‎‏‎‎‏‎"</string>
<string name="installing" msgid="4921993079741206516">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎Installing…‎‏‎‎‏‎"</string>
<string name="installing_app" msgid="1165095864863849422">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎Installing ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
<string name="install_done" msgid="5987363587661783896">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎App installed.‎‏‎‎‏‎"</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎Do you want to install this app?‎‏‎‎‏‎"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎Do you want to update this app?‎‏‎‎‏‎"</string>
<string name="install_failed" msgid="5777824004474125469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎App not installed.‎‏‎‎‏‎"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎The package was blocked from being installed.‎‏‎‎‏‎"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎App not installed as package conflicts with an existing package.‎‏‎‎‏‎"</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎Install/Uninstall actions not supported on Wear.‎‏‎‎‏‎"</string>
<string name="message_staging" msgid="8032722385658438567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‏‎Staging app…‎‏‎‎‏‎"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎Unknown‎‏‎‎‏‎"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‏‏‏‎For your security, your tablet currently isn’t allowed to install unknown apps from this source. You can change this in Settings.‎‏‎‎‏‎"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎For your security, your TV currently isn’t allowed to install unknown apps from this source. You can change this in Settings.‎‏‎‎‏‎"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎For your security, your phone currently isn’t allowed to install unknown apps from this source. You can change this in Settings.‎‏‎‎‏‎"</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use.‎‏‎‎‏‎"</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use.‎‏‎‎‏‎"</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‎Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use.‎‏‎‎‏‎"</string>
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
index 8144516c10d3..bdacb6459ea1 100644
--- a/packages/PackageInstaller/res/values-es-rUS/strings.xml
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Instalador del paquete"</string>
<string name="install" msgid="711829760615509273">"Instalar"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Actualizar"</string>
<string name="done" msgid="6632441120016885253">"Listo"</string>
<string name="cancel" msgid="1018267193425558088">"Cancelar"</string>
<string name="installing" msgid="4921993079741206516">"Instalando…"</string>
<string name="installing_app" msgid="1165095864863849422">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"Se instaló la app."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"¿Deseas instalar esta app?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"¿Deseas actualizar esta app?"</string>
<string name="install_failed" msgid="5777824004474125469">"No se instaló la app."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Se bloqueó el paquete para impedir la instalación."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"No se instaló la app debido a un conflicto con un paquete."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear no admite las acciones de instalación y desinstalación"</string>
<string name="message_staging" msgid="8032722385658438567">"Preparando app…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Desconocido"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Por tu seguridad, la tablet no tiene permitido actualmente instalar apps desconocidas de esta fuente. Puedes modificar esta opción en Configuración."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Por tu seguridad, la TV no tiene permitido actualmente instalar apps desconocidas de esta fuente. Puedes modificar esta opción en Configuración."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Por tu seguridad, el teléfono no tiene permitido actualmente instalar apps desconocidas de esta fuente. Puedes modificar esta opción en Configuración."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"El teléfono y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra el teléfono y de la pérdida de datos que pueda ocasionar su uso."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"La tablet y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra la tablet y de la pérdida de datos que pueda ocasionar su uso."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"La TV y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra la TV y de la pérdida de datos que pueda ocasionar su uso."</string>
diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml
index 8824a18284da..fbb437ed6be4 100644
--- a/packages/PackageInstaller/res/values-fa/strings.xml
+++ b/packages/PackageInstaller/res/values-fa/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"نصب‌کننده بسته"</string>
<string name="install" msgid="711829760615509273">"نصب"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"به‌روزرسانی"</string>
<string name="done" msgid="6632441120016885253">"تمام"</string>
<string name="cancel" msgid="1018267193425558088">"لغو"</string>
<string name="installing" msgid="4921993079741206516">"درحال نصب…"</string>
<string name="installing_app" msgid="1165095864863849422">"درحال نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"برنامه نصب شد."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"می‌خواهید این برنامه را نصب کنید؟"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"می‌خواهید این برنامه را به‌روزرسانی کنید؟"</string>
<string name="install_failed" msgid="5777824004474125469">"برنامه نصب نشد."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"از نصب شدن بسته جلوگیری شد."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"برنامه نصب نشد چون بسته با بسته موجود تداخل دارد."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"‏کنش‌های نصب/حذف نصب در Wear پشتیبانی نمی‌شود."</string>
<string name="message_staging" msgid="8032722385658438567">"مرحله‌بندی برنامه…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"نامشخص"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"برای امنیت شما، درحال‌حاضر رایانه لوحی‌تان اجازه ندارد برنامه‌های ناشناس را از این منبع نصب کنید. می‌توانید آن را در «تنظیمات» تغییر دهید."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"برای امنیت شما، درحال‌حاضر تلویزیونتان اجازه ندارد برنامه‌های ناشناس را از این منبع نصب کنید. می‌توانید آن را در «تنظیمات» تغییر دهید."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"برای امنیت شما، درحال‌حاضر تلفنتان اجازه ندارد برنامه‌های ناشناس را از این منبع نصب کنید. می‌توانید آن را در «تنظیمات» تغییر دهید."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"تلفن و داده‌های شخصی‌تان دربرابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به تلفن یا از دست رفتن داده‌ای هستید که ممکن است درنتیجه استفاده از آن به وجود آید."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"رایانه لوحی و داده‌های شخصی‌تان دربرابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به رایانه لوحی یا از دست رفتن داده‌ای هستید که ممکن است درنتیجه استفاده از آن به وجود آید."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"تلویزیون و داده‌های شخصی‌تان دربرابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به تلویزیون یا از دست رفتن داده‌ای هستید که ممکن است درنتیجه استفاده از آن به وجود آید."</string>
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
index dc8a93e16033..a11cc2783d67 100644
--- a/packages/PackageInstaller/res/values-hr/strings.xml
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Alat za inst. paketa"</string>
<string name="install" msgid="711829760615509273">"Instaliraj"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Ažuriraj"</string>
<string name="done" msgid="6632441120016885253">"Gotovo"</string>
<string name="cancel" msgid="1018267193425558088">"Otkaži"</string>
<string name="installing" msgid="4921993079741206516">"Instaliranje…"</string>
<string name="installing_app" msgid="1165095864863849422">"Instaliranje paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Želite li instalirati ovu aplikaciju?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Želite li ažurirati ovu aplikaciju?"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa blokirano je."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija koja nije instalirana kao paket u sukobu je s postojećim paketom."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Radnje instaliranja i deinstaliranja nisu podržane na Wearu."</string>
<string name="message_staging" msgid="8032722385658438567">"Postavljanje aplikacije…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Nepoznato"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Iz sigurnosnih razloga tablet trenutačno nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora. To možete promijeniti u Postavkama."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Iz sigurnosnih razloga televizor trenutačno nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora. To možete promijeniti u Postavkama."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Iz sigurnosnih razloga telefon trenutačno nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora. To možete promijeniti u Postavkama."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Vaš telefon i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje telefona ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Vaš tablet i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje tableta ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Vaš TV i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje televizora ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
index 672a39207011..42c3cfe60032 100644
--- a/packages/PackageInstaller/res/values-it/strings.xml
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Installazione pacchetti"</string>
<string name="install" msgid="711829760615509273">"Installa"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Aggiorna"</string>
<string name="done" msgid="6632441120016885253">"Fine"</string>
<string name="cancel" msgid="1018267193425558088">"Annulla"</string>
<string name="installing" msgid="4921993079741206516">"Installazione…"</string>
<string name="installing_app" msgid="1165095864863849422">"Installazione di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"App installata."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Vuoi installare questa app?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Vuoi aggiornare questa app?"</string>
<string name="install_failed" msgid="5777824004474125469">"App non installata."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"È stata bloccata l\'installazione del pacchetto."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App non installata poiché il pacchetto è in conflitto con un pacchetto esistente."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Le azioni di installazione/disinstallazione non sono supportate su Wear."</string>
<string name="message_staging" msgid="8032722385658438567">"App in preparazione…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Sconosciuto"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Per motivi di sicurezza, il tuo tablet non è attualmente autorizzato a installare app sconosciute da questa origine. Puoi modificare questa opzione nelle Impostazioni."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Per motivi di sicurezza, la tua TV non è attualmente autorizzata a installare app sconosciute da questa origine. Puoi modificare questa opzione nelle Impostazioni."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Per motivi di sicurezza, il tuo telefono non è attualmente autorizzato a installare app sconosciute da questa origine. Puoi modificare questa opzione nelle Impostazioni."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"I dati del telefono e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni al telefono o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"I dati del tablet e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni al tablet o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"I dati della TV e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni alla TV o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml
index 430e25fcb95b..868c1a624043 100644
--- a/packages/PackageInstaller/res/values-iw/strings.xml
+++ b/packages/PackageInstaller/res/values-iw/strings.xml
@@ -32,7 +32,7 @@
<string name="install_failed" msgid="5777824004474125469">"האפליקציה לא הותקנה."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"החבילה נחסמה להתקנה."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"האפליקציה לא הותקנה כי החבילה מתנגשת עם חבילה קיימת."</string>
- <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטאבלט."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"האפליקציה לא הותקנה כי היא אינה תואמת לטאבלט."</string>
<string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"האפליקציה הזו לא תואמת לטלוויזיה שלך."</string>
<string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"האפליקציה לא הותקנה כי היא לא תואמת לטלפון."</string>
<string name="install_failed_invalid_apk" msgid="8581007676422623930">"האפליקציה לא הותקנה כי נראה שהחבילה לא תקפה."</string>
@@ -56,7 +56,7 @@
<string name="uninstall_application_title" msgid="4045420072401428123">"הסרת התקנה של האפליקציה"</string>
<string name="uninstall_update_title" msgid="824411791011583031">"הסרת התקנה של עדכון"</string>
<string name="uninstall_activity_text" msgid="1928194674397770771">"הפעילות <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> היא חלק מהאפליקציה הבאה:"</string>
- <string name="uninstall_application_text" msgid="3816830743706143980">"האם ברצונך להסיר את ההתקנה של אפליקציה זו?"</string>
+ <string name="uninstall_application_text" msgid="3816830743706143980">"להסיר את ההתקנה של האפליקציה הזו?"</string>
<string name="uninstall_application_text_all_users" msgid="575491774380227119">"להסיר את האפליקציה הזו עבור "<b>"כל"</b>" המשתמשים? האפליקציה והנתונים שלה יוסרו עבור "<b>"כל"</b>" המשתמשים במכשיר."</string>
<string name="uninstall_application_text_user" msgid="498072714173920526">"להסיר את ההתקנה של האפליקציה הזו עבור <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
<string name="uninstall_update_text" msgid="863648314632448705">"להחליף את האפליקציה הזאת בגרסת היצרן? כל הנתונים יוסרו."</string>
@@ -72,16 +72,16 @@
<string name="uninstall_failed_app" msgid="5506028705017601412">"לא ניתן היה להסיר את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
<string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"לא ניתן להסיר את ההתקנה של אפליקציה פעילה של מנהל המכשיר"</string>
<string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"לא ניתן להסיר את ההתקנה של אפליקציה פעילה של מנהל המכשיר של <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
- <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"אפליקציה זו נדרשת לחלק מהמשתמשים או מהפרופילים והתקנתה הוסרה למשתמשים אחרים"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"האפליקציה הזו נדרשת עבור חלק מהמשתמשים או הפרופילים, וההתקנה שלה הוסרה עבור משתמשים אחרים"</string>
<string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"האפליקציה הזו נחוצה לפרופיל שלך ולא ניתן להסיר את ההתקנה שלה."</string>
- <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"מנהל המכשיר שלך מחייב את קיומה של אפליקציה זו, ולא ניתן להסירה."</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="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>
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"‏פעולות התקנה/הסרת התקנה אינן נתמכות ב-Wear."</string>
- <string name="message_staging" msgid="8032722385658438567">"מכין אפליקציה להתקנה…"</string>
+ <string name="message_staging" msgid="8032722385658438567">"בתהליך הכנת האפליקציה להתקנה…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"לא ידוע"</string>
<!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
<skip />
@@ -90,12 +90,12 @@
<!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
<skip />
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"נתוני הטלפון והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. התקנת האפליקציה הזו מהווה את הסכמתך לכך שהאחריות הבלעדית היא שלך במקרה של אובדן נתונים או גרימת נזק לטלפון שלך בעקבות השימוש באפליקציה."</string>
- <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"נתוני הטאבלט והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטאבלט שלך בעקבות השימוש באפליקציה."</string>
- <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"נתוני הטלוויזיה והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטלוויזיה שלך בעקבות השימוש באפליקציה."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"נתוני הטאבלט והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. התקנת האפליקציה הזו מהווה את הסכמתך לכך שהאחריות הבלעדית היא שלך במקרה של אובדן נתונים או גרימת נזק לטאבלט בעקבות השימוש באפליקציה."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"נתוני הטלוויזיה והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. התקנת האפליקציה הזו מהווה את הסכמתך לכך שהאחריות הבלעדית היא שלך במקרה של אובדן נתונים או גרימת נזק לטלוויזיה שלך בעקבות השימוש באפליקציה."</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"המשך"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"הגדרות"</string>
- <string name="wear_app_channel" msgid="1960809674709107850">"‏מתקין/מסיר התקנה של אפליקציות Wear"</string>
+ <string name="wear_app_channel" msgid="1960809674709107850">"‏תהליך התקנה/הסרת התקנה של אפליקציות Wear"</string>
<string name="app_installed_notification_channel_description" msgid="2695385797601574123">"התראה על התקנת האפליקציה"</string>
<string name="notification_installation_success_message" msgid="6450467996056038442">"הותקנה בהצלחה"</string>
- <string name="notification_installation_success_status" msgid="3172502643504323321">"האפליקציה \"<xliff:g id="APPNAME">%1$s</xliff:g>\" הותקנה בהצלחה"</string>
+ <string name="notification_installation_success_status" msgid="3172502643504323321">"האפליקציה \"<xliff:g id="APPNAME">%1$s</xliff:g>\" הותקנה"</string>
</resources>
diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml
index 2bda646a00cc..f86afea47882 100644
--- a/packages/PackageInstaller/res/values-tr/strings.xml
+++ b/packages/PackageInstaller/res/values-tr/strings.xml
@@ -18,17 +18,14 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Paket yükleyici"</string>
<string name="install" msgid="711829760615509273">"Yükle"</string>
- <!-- no translation found for update (3932142540719227615) -->
- <skip />
+ <string name="update" msgid="3932142540719227615">"Güncelle"</string>
<string name="done" msgid="6632441120016885253">"Bitti"</string>
<string name="cancel" msgid="1018267193425558088">"İptal"</string>
<string name="installing" msgid="4921993079741206516">"Yükleniyor…"</string>
<string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> yükleniyor…"</string>
<string name="install_done" msgid="5987363587661783896">"Uygulama yüklendi."</string>
- <!-- no translation found for install_confirm_question (7663733664476363311) -->
- <skip />
- <!-- no translation found for install_confirm_question_update (3348888852318388584) -->
- <skip />
+ <string name="install_confirm_question" msgid="7663733664476363311">"Bu uygulamayı yüklemek istiyor musunuz?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Bu uygulamayı güncellemek istiyor musunuz?"</string>
<string name="install_failed" msgid="5777824004474125469">"Uygulama yüklenmedi."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketin yüklemesi engellendi."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Paket, mevcut bir paketle çakıştığından uygulama yüklenemedi."</string>
@@ -83,12 +80,9 @@
<string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Yükleme/Yüklemeyi kaldırma işlemleri Wear\'da desteklenmiyor."</string>
<string name="message_staging" msgid="8032722385658438567">"Uygulama hazırlanıyor…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Bilinmiyor"</string>
- <!-- no translation found for untrusted_external_source_warning (7067510047443133095) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (7057271609532508035) -->
- <skip />
- <!-- no translation found for untrusted_external_source_warning (8444191224459138919) -->
- <skip />
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Güvenlik nedeniyle şu anda tabletinizin bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmemektedir. Bunu Ayarlar\'da değiştirebilirsiniz."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Güvenlik nedeniyle şu anda TV\'nizin bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmemektedir. Bunu Ayarlar\'da değiştirebilirsiniz."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Güvenlik nedeniyle şu anda telefonunuzun bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmemektedir. Bunu Ayarlar\'da değiştirebilirsiniz."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonunuz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı telefonunuzda oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletiniz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı tabletinizde oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV\'niz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı TV\'nizde oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
index 705d3f4bdf87..38c06dd48b85 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
@@ -41,6 +41,15 @@ import java.util.List;
public class InstallSuccess extends AlertActivity {
private static final String LOG_TAG = InstallSuccess.class.getSimpleName();
+ @Nullable
+ private PackageUtil.AppSnippet mAppSnippet;
+
+ @Nullable
+ private String mAppPackageName;
+
+ @Nullable
+ private Intent mLaunchIntent;
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -55,59 +64,73 @@ public class InstallSuccess extends AlertActivity {
Intent intent = getIntent();
ApplicationInfo appInfo =
intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
+ mAppPackageName = appInfo.packageName;
Uri packageURI = intent.getData();
// Set header icon and title
- PackageUtil.AppSnippet as;
PackageManager pm = getPackageManager();
if ("package".equals(packageURI.getScheme())) {
- as = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo),
+ mAppSnippet = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo),
pm.getApplicationIcon(appInfo));
} else {
File sourceFile = new File(packageURI.getPath());
- as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
+ mAppSnippet = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
}
- mAlert.setIcon(as.icon);
- mAlert.setTitle(as.label);
- mAlert.setView(R.layout.install_content_view);
- mAlert.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.launch), null,
- null);
- mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.done),
- (ignored, ignored2) -> {
- if (appInfo.packageName != null) {
- Log.i(LOG_TAG, "Finished installing " + appInfo.packageName);
- }
- finish();
- }, null);
- setupAlert();
- requireViewById(R.id.install_success).setVisibility(View.VISIBLE);
- // Enable or disable "launch" button
- Intent launchIntent = getPackageManager().getLaunchIntentForPackage(
- appInfo.packageName);
- boolean enabled = false;
- if (launchIntent != null) {
- List<ResolveInfo> list = getPackageManager().queryIntentActivities(launchIntent,
- 0);
- if (list != null && list.size() > 0) {
- enabled = true;
- }
- }
+ mLaunchIntent = getPackageManager().getLaunchIntentForPackage(mAppPackageName);
+
+ bindUi();
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ bindUi();
+ }
- Button launchButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
- if (enabled) {
- launchButton.setOnClickListener(view -> {
- try {
- startActivity(launchIntent);
- } catch (ActivityNotFoundException | SecurityException e) {
- Log.e(LOG_TAG, "Could not start activity", e);
+ private void bindUi() {
+ if (mAppSnippet == null) {
+ return;
+ }
+
+ mAlert.setIcon(mAppSnippet.icon);
+ mAlert.setTitle(mAppSnippet.label);
+ mAlert.setView(R.layout.install_content_view);
+ mAlert.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.launch), null,
+ null);
+ mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.done),
+ (ignored, ignored2) -> {
+ if (mAppPackageName != null) {
+ Log.i(LOG_TAG, "Finished installing " + mAppPackageName);
}
finish();
- });
- } else {
- launchButton.setEnabled(false);
+ }, null);
+ setupAlert();
+ requireViewById(R.id.install_success).setVisibility(View.VISIBLE);
+ // Enable or disable "launch" button
+ boolean enabled = false;
+ if (mLaunchIntent != null) {
+ List<ResolveInfo> list = getPackageManager().queryIntentActivities(mLaunchIntent,
+ 0);
+ if (list != null && list.size() > 0) {
+ enabled = true;
}
}
+
+ Button launchButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
+ if (enabled) {
+ launchButton.setOnClickListener(view -> {
+ try {
+ startActivity(mLaunchIntent);
+ } catch (ActivityNotFoundException | SecurityException e) {
+ Log.e(LOG_TAG, "Could not start activity", e);
+ }
+ finish();
+ });
+ } else {
+ launchButton.setEnabled(false);
+ }
}
}
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
index 18502334610d..2ed8b7f1b0c5 100644
--- a/packages/PrintSpooler/res/values-iw/strings.xml
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -28,13 +28,13 @@
<string name="label_orientation" msgid="2853142581990496477">"כיוון"</string>
<string name="label_pages" msgid="7768589729282182230">"עמודים"</string>
<string name="destination_default_text" msgid="5422708056807065710">"בחירת מדפסת"</string>
- <string name="template_all_pages" msgid="3322235982020148762">"הכל <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"כל <xliff:g id="PAGE_COUNT">%1$s</xliff:g> הדפים"</string>
<string name="template_page_range" msgid="428638530038286328">"טווח של <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"למשל 1–5‏,8,‏11–13"</string>
<string name="print_preview" msgid="8010217796057763343">"תצוגה מקדימה של הדפסה"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"‏התקנה של PDF viewer‏ ליצירת תצוגה מקדימה"</string>
<string name="printing_app_crashed" msgid="854477616686566398">"אפליקציית ההדפסה קרסה"</string>
- <string name="generating_print_job" msgid="3119608742651698916">"יוצר עבודת הדפסה"</string>
+ <string name="generating_print_job" msgid="3119608742651698916">"בתהליך יצירה של עבודת הדפסה"</string>
<string name="save_as_pdf" msgid="5718454119847596853">"‏שמירה כ-PDF"</string>
<string name="all_printers" msgid="5018829726861876202">"כל המדפסות…"</string>
<string name="print_dialog" msgid="32628687461331979">"תיבת דו שיח של מדפסת"</string>
@@ -42,8 +42,8 @@
<string name="page_description_template" msgid="6831239682256197161">"עמוד <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> מתוך <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
<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="collapse_handle" msgid="6886637989442507451">"נקודת אחיזה לכיווץ"</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>
@@ -52,9 +52,9 @@
<string name="add_print_service_label" msgid="5356702546188981940">"הוספת שירות"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"תיבת החיפוש מוצגת"</string>
<string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"תיבת החיפוש מוסתרת"</string>
- <string name="print_add_printer" msgid="1088656468360653455">"הוסף מדפסת"</string>
- <string name="print_select_printer" msgid="7388760939873368698">"בחר מדפסת"</string>
- <string name="print_forget_printer" msgid="5035287497291910766">"שכח את המדפסת"</string>
+ <string name="print_add_printer" msgid="1088656468360653455">"הוספת מדפסת"</string>
+ <string name="print_select_printer" msgid="7388760939873368698">"בחירת מדפסת"</string>
+ <string name="print_forget_printer" msgid="5035287497291910766">"לשכוח את המדפסת"</string>
<plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
<item quantity="two">נמצאו <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item>
<item quantity="many">נמצאו <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item>
@@ -62,28 +62,28 @@
<item quantity="one">נמצאה מדפסת <xliff:g id="COUNT_0">%1$s</xliff:g></item>
</plurals>
<string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="printer_info_desc" msgid="7181988788991581654">"מידע נוסף על מדפסת זו"</string>
+ <string name="printer_info_desc" msgid="7181988788991581654">"מידע נוסף על המדפסת הזו"</string>
<string name="notification_channel_progress" msgid="872788690775721436">"עבודות הדפסה פועלות"</string>
<string name="notification_channel_failure" msgid="9042250774797916414">"עבודות הדפסה שנכשלו"</string>
<string name="could_not_create_file" msgid="3425025039427448443">"לא ניתן היה ליצור קובץ"</string>
<string name="print_services_disabled_toast" msgid="9089060734685174685">"שירותי הדפסה מסוימים מושבתים"</string>
- <string name="print_searching_for_printers" msgid="6550424555079932867">"מחפש מדפסות"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"המערכת מחפשת מדפסות"</string>
<string name="print_no_print_services" msgid="8561247706423327966">"לא הופעלו שירותי הדפסה"</string>
<string name="print_no_printers" msgid="4869403323900054866">"לא נמצאו מדפסות"</string>
<string name="cannot_add_printer" msgid="7840348733668023106">"לא ניתן להוסיף מדפסות"</string>
- <string name="select_to_add_printers" msgid="3800709038689830974">"בחר כדי להוסיף מדפסת"</string>
+ <string name="select_to_add_printers" msgid="3800709038689830974">"יש להקיש כדי להוסיף מדפסת"</string>
<string name="enable_print_service" msgid="3482815747043533842">"צריך לבחור כדי להפעיל"</string>
<string name="enabled_services_title" msgid="7036986099096582296">"שירותים מופעלים"</string>
<string name="recommended_services_title" msgid="3799434882937956924">"שירותים מומלצים"</string>
<string name="disabled_services_title" msgid="7313253167968363211">"שירותים מושבתים"</string>
<string name="all_services_title" msgid="5578662754874906455">"כל השירותים"</string>
<plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
- <item quantity="two">התקן כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item>
- <item quantity="many">התקן כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item>
- <item quantity="other">התקן כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item>
- <item quantity="one">התקן כדי לגלות מדפסת <xliff:g id="COUNT_0">%1$s</xliff:g></item>
+ <item quantity="two">יש להתקין כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item>
+ <item quantity="many">יש להתקין כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item>
+ <item quantity="other">יש להתקין כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item>
+ <item quantity="one">יש להתקין כדי לגלות מדפסת אחת (<xliff:g id="COUNT_0">%1$s</xliff:g>)‏</item>
</plurals>
- <string name="printing_notification_title_template" msgid="295903957762447362">"מדפיס את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="printing_notification_title_template" msgid="295903957762447362">"בתהליך הדפסה של <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="cancelling_notification_title_template" msgid="1821759594704703197">"המערכת מבטלת את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="failed_notification_title_template" msgid="2256217208186530973">"שגיאת מדפסת ב-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="blocked_notification_title_template" msgid="1175435827331588646">"המדפסת חסמה את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -108,8 +108,8 @@
</string-array>
<string name="print_write_error_message" msgid="5787642615179572543">"לא ניתן היה לכתוב לקובץ"</string>
<string name="print_error_default_message" msgid="8602678405502922346">"מצטערים, הפעולה לא בוצעה. אפשר לנסות שוב."</string>
- <string name="print_error_retry" msgid="1426421728784259538">"כדאי לנסות שוב"</string>
- <string name="print_error_printer_unavailable" msgid="8985614415253203381">"המדפסת הזו אינה זמינה כעת."</string>
+ <string name="print_error_retry" msgid="1426421728784259538">"ניסיון נוסף"</string>
+ <string name="print_error_printer_unavailable" msgid="8985614415253203381">"המדפסת הזו לא זמינה כרגע."</string>
<string name="print_cannot_load_page" msgid="6179560924492912009">"לא ניתן להציג תצוגה מקדימה"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"בתהליך יצירת תצוגה מקדימה…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ml/strings.xml b/packages/PrintSpooler/res/values-ml/strings.xml
new file mode 100644
index 000000000000..73af95d2e117
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ml/strings.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="4469836075319831821">"Print Spooler"</string>
+ <string name="more_options_button" msgid="2243228396432556771">"കൂടുതൽ ഓപ്‌ഷനുകൾ"</string>
+ <string name="label_destination" msgid="9132510997381599275">"ലക്ഷ്യസ്ഥാനം"</string>
+ <string name="label_copies" msgid="3634531042822968308">"പകർപ്പുകൾ"</string>
+ <string name="label_copies_summary" msgid="3861966063536529540">"പകർപ്പുകൾ:"</string>
+ <string name="label_paper_size" msgid="908654383827777759">"പേപ്പർ വലുപ്പം"</string>
+ <string name="label_paper_size_summary" msgid="5668204981332138168">"പേപ്പർ വലുപ്പം:"</string>
+ <string name="label_color" msgid="1108690305218188969">"നിറം"</string>
+ <string name="label_duplex" msgid="5370037254347072243">"രണ്ട് വശങ്ങളുള്ളത്"</string>
+ <string name="label_orientation" msgid="2853142581990496477">"ഓറിയന്‍റേഷന്‍‌"</string>
+ <string name="label_pages" msgid="7768589729282182230">"പേജുകൾ"</string>
+ <string name="destination_default_text" msgid="5422708056807065710">"ഒരു പ്രിന്റർ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"എല്ലാ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> എന്നതിന്റെ പരിധി"</string>
+ <string name="pages_range_example" msgid="8558694453556945172">"ഉദാ. 1—5,8,11—13"</string>
+ <string name="print_preview" msgid="8010217796057763343">"പ്രിന്റ് പ്രിവ്യൂ"</string>
+ <string name="install_for_print_preview" msgid="6366303997385509332">"പ്രിവ്യൂ കാണിക്കുന്നതിന് PDF വ്യൂവർ ഇൻസ്റ്റാൾ ചെയ്യുക"</string>
+ <string name="printing_app_crashed" msgid="854477616686566398">"പ്രിന്റുചെയ്യൽ അപ്ലിക്കേഷൻ ക്രാഷായി"</string>
+ <string name="generating_print_job" msgid="3119608742651698916">"പ്രിന്റ് ജോലി സൃഷ്‌ടിക്കുന്നു"</string>
+ <string name="save_as_pdf" msgid="5718454119847596853">"PDF-ആയി സംരക്ഷിക്കൂ"</string>
+ <string name="all_printers" msgid="5018829726861876202">"എല്ലാ പ്രിന്ററുകളും..."</string>
+ <string name="print_dialog" msgid="32628687461331979">"പ്രിന്റ് സംഭാഷണം"</string>
+ <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> / <xliff:g id="PAGE_COUNT">%2$d</xliff:g> പേജ്"</string>
+ <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="savetopdf_button" msgid="2976186791686924743">"PDF-ൽ സംരക്ഷിക്കുക"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്‌ഷനുകൾ വിപുലീകരിച്ചു"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്‌ഷനുകൾ ചുരുക്കി"</string>
+ <string name="search" msgid="5421724265322228497">"Search"</string>
+ <string name="all_printers_label" msgid="3178848870161526399">"എല്ലാ പ്രിന്ററുകളും"</string>
+ <string name="add_print_service_label" msgid="5356702546188981940">"സേവനം ചേർക്കുക"</string>
+ <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"തിരയൽ ബോക്‌സ് ദൃശ്യമാക്കിയിരിക്കുന്നു"</string>
+ <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"തിരയൽ ബോക്‌സ് മറച്ചിരിക്കുന്നു"</string>
+ <string name="print_add_printer" msgid="1088656468360653455">"പ്രിന്റർ ചേർക്കുക"</string>
+ <string name="print_select_printer" msgid="7388760939873368698">"പ്രിന്റർ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="print_forget_printer" msgid="5035287497291910766">"പ്രിന്റർ മറന്നു"</string>
+ <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> പ്രിന്ററുകൾ കണ്ടെത്തി</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> പ്രിന്റർ കണ്ടെത്തി</item>
+ </plurals>
+ <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
+ <string name="printer_info_desc" msgid="7181988788991581654">"ഈ പ്രിന്ററിനെ കുറിച്ചുള്ള കൂടുതൽ വിവരങ്ങൾ"</string>
+ <string name="notification_channel_progress" msgid="872788690775721436">"നടന്നുകൊണ്ടിരിക്കുന്ന പ്രിന്റ് ജോലികൾ"</string>
+ <string name="notification_channel_failure" msgid="9042250774797916414">"പരാജയപ്പെട്ട പ്രിന്റ് ജോലികൾ"</string>
+ <string name="could_not_create_file" msgid="3425025039427448443">"ഫയൽ സൃഷ്ടിക്കാൻ കഴിഞ്ഞില്ല"</string>
+ <string name="print_services_disabled_toast" msgid="9089060734685174685">"ചില പ്രിന്റ് സേവനങ്ങൾ പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"പ്രിന്ററുകൾക്കായി തിരയുന്നു"</string>
+ <string name="print_no_print_services" msgid="8561247706423327966">"പ്രിന്റ് സേവനങ്ങളൊന്നും പ്രവർത്തനക്ഷമാക്കിയിട്ടില്ല"</string>
+ <string name="print_no_printers" msgid="4869403323900054866">"പ്രിന്ററുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
+ <string name="cannot_add_printer" msgid="7840348733668023106">"പ്രിന്ററുകൾ ചേർക്കാൻ കഴിയില്ല"</string>
+ <string name="select_to_add_printers" msgid="3800709038689830974">"പ്രിന്റർ ചേർക്കാൻ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="enable_print_service" msgid="3482815747043533842">"പ്രവർത്തനക്ഷമമാക്കാൻ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="enabled_services_title" msgid="7036986099096582296">"പ്രവർത്തനക്ഷമമാക്കിയ സേവനങ്ങൾ"</string>
+ <string name="recommended_services_title" msgid="3799434882937956924">"ശുപാർശ ചെയ്യപ്പെടുന്ന സേവനങ്ങൾ"</string>
+ <string name="disabled_services_title" msgid="7313253167968363211">"പ്രവർത്തനരഹിതമാക്കിയ സേവനങ്ങൾ"</string>
+ <string name="all_services_title" msgid="5578662754874906455">"എല്ലാ സേവനങ്ങളും"</string>
+ <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> പ്രിന്ററുകൾ കണ്ടെത്തുന്നതിന് ഇൻസ്റ്റാൾ ചെയ്യുക</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> പ്രിന്റർ കണ്ടെത്തുന്നതിന് ഇൻസ്റ്റാൾ ചെയ്യുക</item>
+ </plurals>
+ <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> പ്രിന്റുചെയ്യുന്നു"</string>
+ <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> റദ്ദാക്കുന്നു"</string>
+ <string name="failed_notification_title_template" msgid="2256217208186530973">"പ്രിന്റർ പിശക് <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="blocked_notification_title_template" msgid="1175435827331588646">"പ്രിന്റർ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> തടഞ്ഞു"</string>
+ <string name="cancel" msgid="4373674107267141885">"റദ്ദാക്കുക"</string>
+ <string name="restart" msgid="2472034227037808749">"പുനരാരംഭിക്കുക"</string>
+ <string name="no_connection_to_printer" msgid="2159246915977282728">"പ്രിന്ററിൽ കണക്ഷനൊന്നുമില്ല"</string>
+ <string name="reason_unknown" msgid="5507940196503246139">"അജ്ഞാതം"</string>
+ <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ഉപയോഗിക്കണോ?"</string>
+ <string name="print_service_security_warning_summary" msgid="1427434625361692006">"നിങ്ങളുടെ പ്രമാണം പ്രിന്ററിലേക്ക് പോകുന്നതിനിടെ അത് ഒന്നോ അതിലധികമോ സെർവറുകളിലൂടെ കടന്നുപോകാനിടയുണ്ട്."</string>
+ <string-array name="color_mode_labels">
+ <item msgid="7602948745415174937">"കറുപ്പ് &amp; വെള്ള"</item>
+ <item msgid="2762241247228983754">"നിറം"</item>
+ </string-array>
+ <string-array name="duplex_mode_labels">
+ <item msgid="3882302912790928315">"ഒന്നുമില്ല"</item>
+ <item msgid="7296563835355641719">"നീളമുള്ള അരിക്"</item>
+ <item msgid="79513688117503758">"ഹ്രസ്വ അരിക്"</item>
+ </string-array>
+ <string-array name="orientation_labels">
+ <item msgid="4061931020926489228">"പോർട്രെയ്‌റ്റ്"</item>
+ <item msgid="3199660090246166812">"ലാൻഡ്‌സ്‌കേപ്പ്"</item>
+ </string-array>
+ <string name="print_write_error_message" msgid="5787642615179572543">"ഫയലിൽ റൈറ്റുചെയ്യാനായില്ല"</string>
+ <string name="print_error_default_message" msgid="8602678405502922346">"ക്ഷമിക്കണം, അത് പ്രവർത്തിച്ചില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
+ <string name="print_error_retry" msgid="1426421728784259538">"വീണ്ടും ശ്രമിക്കുക"</string>
+ <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ഈ പ്രിന്ററർ ഇപ്പോൾ ലഭ്യമല്ല."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"പ്രിവ്യൂ കാണിക്കാൻ കഴിയില്ല"</string>
+ <string name="print_preparing_preview" msgid="3939930735671364712">"പ്രിവ്യൂ തയ്യാറാക്കുന്നു…"</string>
+</resources>
diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml
index 79cb1ae3d3de..7b526bb5193c 100644
--- a/packages/PrintSpooler/res/values-nl/strings.xml
+++ b/packages/PrintSpooler/res/values-nl/strings.xml
@@ -70,10 +70,10 @@
<string name="print_no_printers" msgid="4869403323900054866">"Geen printers gevonden"</string>
<string name="cannot_add_printer" msgid="7840348733668023106">"Kan geen printers toevoegen"</string>
<string name="select_to_add_printers" msgid="3800709038689830974">"Selecteer om printer toe te voegen"</string>
- <string name="enable_print_service" msgid="3482815747043533842">"Selecteer om in te schakelen"</string>
- <string name="enabled_services_title" msgid="7036986099096582296">"Ingeschakelde services"</string>
+ <string name="enable_print_service" msgid="3482815747043533842">"Selecteer om aan te zetten"</string>
+ <string name="enabled_services_title" msgid="7036986099096582296">"Aangezette services"</string>
<string name="recommended_services_title" msgid="3799434882937956924">"Aanbevolen services"</string>
- <string name="disabled_services_title" msgid="7313253167968363211">"Uitgeschakelde services"</string>
+ <string name="disabled_services_title" msgid="7313253167968363211">"Uitgezette services"</string>
<string name="all_services_title" msgid="5578662754874906455">"Alle services"</string>
<plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
<item quantity="other">Installeren om <xliff:g id="COUNT_1">%1$s</xliff:g> printers te vinden</item>
diff --git a/packages/SettingsLib/SettingsTheme/res/layout/image_frame.xml b/packages/SettingsLib/SettingsTheme/res/layout/settings_icon.xml
index 55677908b684..55677908b684 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout/image_frame.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout/settings_icon.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/layout/settings_preference.xml b/packages/SettingsLib/SettingsTheme/res/layout/settings_preference.xml
index 3a289a7ceb00..d2b3169369ae 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout/settings_preference.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout/settings_preference.xml
@@ -29,7 +29,7 @@
android:clipToPadding="false"
android:baselineAligned="false">
- <include layout="@layout/image_frame"/>
+ <include layout="@layout/settings_icon"/>
<RelativeLayout
android:layout_width="0dp"
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index dff086930fb8..832894c163d8 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Stel slot op"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Skakel oor na <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Skep tans nuwe gebruiker …"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Bynaam"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Voeg gas by"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Verwyder gas"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 4bcbf72c23db..520289bb65dd 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"ቁልፍ አዘጋጅ"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"ወደ <xliff:g id="USER_NAME">%s</xliff:g> ቀይር"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"አዲስ ተጠቃሚ በመፍጠር ላይ…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ቅጽል ስም"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"እንግዳን አክል"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"እንግዳን አስወግድ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index ccbdbb1c3444..af071e878a06 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -508,16 +508,11 @@
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"وقت أقل."</string>
<string name="cancel" msgid="5665114069455378395">"إلغاء"</string>
<string name="okay" msgid="949938843324579502">"حسنًا"</string>
- <!-- no translation found for alarms_and_reminders_label (6918395649731424294) -->
- <skip />
- <!-- no translation found for alarms_and_reminders_switch_title (186992351401152744) -->
- <skip />
- <!-- no translation found for alarms_and_reminders_title (2988400785896875237) -->
- <skip />
- <!-- no translation found for alarms_and_reminders_footer_title (5882788882647778753) -->
- <skip />
- <!-- no translation found for keywords_alarms_and_reminders (8882739572152019456) -->
- <skip />
+ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"المنبّهات والتذكيرات"</string>
+ <string name="alarms_and_reminders_switch_title" msgid="186992351401152744">"السماح بضبط المنبّهات أو التذكيرات"</string>
+ <string name="alarms_and_reminders_title" msgid="2988400785896875237">"المنبّهات والتذكيرات"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="5882788882647778753">"يمكنك السماح لهذا التطبيق بضبط المنبّهات أو الموقّتات الأخرى استنادًا إلى الأحداث. سيسمح هذا الأذن بتنشيط التطبيق وتشغيله حتى في حال عدم استخدام الجهاز. تجدر الإشارة إلى أن إبطال هذا الأذن قد يسبب خللاً في عمل التطبيق، وعلى وجه الخصوص لن تعمل أي منبّهات تم ضبطها بواسطة التطبيق."</string>
+ <string name="keywords_alarms_and_reminders" msgid="8882739572152019456">"جدول زمني، منبّه، تذكير، حدث، فعالية"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"تفعيل"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"تفعيل وضع \"الرجاء عدم الإزعاج\""</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"مطلقًا"</string>
@@ -571,6 +566,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"تعيين التأمين"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"التبديل إلى <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"جارٍ إنشاء مستخدم جديد…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"اللقب"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"إضافة ضيف"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"إزالة جلسة الضيف"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index e5b30cb07028..8b6d29bb0e55 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"লক ছেট কৰক"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>লৈ সলনি কৰক"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰি থকা হৈছে…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"উপনাম"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ কৰক"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b58c3e2d0a8f..f00a87b6288d 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Kilid ayarlayın"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> adlı istifadəçiyə keçin"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Yeni istifadəçi yaradılır…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Ləqəb"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Qonaq əlavə edin"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Qonağı silin"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4fe132d157cc..26528b50da5f 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -563,6 +563,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Podesi zaključavanje"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Pređi na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Pravi se novi korisnik…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 268f2873b480..3f83d71d2fe4 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Усталёўка блакiроўкi"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Пераключыцца на карыстальніка <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Ствараецца новы карыстальнік…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Псеўданім"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Дадаць госця"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Выдаліць госця"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 25536e281890..55e87322c7e5 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -450,10 +450,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Възможно е таблетът да се изключи скоро (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Възможно е устройството да се изключи скоро (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_charging_duration_only (8085099012811384899) -->
- <skip />
- <!-- no translation found for power_charging_duration (6127154952524919719) -->
- <skip />
+ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Оставащо време до пълно зареждане: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_limited" msgid="1956874810658999681">"<xliff:g id="LEVEL">%1$s</xliff:g> – Оптимизиране с цел състоянието на батерията"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Зарежда се"</string>
@@ -461,8 +459,7 @@
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Зарежда се бавно"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Не се зарежда"</string>
<string name="battery_info_status_not_charging" msgid="8330015078868707899">"Включена в захранването, в момента не се зарежда"</string>
- <!-- no translation found for battery_info_status_full (1339002294876531312) -->
- <skip />
+ <string name="battery_info_status_full" msgid="1339002294876531312">"Заредена"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролира се от администратор"</string>
<string name="disabled" msgid="8017887509554714950">"Деактивирано"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Има разрешение"</string>
@@ -562,6 +559,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Задаване на заключване"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Превключване към <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Създава се нов потребител…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавяне на гост"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Премахване на госта"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 0808a03a1d41..9e2ce0908359 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"লক সেট করুন"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>-এ পাল্টান"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"নতুন ব্যবহারকারী তৈরি করা হচ্ছে…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"বিশেষ নাম"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ করুন"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি সরান"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index f56b66ea982a..10214641ed76 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -563,6 +563,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Postaviti zaključavanje"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Prebaci na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Kreiranje novog korisnika…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 36c23c99e634..24455710635f 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Defineix un bloqueig"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Canvia a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"S\'està creant l\'usuari…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Àlies"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Afegeix un convidat"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Suprimeix el convidat"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 2466b9c258ee..1e3869303140 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Nastavit zámek"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Přepnout na uživatele <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Vytváření nového uživatele…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Přezdívka"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Přidat hosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odstranit hosta"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 5c46619b1e0d..f1ea6cc0f707 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -559,6 +559,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Konfigurer låseskærmen"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Skift til <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Opretter ny bruger…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Kaldenavn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tilføj gæst"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gæsten"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 99aad6717974..dcf787903597 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -559,6 +559,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Sperre einrichten"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Zu <xliff:g id="USER_NAME">%s</xliff:g> wechseln"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Neuer Nutzer wird erstellt…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Alias"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gast hinzufügen"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Gast entfernen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 878907efa032..9ebafd947453 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Ορισμός κλειδώματος"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Εναλλαγή σε <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Δημιουργία νέου χρήστη…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Ψευδώνυμο"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Προσθήκη επισκέπτη"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Κατάργηση επισκέπτη"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index e70d99a5295d..7beb37893969 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -559,6 +559,7 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Set lock"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Switch to <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
+ <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 437e49a9cf1d..b1596c324837 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -559,6 +559,7 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Set lock"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Switch to <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
+ <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index e70d99a5295d..7beb37893969 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -559,6 +559,7 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Set lock"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Switch to <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
+ <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index e70d99a5295d..7beb37893969 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -559,6 +559,7 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Set lock"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Switch to <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
+ <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index fc4f3b99d28d..c984f6e2ef1b 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -559,6 +559,7 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎Set lock‎‏‎‎‏‎"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎Switch to ‎‏‎‎‏‏‎<xliff:g id="USER_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎Creating new user…‎‏‎‎‏‎"</string>
+ <string name="add_user_failed" msgid="4809887794313944872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎Failed to create a new user‎‏‎‎‏‎"</string>
<string name="user_nickname" msgid="262624187455825083">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎Nickname‎‏‎‎‏‎"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎Add guest‎‏‎‎‏‎"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‎Remove guest‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 750a048f9aa4..0b543b830d0c 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -450,10 +450,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Es posible que pronto se apague la tablet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Es posible que pronto se apague el dispositivo (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_charging_duration_only (8085099012811384899) -->
- <skip />
- <!-- no translation found for power_charging_duration (6127154952524919719) -->
- <skip />
+ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> para completar"</string>
+ <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar"</string>
<string name="power_charging_limited" msgid="1956874810658999681">"<xliff:g id="LEVEL">%1$s</xliff:g>: Optimizando el estado de la batería"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
@@ -461,8 +459,7 @@
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carga lenta"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando."</string>
<string name="battery_info_status_not_charging" msgid="8330015078868707899">"Conectado. No se puede cargar en este momento"</string>
- <!-- no translation found for battery_info_status_full (1339002294876531312) -->
- <skip />
+ <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string>
<string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Con permiso"</string>
@@ -562,6 +559,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Configurar bloqueo"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Cambiar a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creando usuario nuevo…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Sobrenombre"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Agregar invitado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index ff1582efdc54..5d738d7c4318 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Establecer bloqueo"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Cambiar a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creando usuario…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Apodo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Añadir invitado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 1e6ad9fe70b7..591290b7dcdb 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Määra lukk"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Lülita kasutajale <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Uue kasutaja loomine …"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Hüüdnimi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisa külaline"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index a77ba2d854ae..f5c36152e10f 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Ezarri blokeoa"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Aldatu <xliff:g id="USER_NAME">%s</xliff:g> erabiltzailera"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Beste erabiltzaile bat sortzen…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Goitizena"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gehitu gonbidatua"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Kendu gonbidatua"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index a8ed0d0635de..a4ccebad5f44 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"تنظیم قفل"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"رفتن به <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"درحال ایجاد کاربر جدید…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"نام مستعار"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"افزودن مهمان"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"حذف مهمان"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index b545deea66c1..f6a1f412c1ee 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Aseta lukitus"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Vaihda tähän käyttäjään: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Luodaan uutta käyttäjää…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Lempinimi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 21ddbd1585aa..2b379c70b5e8 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Définir verrouillage écran"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Passer à <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Créer un utilisateur…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Pseudo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index d899fb00c39a..ef4c707864b1 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Définir verrouillage écran"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Passer à <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Création d\'un nouvel utilisateur…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Pseudo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 747370cc5384..e9cfa401f579 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Establecer bloqueo"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Cambiar a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creando usuario novo…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Alcume"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engadir convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar convidado"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 760172035187..378215cbd556 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"લૉક સેટ કરો"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> પર સ્વિચ કરો"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"નવા વપરાશકર્તા બનાવી રહ્યાં છીએ…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ઉપનામ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"અતિથિ ઉમેરો"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"અતિથિને કાઢી નાખો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 6dc6a7eb5b67..319150af593e 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"लॉक सेट करें"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> पर जाएं"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"नया उपयोगकर्ता बनाया जा रहा है…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"प्रचलित नाम"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"मेहमान जोड़ें"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"मेहमान हटाएं"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 7aefec395055..82bd8aed536e 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -563,6 +563,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Postavi zaključavanje"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Prelazak na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Izrada novog korisnika…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodavanje gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Uklanjanje gosta"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index fe4aa3afc630..edea1405533f 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Képernyőzár beállítása"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Váltás erre: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Új felhasználó létrehozása…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Becenév"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Vendég hozzáadása"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Vendég munkamenet eltávolítása"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 3b6b91d57471..4a7b0fe4b5b2 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -507,7 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Զարթուցիչներ և հիշեցումներ"</string>
<string name="alarms_and_reminders_switch_title" msgid="186992351401152744">"Թույլատրել կարգավորել զարթուցիչներ և հիշեցումներ"</string>
<string name="alarms_and_reminders_title" msgid="2988400785896875237">"Զարթուցիչներ և հիշեցումներ"</string>
- <string name="alarms_and_reminders_footer_title" msgid="5882788882647778753">"Թույլատրեք այս հավելվածին կարգավորել զարթուցիչներ և ժամանակացույցների հետ կապված այլ իրադարձություններ։ Դա թույլ կտա հավելվածին միանալ և գործարկվել, նույնիսկ եթե չեք օգտագործում սարքը։ Նկատի ունեցեք, որ եթե չեղարկեք այս թույլտվությունը, հավելվածը կարող է աշխատել թերություններով, մասնավորապես, հավելվածի կողմից կարգավորված զարթուցիչներն այլևս չեն աշխատի։"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="5882788882647778753">"Թույլ տվեք այս հավելվածին կարգավորել զարթուցիչներ և ժամանակացույցների հետ կապված այլ իրադարձություններ։ Հավելվածը կկարողանա միանալ և գործարկվել, նույնիսկ եթե չեք օգտագործում սարքը։ Նկատի ունեցեք, որ եթե չեղարկեք այս թույլտվությունը, հավելվածը կարող է աշխատել թերություններով, մասնավորապես, հավելվածի կողմից կարգավորված զարթուցիչներն այլևս չեն աշխատի։"</string>
<string name="keywords_alarms_and_reminders" msgid="8882739572152019456">"ժամանակացույց, զարթուցիչ, հիշեցում, իրադարձություն"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Միացնել"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Միացրեք «Չանհանգստացնել» ռեժիմը"</string>
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Կարգավորել կողպումը"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Անցնել <xliff:g id="USER_NAME">%s</xliff:g> պրոֆիլին"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Ստեղծվում է օգտատիրոջ նոր պրոֆիլ…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Կեղծանուն"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ավելացնել հյուր"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Հեռացնել հյուրին"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index d084998ffc9a..6c70022a25a3 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Setel kunci"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Beralih ke <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Membuat pengguna baru …"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tambahkan tamu"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Hapus tamu"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index ddf0742a786f..541840ad973d 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Velja lás"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Skipta yfir í <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Stofnar nýjan notanda…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Gælunafn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Bæta gesti við"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjarlægja gest"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 7bf9eba80786..58c001278c0d 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -559,6 +559,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Imposta blocco"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Passa a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creazione nuovo utente…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Aggiungi ospite"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Rimuovi ospite"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 87f59c2df142..8ab65d621ab9 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"הגדרת נעילה"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"מעבר אל <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"בתהליך יצירה של משתמש חדש…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"כינוי"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"הוספת אורח"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"הסרת אורח"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index c9d58e915437..19efad69c37e 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"ロックを設定"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> に切り替え"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"新しいユーザーを作成しています…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ニックネーム"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ゲストを追加"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ゲストを削除"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index bc12f9460593..ef1110ec33b2 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"საკეტის დაყენება"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>-ზე გადართვა"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"მიმდინარეობს ახალი მომხმარებლის შექმნა…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"მეტსახელი"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"სტუმრის დამატება"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"სტუმრის ამოშლა"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 393a55f6d515..0a9db64a3248 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Бекітпе тағайындау"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> пайдаланушысына ауысу"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Жаңа пайдаланушы профилі жасалуда…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Лақап ат"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Қонақ қосу"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты жою"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 605b3be2ad57..3635c82f7d9c 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"កំណត់​ការ​ចាក់​សោ"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"ប្ដូរទៅ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"កំពុងបង្កើត​អ្នកប្រើប្រាស់ថ្មី…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ឈ្មោះ​ហៅក្រៅ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"បញ្ចូល​ភ្ញៀវ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ដកភ្ញៀវចេញ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 40540243979f..a261d2103fd1 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"ಲಾಕ್ ಹೊಂದಿಸಿ"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> ಗೆ ಬದಲಿಸಿ"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ಅಡ್ಡ ಹೆಸರು"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ಅತಿಥಿಯನ್ನು ಸೇರಿಸಿ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index d4719ba499ca..14d5d1ca66de 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"잠금 설정"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>(으)로 전환"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"새로운 사용자를 만드는 중…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"닉네임"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"게스트 추가"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"게스트 삭제"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index c0dab0689c68..a52cad637386 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Бөгөт коюу"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> аккаунтуна которулуу"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Жаңы колдонуучу түзүлүүдө…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Ылакап аты"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Конок кошуу"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Конокту өчүрүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index a9d1f2942dbb..565fd300861a 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"ຕັ້ງການລັອກ"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"ສະຫຼັບໄປ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ກຳລັງສ້າງຜູ້ໃຊ້ໃໝ່…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ຊື່ຫຼິ້ນ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ເພີ່ມແຂກ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ລຶບແຂກອອກ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 2fe28d205963..e35a3088c885 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Nustatyti užraktą"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Perjungti į <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Kuriamas naujas naudotojas…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Slapyvardis"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridėti svečią"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Pašalinti svečią"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 3b7b73b04451..eb8c8088e66d 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -563,6 +563,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Iestatīt bloķēšanu"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Pārslēgties uz: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Notiek jauna lietotāja izveide…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Segvārds"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pievienot viesi"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Noņemt viesi"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index d02747473a9a..d0e5996e24ff 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Постави заклучување"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Префрли на <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Се создава нов корисник…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Прекар"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додај гостин"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Отстрани гостин"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index c553bdc4d7ce..f5bf135693e6 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"ലോക്ക് സജ്ജീകരിക്കുക"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> എന്നതിലേക്ക് മാറുക"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"പുതിയ ഉപയോക്താവിനെ സൃഷ്‌ടിക്കുന്നു…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"വിളിപ്പേര്"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"അതിഥിയെ ചേർക്കുക"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 48278dc472dd..3d3f710025e4 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Түгжээг тохируулах"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> руу сэлгэх"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Шинэ хэрэглэгч үүсгэж байна…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Хоч"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Зочин нэмэх"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Зочин хасах"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index a0eecdec444e..f57b164e085b 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"लॉक सेट करा"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> वर स्विच करा"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"नवीन वापरकर्ता तयार करत आहे…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"टोपणनाव"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 5c2fcb7a182b..28d9e8e26d84 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Tetapkan kunci"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Tukar kepada <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Mencipta pengguna baharu…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tambah tetamu"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Alih keluar tetamu"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 7f3fc67a1e5a..e5df8cbfa1c9 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -507,7 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"နှိုးစက်နှင့် သတိပေးချက်များ"</string>
<string name="alarms_and_reminders_switch_title" msgid="186992351401152744">"နှိုးစက် (သို့) သတိပေးချက်များ သတ်မှတ်ခွင့်ပြုရန်"</string>
<string name="alarms_and_reminders_title" msgid="2988400785896875237">"နှိုးစက်နှင့် သတိပေးချက်များ"</string>
- <string name="alarms_and_reminders_footer_title" msgid="5882788882647778753">"နှိုးစက်သတ်မှတ်ရန် (သို့) အချိန်သတ်မှတ်ချက်ပါသည့် အစီအစဉ်များဆွဲရန် ဤအက်ပ်ကို ခွင့်ပြုပါ။ ၎င်းက စက်ကို သင်အသုံးမပြုသော်လည်း အက်ပ်ကို နှိုးရန်နှင့် အလုပ်လုပ်နေရန် ခွင့်ပြုမည်။ ဤခွင့်ပြုချက်ကို ရုတ်သိမ်းခြင်းက အက်ပ်ကို ချွတ်ယွင်းစေမည်ဖြစ်ကြောင်း သတိပြုပါ၊ အထူးသဖြင့် အက်ပ်က သတ်မှတ်ထားသော မည်သည့်နှိုးစက်မျှ အလုပ်မလုပ်တော့ပါ။"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="5882788882647778753">"နှိုးစက်သတ်မှတ်ရန် (သို့) အချိန်သတ်မှတ်ချက်ပါသည့် အစီအစဉ်များဆွဲရန် ဤအက်ပ်ကို ခွင့်ပြုပါ။ သင်က စက်ကိုအသုံးမပြုနေသည့် အချိန်တွင်လည်း စတင်ရန်နှင့် အလုပ်လုပ်နေရန် အက်ပ်ကို ခွင့်ပြုပါမည်။ ဤခွင့်ပြုချက်ကို ရုတ်သိမ်းခြင်းက အက်ပ်ကို ချွတ်ယွင်းစေမည်ဖြစ်ကြောင်း သတိပြုပါ၊ အထူးသဖြင့် အက်ပ်က သတ်မှတ်ထားသော မည်သည့်နှိုးစက်မျှ အလုပ်မလုပ်တော့ပါ။"</string>
<string name="keywords_alarms_and_reminders" msgid="8882739572152019456">"အချိန်ဇယား၊ နှိုးစက်၊ သတိပေးချက်၊ အစီအစဉ်"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ဖွင့်ရန်"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'မနှောင့်ယှက်ရ\' ဖွင့်ခြင်း"</string>
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"သော့ချရန် သတ်မှတ်ပါ"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> သို့ ပြောင်းရန်"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"အသုံးပြုသူအသစ် ပြုလုပ်နေသည်…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"နာမည်ပြောင်"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ဧည့်သည့် ထည့်ရန်"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ဧည့်သည်ကို ဖယ်ထုတ်ရန်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 24c982f11bac..a0c5651dac6d 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -507,7 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmer og påminnelser"</string>
<string name="alarms_and_reminders_switch_title" msgid="186992351401152744">"Gi tillatelse til å angi alarmer og påminnelser"</string>
<string name="alarms_and_reminders_title" msgid="2988400785896875237">"Alarmer og påminnelser"</string>
- <string name="alarms_and_reminders_footer_title" msgid="5882788882647778753">"Dette gjør at appen kan planlegge alarmer eller andre tidsbaserte hendelser. Dette gjør at appen kan starte og kjøre, selv når du ikke bruker enheten. Hvis du opphever denne tillatelsen, kan det føre til feil med appen, spesifikt at alarmer som appen har planlagt, ikke fungerer lenger."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="5882788882647778753">"Tillat denne appen å planlegge alarmer eller andre tidsbaserte hendelser. Dette gjør at appen kan starte og kjøre, selv når du ikke bruker enheten. Hvis du opphever denne tillatelsen, kan det føre til feil med appen, blant annet at alarmer som appen har planlagt, ikke fungerer lenger."</string>
<string name="keywords_alarms_and_reminders" msgid="8882739572152019456">"tidsplan, alarm, påminnelse, hendelse"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Slå på"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Slå på Ikke forstyrr"</string>
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Angi lås"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Bytt til <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Oppretter en ny bruker …"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Kallenavn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Legg til en gjest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index ca9dd296f79d..c98b4aea4aaa 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"लक सेट गर्नुहोस्"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"प्रयोगकर्ता बदलेर <xliff:g id="USER_NAME">%s</xliff:g> पार्नुहोस्"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"नयाँ प्रयोगकर्ता बनाउँदै…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"उपनाम"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथि थप्नुहोस्"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अतिथि हटाउनुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 2126b1f8047f..8139fe3ec839 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Vergrendeling instellen"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Overschakelen naar <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Nieuwe gebruiker maken…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Bijnaam"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gast toevoegen"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Gast verwijderen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index b6da15cce542..db404b8ad0b0 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"ଲକ୍‌ ସେଟ୍‌ କରନ୍ତୁ"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>କୁ ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରାଯାଉଛି…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ଡାକନାମ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ଅତିଥି ଯୋଗ କରନ୍ତୁ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ଅତିଥିଙ୍କୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index f958c109c394..c8af67b370cb 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">" ਲਾਕ ਸੈੱਟ ਕਰੋ"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> \'ਤੇ ਜਾਓ"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਇਆ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ਉਪਨਾਮ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ਮਹਿਮਾਨ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ਮਹਿਮਾਨ ਹਟਾਓ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 9bf38735b353..687f66315259 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Ustaw blokadę"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Przełącz na: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Tworzę nowego użytkownika…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gościa"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Usuń gościa"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 395347e76af2..34fff26b4436 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Definir bloqueio"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Mudar para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Criando novo usuário…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 1c502d201cd5..bb1d8b248861 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Definir bloqueio"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Mudar para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"A criar novo utilizador…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Pseudónimo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 395347e76af2..34fff26b4436 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Definir bloqueio"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Mudar para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Criando novo usuário…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 5527c666fdd9..5e5c04432924 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -563,6 +563,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Configurați blocarea"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Treceți la <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Se creează un utilizator nou…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adăugați un invitat"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ștergeți invitatul"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index cd80bc5846d3..b9b2edb8e318 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Включить блокировку"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Переключиться на этот аккаунт: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Создаем нового пользователя…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавить гостя"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Удалить аккаунт гостя"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index f75a3da0512a..cd25803552b9 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"අගුල සකසන්න"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> වෙත මාරු වන්න"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"නව පරිශීලක තනමින්…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"අපනාමය"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"අමුත්තා එක් කරන්න"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"අමුත්තා ඉවත් කරන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 14c3b0809277..03c3cb2ed047 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Nastaviť uzamknutie"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Prepnúť na používateľa <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Vytvára sa nový používateľ…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Prezývka"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridať hosťa"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 2c24e68e5708..b2635fbbb62c 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Nastavi zaklepanje"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Preklop na račun <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Ustvarjanje novega uporabnika …"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Vzdevek"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodajanje gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odstranitev gosta"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 7496835e20a5..e57ede68d185 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Cakto kyçjen"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Kalo te <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Po krijohet një përdorues i ri…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Pseudonimi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Shto të ftuar"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Hiq të ftuarin"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 8db0e062aa95..c0a9022d39bf 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -563,6 +563,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Подеси закључавање"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Пређи на корисника <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Прави се нови корисник…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Надимак"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додај госта"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index b0e1de93939e..da220324cb67 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Konfigurera lås"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Byt till <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Skapar ny användare …"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Smeknamn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lägg till gäst"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ta bort gäst"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 537f22601e0b..4da81849811f 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Weka ufunguo"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Badili utumie <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Inaweka mtumiaji mpya…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Jina wakilishi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ongeza mgeni"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ondoa mgeni"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 7aec7bc23279..535bbf222f65 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"பூட்டை அமை"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>க்கு மாறு"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"புதிய பயனரை உருவாக்குகிறது…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"புனைப்பெயர்"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"கெஸ்ட்டைச் சேர்"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"கெஸ்ட்டை அகற்று"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 3ae2d90b9753..31f751952478 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"లాక్‌ను సెట్ చేయి"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>కు మార్చు"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"కొత్త యూజర్‌ను క్రియేట్ చేస్తోంది…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"మారుపేరు"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"గెస్ట్‌ను జోడించండి"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"అతిథిని తీసివేయండి"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index b566d88321ea..59ace4a8537a 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"ตั้งค่าล็อก"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"เปลี่ยนเป็น <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"กำลังสร้างผู้ใช้ใหม่…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"ชื่อเล่น"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"เพิ่มผู้เข้าร่วม"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"นำผู้เข้าร่วมออก"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 2a8109c2d8f3..0c072caf6ba1 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Itakda ang lock"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Lumipat sa <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Gumagawa ng bagong user…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Magdagdag ng bisita"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Alisin ang bisita"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 03d975e2aa0c..fc9bd9e99cd2 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Kilidi ayarla"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> hesabına geç"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Yeni kullanıcı oluşturuluyor…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Takma ad"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Misafir ekle"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Misafir oturumunu kaldır"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 5b1130b21b43..e08b51515e42 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -564,6 +564,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Налаштувати блокування"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Перейти до користувача <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Створення нового користувача…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Псевдонім"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додати гостя"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Видалити гостя"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 2ce5204afde1..0909efb63a8c 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -567,6 +567,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"لاک سیٹ کریں"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"‫<xliff:g id="USER_NAME">%s</xliff:g> پر سوئچ کریں"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"نیا صارف تخلیق کرنا…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"عرفی نام"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 4eb0e4814a62..f83fe1d25eb8 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Qulf o‘rnatish"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Bunga almashish: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Yangi foydalanuvchi yaratilmoqda…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Nik"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index f7692493e7e0..ab415f9b9d59 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Thiết lập khóa"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Chuyển sang <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Đang tạo người dùng mới…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Biệt hiệu"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Thêm khách"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Xóa phiên khách"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index cc5b97b154cb..2d95ab1a68f3 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"设置屏幕锁定方式"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"切换到<xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"正在创建新用户…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"昵称"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"添加访客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除访客"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index d49707b6346f..3314f825ccf6 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"設定上鎖畫面"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"切換至<xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"正在建立新使用者…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 7649e44c08a2..95eae87912bd 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"設定鎖定"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"切換至<xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"正在建立新使用者…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index d0ddec58f6ab..f5322a12df3a 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -562,6 +562,8 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Setha ukukhiya"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Shintshela ku-<xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Idala umsebenzisi omusha…"</string>
+ <!-- no translation found for add_user_failed (4809887794313944872) -->
+ <skip />
<string name="user_nickname" msgid="262624187455825083">"Isiteketiso"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engeza isivakashi"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Susa isihambeli"</string>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index b6b5ae5b6ce4..4ff3c55e3a70 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -449,6 +449,9 @@
<!-- Permission required for CTS test - ResourceObserverNativeTest -->
<uses-permission android:name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" />
+ <!-- Permission required for CTS test - CtsPermission5TestCases -->
+ <uses-permission android:name="android.permission.RENOUNCE_PERMISSIONS" />
+
<!-- Permission required for CTS test - android.widget.cts.ToastTest -->
<uses-permission android:name="android.permission.UNLIMITED_TOASTS" />
diff --git a/packages/Shell/res/values-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml
index ade92dbdd545..b975521c2acb 100644
--- a/packages/Shell/res/values-iw/strings.xml
+++ b/packages/Shell/res/values-iw/strings.xml
@@ -19,25 +19,25 @@
<string name="app_label" msgid="3701846017049540910">"מעטפת"</string>
<string name="bugreport_notification_channel" msgid="2574150205913861141">"דוחות על באגים"</string>
<string name="bugreport_in_progress_title" msgid="4311705936714972757">"בתהליך יצירה של דוח על באג (<xliff:g id="ID">#%d</xliff:g>)"</string>
- <string name="bugreport_finished_title" msgid="4429132808670114081">"הדוח על הבאג <xliff:g id="ID">#%d</xliff:g> צולם"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"הדוח על הבאג (<xliff:g id="ID">#%d</xliff:g>) צולם"</string>
<string name="bugreport_updating_title" msgid="4423539949559634214">"בתהליך הוספת פרטים לדוח על הבאג"</string>
- <string name="bugreport_updating_wait" msgid="3322151947853929470">"המתן…"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"רק רגע…"</string>
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"הדוח על הבאג יופיע בטלפון בקרוב"</string>
<string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"יש להקיש כדי לשתף את הדוח על הבאג"</string>
- <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"הקש כדי לשתף את הדוח על הבאג"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"החלק ימינה כדי לשתף את הדוח על הבאג ללא צילום מסך או המתן להשלמת צילום המסך"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"יש להקיש כדי לשתף את הדוח על הבאג"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"אפשר להחליק ימינה כדי לשתף את הדוח על הבאג ללא צילום מסך, או להמתין להשלמת צילום המסך"</string>
<string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"יש להקיש כדי לשתף את הדוח על הבאג ללא צילום מסך, או להמתין להשלמת צילום המסך"</string>
<string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"יש להקיש כדי לשתף את הדוח על הבאג ללא צילום מסך, או להמתין להשלמת צילום המסך"</string>
<string name="bugreport_confirm" msgid="5917407234515812495">"דוחות על באגים כוללים נתונים מקובצי היומן השונים במערכת, שעשויים לכלול נתונים הנחשבים רגישים (כגון שימוש באפליקציות ונתוני מיקום). כדאי לשתף דוחות על באגים רק עם אפליקציות ואנשים מהימנים."</string>
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"אל תציגו זאת שוב"</string>
- <string name="bugreport_storage_title" msgid="5332488144740527109">"דוחות באגים"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"דוחות על באגים"</string>
<string name="bugreport_unreadable_text" msgid="586517851044535486">"לא ניתן היה לקרוא את קובץ הדוח על הבאג"</string>
<string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"‏לא ניתן היה להוסיף את פרטי הדוח על הבאג לקובץ ה-zip"</string>
<string name="bugreport_unnamed" msgid="2800582406842092709">"ללא שם"</string>
<string name="bugreport_info_action" msgid="2158204228510576227">"פרטים"</string>
<string name="bugreport_screenshot_action" msgid="8677781721940614995">"צילום מסך"</string>
<string name="bugreport_screenshot_taken" msgid="5684211273096253120">"צילום המסך בוצע בהצלחה."</string>
- <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"לא ניתן היה לצלם מסך."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"לא ניתן היה לצלם את המסך."</string>
<string name="bugreport_info_dialog_title" msgid="1355948594292983332">"פרטי הדוח על הבאג (<xliff:g id="ID">#%d</xliff:g>)"</string>
<string name="bugreport_info_name" msgid="4414036021935139527">"שם קובץ"</string>
<string name="bugreport_info_title" msgid="2306030793918239804">"כותרת הבאג"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index c9bd370cd49c..3adff125886b 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -275,6 +275,8 @@
<!-- Permission to make accessibility service access Bubbles -->
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
+ <!-- Can control and display smartspace content -->
+ <uses-permission android:name="android.permission.MANAGE_SMARTSPACE" />
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
@@ -679,7 +681,7 @@
<activity
android:name=".settings.brightness.BrightnessDialog"
android:label="@string/quick_settings_brightness_dialog_title"
- android:theme="@*android:style/Theme.DeviceDefault.QuickSettings.Dialog"
+ android:theme="@*android:style/Theme.DeviceDefault.SystemUI.Dialog"
android:finishOnCloseSystemDialogs="true"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
@@ -757,6 +759,7 @@
android:excludeFromRecents="true"
android:showWhenLocked="true"
android:showForAllUsers="true"
+ android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
android:visibleToInstantApps="true">
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index f8a9a0459673..c090d8a3d8ce 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -16,7 +16,9 @@
package com.android.systemui.plugins;
+import android.app.smartspace.SmartspaceTarget;
import android.os.Parcelable;
+import android.view.ViewGroup;
import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -36,9 +38,23 @@ public interface BcSmartspaceDataPlugin extends Plugin {
/** Unregister a listener. */
void unregisterListener(SmartspaceTargetListener listener);
+ /**
+ * Create a view to be shown within the parent. Do not add the view, as the parent
+ * will be responsible for correctly setting the LayoutParams
+ */
+ SmartspaceView getView(ViewGroup parent);
+
+ /** Updates Smartspace data and propagates it to any listeners. */
+ void onTargetsAvailable(List<SmartspaceTarget> targets);
+
/** Provides Smartspace data to registered listeners. */
interface SmartspaceTargetListener {
/** Each Parcelable is a SmartspaceTarget that represents a card. */
void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets);
}
+
+ /** View to which this plugin can be registered, in order to get updates. */
+ interface SmartspaceView {
+ void registerDataProvider(BcSmartspaceDataPlugin plugin);
+ }
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 26cead206310..c9f2401fd16a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -143,6 +143,7 @@ public interface QSTile {
public SlashState slash;
public boolean handlesLongClick = true;
public boolean showRippleEffect = true;
+ public Drawable sideViewDrawable;
public boolean copyTo(State other) {
if (other == null) throw new IllegalArgumentException();
@@ -163,7 +164,8 @@ public interface QSTile {
|| !Objects.equals(other.dualTarget, dualTarget)
|| !Objects.equals(other.slash, slash)
|| !Objects.equals(other.handlesLongClick, handlesLongClick)
- || !Objects.equals(other.showRippleEffect, showRippleEffect);
+ || !Objects.equals(other.showRippleEffect, showRippleEffect)
+ || !Objects.equals(other.sideViewDrawable, sideViewDrawable);
other.icon = icon;
other.iconSupplier = iconSupplier;
other.label = label;
@@ -179,6 +181,7 @@ public interface QSTile {
other.slash = slash != null ? slash.copy() : null;
other.handlesLongClick = handlesLongClick;
other.showRippleEffect = showRippleEffect;
+ other.sideViewDrawable = sideViewDrawable;
return changed;
}
@@ -204,6 +207,7 @@ public interface QSTile {
sb.append(",isTransient=").append(isTransient);
sb.append(",state=").append(state);
sb.append(",slash=\"").append(slash).append("\"");
+ sb.append(",sideViewDrawable").append(sideViewDrawable);
return sb.append(']');
}
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 773e4efae2e4..6ba69976ffbb 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -22,12 +22,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="514691256816366517">"מגן מקלדת"</string>
<string name="keyguard_password_enter_pin_code" msgid="8582296866585566671">"יש להזין את קוד האימות"</string>
- <string name="keyguard_password_enter_puk_code" msgid="3813154965969758868">"‏הזן את קוד ה-PUK של כרטיס ה-SIM ולאחר מכן הזן קוד גישה חדש"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3813154965969758868">"‏יש להזין את קוד ה-PUK של כרטיס ה-SIM ולאחר מכן את קוד האימות חדש"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="3529260761374385243">"‏קוד PUK של כרטיס SIM"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="2304037870481240781">"‏קוד אימות חדש לכרטיס ה-SIM"</string>
- <string name="keyguard_password_entry_touch_hint" msgid="6180028658339706333"><font size="17">"גע כדי להזין את הסיסמה"</font></string>
- <string name="keyguard_password_enter_password_code" msgid="7393393239623946777">"הזן סיסמה לביטול הנעילה"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="3692259677395250509">"הזן את קוד הגישה לביטול הנעילה"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="6180028658339706333"><font size="17">"צריך לגעת כדי להקליד את הסיסמה"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="7393393239623946777">"יש להזין סיסמה לביטול הנעילה"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="3692259677395250509">"יש להזין את קוד האימות לביטול הנעילה"</string>
<string name="keyguard_enter_your_pin" msgid="5429932527814874032">"צריך להזין קוד אימות"</string>
<string name="keyguard_enter_your_pattern" msgid="351503370332324745">"יש להזין קו ביטול נעילה"</string>
<string name="keyguard_enter_your_password" msgid="7225626204122735501">"יש להזין סיסמה"</string>
@@ -39,21 +39,21 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה מהירה"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה איטית"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1158086783302116604">"<xliff:g id="PERCENTAGE">%s</xliff:g> • מופעלת אופטימיזציה לשמירה על תקינות הסוללה"</string>
- <string name="keyguard_low_battery" msgid="1868012396800230904">"חבר את המטען."</string>
- <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"לחץ על \'תפריט\' כדי לבטל את הנעילה."</string>
+ <string name="keyguard_low_battery" msgid="1868012396800230904">"כדאי לחבר את המטען."</string>
+ <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"יש ללחוץ על \'תפריט\' כדי לבטל את הנעילה."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"הרשת נעולה"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"‏אין כרטיס SIM"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"‏יש להכניס כרטיס SIM."</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"‏כרטיס ה-SIM חסר או שלא ניתן לקרוא אותו. הכנס כרטיס SIM."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"‏כרטיס ה-SIM חסר או שלא ניתן לקרוא אותו. יש להכניס כרטיס SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"‏לא ניתן להשתמש בכרטיס SIM זה."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"‏כרטיס ה-SIM שלך הושבת לצמיתות.\nפנה לספק השירות האלחוטי שלך לקבלת כרטיס SIM אחר."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"‏כרטיס ה-SIM שלך הושבת באופן סופי.\nיש לפנות לספק השירות האלחוטי שלך לקבלת כרטיס SIM אחר."</string>
<string name="keyguard_sim_locked_message" msgid="4343544458476911044">"‏כרטיס ה-SIM נעול."</string>
<string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"‏כרטיס ה-SIM נעול באמצעות PUK."</string>
- <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"‏מבטל את הנעילה של כרטיס ה-SIM…"</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"‏בתהליך ביטול נעילה של כרטיס ה-SIM…"</string>
<string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"אזור של קוד האימות"</string>
- <string name="keyguard_accessibility_password" msgid="3524161948484801450">"סיסמת מכשיר"</string>
- <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"‏אזור לקוד הגישה של כרטיס ה-SIM"</string>
- <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"‏אזור לקוד הגישה של כרטיס ה-SIM"</string>
+ <string name="keyguard_accessibility_password" msgid="3524161948484801450">"סיסמת המכשיר"</string>
+ <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"‏אזור לקוד האימות של כרטיס ה-SIM"</string>
+ <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"‏האזור של קוד האימות של כרטיס ה-SIM"</string>
<string name="keyguard_accessibility_next_alarm" msgid="4492876946798984630">"ההתראה הבאה נקבעה ל-<xliff:g id="ALARM">%1$s</xliff:g>"</string>
<string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Delete"</string>
<string name="disable_carrier_button_text" msgid="7153361131709275746">"‏השבתת ה-eSIM"</string>
@@ -70,25 +70,25 @@
<item quantity="other">אפשר יהיה לנסות שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות.</item>
<item quantity="one">אפשר יהיה לנסות שוב בעוד שנייה אחת.</item>
</plurals>
- <string name="kg_pattern_instructions" msgid="5376036737065051736">"שרטט את קו ביטול הנעילה"</string>
- <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"‏הזן את קוד הגישה של כרטיס ה-SIM."</string>
+ <string name="kg_pattern_instructions" msgid="5376036737065051736">"צריך לשרטט את קו ביטול הנעילה"</string>
+ <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"‏יש להזין את קוד האימות של כרטיס ה-SIM."</string>
<string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"‏יש להזין את קוד האימות של כרטיס ה-SIM של <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
<string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"‏<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> יש להשבית את כרטיס ה-eSIM כדי להשתמש במכשיר ללא שירות סלולרי."</string>
<string name="kg_pin_instructions" msgid="822353548385014361">"יש להזין קוד אימות"</string>
<string name="kg_password_instructions" msgid="324455062831719903">"צריך להזין את הסיסמה"</string>
<string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"‏כרטיס ה-SIM מושבת עכשיו. צריך להזין קוד PUK כדי להמשיך. יש לפנות אל הספק לקבלת פרטים."</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"‏ה-SIM של \"<xliff:g id="CARRIER">%1$s</xliff:g>\" מושבת עכשיו. צריך להזין קוד PUK כדי להמשיך. לפרטים, יש לפנות אל הספק."</string>
- <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"הזן את קוד הגישה הרצוי"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"יש להזין את קוד האימות הרצוי"</string>
<string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"צריך לאשר את קוד האימות הרצוי"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"‏מתבצע ביטול נעילה של כרטיס ה-SIM…"</string>
- <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"הקלד קוד גישה שאורכו 4 עד 8 ספרות."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"יש להקליד קוד אימות שאורכו 4 עד 8 ספרות."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"‏קוד PUK צריך להיות בן 8 ספרות או יותר."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"‏יש להזין את קוד ה-PUK הנכון. ניסיונות חוזרים ישביתו את כרטיס ה-SIM באופן סופי."</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ניסית לשרטט את קו ביטול הנעילה יותר מדי פעמים"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"הקלדת קוד גישה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nיש לנסות שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‏קוד הגישה של כרטיס ה-SIM שגוי. צור קשר עם הספק כדי לבטל את נעילת המכשיר."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nאפשר לנסות שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nאפשר לנסות שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‏קוד האימות של כרטיס ה-SIM שגוי. יש ליצור קשר עם הספק כדי לבטל את נעילת המכשיר."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="two">‏קוד האימות של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
<item quantity="many">‏קוד האימות של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
@@ -102,7 +102,7 @@
<item quantity="other">‏קוד ה-PUK של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני שכרטיס ה-SIM יינעל לצמיתות.</item>
<item quantity="one">‏קוד ה-PUK של כרטיס ה-SIM שגוי. נותר לך ניסיון <xliff:g id="NUMBER_0">%d</xliff:g> נוסף לפני שכרטיס ה-SIM יינעל לצמיתות.</item>
</plurals>
- <string name="kg_password_pin_failed" msgid="5136259126330604009">"‏פעולת קוד הגישה של כרטיס ה-SIM נכשלה!"</string>
+ <string name="kg_password_pin_failed" msgid="5136259126330604009">"‏נכשלה פעולת קוד הגישה של כרטיס ה-SIM"</string>
<string name="kg_password_puk_failed" msgid="6778867411556937118">"‏הניסיון לביטול הנעילה של כרטיס ה-SIM באמצעות קוד PUK נכשל!"</string>
<string name="kg_pin_accepted" msgid="1625501841604389716">"הקוד התקבל!"</string>
<string name="keyguard_carrier_default" msgid="6359808469637388586">"אין שירות."</string>
@@ -112,12 +112,12 @@
<string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"צריך להזין קוד אימות לאחר הפעלה מחדש של המכשיר"</string>
<string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"יש להזין סיסמה לאחר הפעלה מחדש של המכשיר"</string>
<string name="kg_prompt_reason_timeout_pattern" msgid="9170360502528959889">"יש להזין את קו ביטול הנעילה כדי להגביר את רמת האבטחה"</string>
- <string name="kg_prompt_reason_timeout_pin" msgid="5945186097160029201">"יש להזין קוד גישה כדי להגביר את רמת האבטחה"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="5945186097160029201">"יש להזין קוד אימות כדי להגביר את רמת האבטחה"</string>
<string name="kg_prompt_reason_timeout_password" msgid="2258263949430384278">"יש להזין סיסמה כדי להגביר את רמת האבטחה"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="1922016914701991230">"יש להזין את קו ביטול הנעילה כשמחליפים בין פרופילים"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="6490434826361055400">"צריך להזין את קוד האימות כשמחליפים פרופיל"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="1680374696393804441">"יש להזין את הסיסמה בזמן מעבר בין פרופילים"</string>
- <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"מנהל המכשיר נעל את המכשיר"</string>
+ <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"המנהל של המכשיר נהל אותו"</string>
<string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"המכשיר ננעל באופן ידני"</string>
<plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="1337428979661197957">
<item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את קו ביטול הנעילה.</item>
@@ -126,10 +126,10 @@
<item quantity="one">נעילת המכשיר לא בוטלה במשך שעה אחת (<xliff:g id="NUMBER_0">%d</xliff:g>). יש להזין את קו ביטול הנעילה.</item>
</plurals>
<plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="6444519502336330270">
- <item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את קוד הגישה.</item>
- <item quantity="many">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את קוד הגישה.</item>
- <item quantity="other">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. הזן את קוד הגישה.</item>
- <item quantity="one">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_0">%d</xliff:g> שעה. הזן את קוד הגישה.</item>
+ <item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את קוד האימות.</item>
+ <item quantity="many">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את קוד האימות.</item>
+ <item quantity="other">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את קוד האימות.</item>
+ <item quantity="one">נעילת המכשיר לא בוטלה במשך שעה (<xliff:g id="NUMBER_0">%d</xliff:g>). יש להזין את קוד האימות.</item>
</plurals>
<plurals name="kg_prompt_reason_time_password" formatted="false" msgid="5343961527665116914">
<item quantity="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. יש להזין את הסיסמה.</item>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 32759215483a..ed1ea379e5b2 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -46,7 +46,7 @@
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Plaats een simkaart."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"De simkaart ontbreekt of kan niet worden gelezen. Plaats een simkaart."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Onbruikbare simkaart."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"Je simkaart is definitief uitgeschakeld.\n Neem contact op met je mobiele serviceprovider voor een nieuwe simkaart."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"Je simkaart is definitief uitgezet.\n Neem contact op met je mobiele serviceprovider voor een nieuwe simkaart."</string>
<string name="keyguard_sim_locked_message" msgid="4343544458476911044">"Simkaart is vergrendeld."</string>
<string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"Simkaart is vergrendeld met pukcode."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"Simkaart ontgrendelen…"</string>
@@ -71,11 +71,11 @@
<string name="kg_pattern_instructions" msgid="5376036737065051736">"Teken je patroon"</string>
<string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Geef de pincode van de simkaart op."</string>
<string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Geef de pincode voor de simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\' op."</string>
- <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Schakel de e-simkaart uit om het apparaat te gebruiken zonder mobiele service."</string>
+ <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Zet de e-simkaart uit om het apparaat te gebruiken zonder mobiele service."</string>
<string name="kg_pin_instructions" msgid="822353548385014361">"Geef je pincode op"</string>
<string name="kg_password_instructions" msgid="324455062831719903">"Geef je wachtwoord op"</string>
- <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Neem contact op met de provider voor informatie."</string>
- <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"Simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\' is nu uitgeschakeld. Geef de pukcode op om door te gaan. Neem contact op met je provider voor meer informatie."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"De simkaart is nu uitgezet. Geef de pukcode op om door te gaan. Neem contact op met de provider voor informatie."</string>
+ <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"Simkaart van <xliff:g id="CARRIER">%1$s</xliff:g> is nu uitgezet. Geef de pukcode op om door te gaan. Neem contact op met je provider voor meer informatie."</string>
<string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Geef de gewenste pincode op"</string>
<string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Gewenste pincode bevestigen"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"Simkaart ontgrendelen…"</string>
@@ -132,8 +132,8 @@
<item quantity="one">Geef de pincode van de simkaart op. Je hebt nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat je contact met je provider moet opnemen om het apparaat te ontgrendelen.</item>
</plurals>
<plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
- <item quantity="other">De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item>
- <item quantity="one">De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_0">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item>
+ <item quantity="other">De simkaart is nu uitgezet. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item>
+ <item quantity="one">De simkaart is nu uitgezet. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_0">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item>
</plurals>
<string name="clock_title_default" msgid="6342735240617459864">"Standaard"</string>
<string name="clock_title_bubble" msgid="2204559396790593213">"Bel"</string>
diff --git a/packages/SystemUI/res-product/values-iw/strings.xml b/packages/SystemUI/res-product/values-iw/strings.xml
index 4026dac78d2d..a5c7aaa9064f 100644
--- a/packages/SystemUI/res-product/values-iw/strings.xml
+++ b/packages/SystemUI/res-product/values-iw/strings.xml
@@ -21,18 +21,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"צריך ליישר את הטלפון כדי לטעון אותו במהירות"</string>
<string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"צריך ליישר את הטלפון כדי לטעון אותו באופן אלחוטי"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"‏מכשיר Android TV ייכבה בקרוב. יש ללחוץ על לחצן כלשהו כדי שהוא ימשיך לפעול."</string>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"‏מכשיר ה-Android TV ייכבה בקרוב. יש ללחוץ על לחצן כלשהו כדי שהוא ימשיך לפעול."</string>
<string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"המכשיר ייכבה בקרוב, יש ללחוץ כדי שהוא ימשיך לפעול."</string>
<string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"‏אין כרטיס SIM בטאבלט."</string>
<string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"‏אין כרטיס SIM בטלפון."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"קודי האימות אינם תואמים"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"קודי האימות לא תואמים"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, הטאבלט הזה יאופס וכל הנתונים שבו יימחקו."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, טלפון זה יאופס וכל הנתונים שבו יימחקו."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, הטלפון הזה יאופס וכל הנתונים שבו יימחקו."</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים. הטאבלט יאופס וכל הנתונים שלו יימחקו."</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. הטלפון יאופס וכל הנתונים שבו יימחקו."</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, המשתמש הזה יוסר וכל נתוני המשתמש יימחקו."</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, המשתמש הזה יוסר וכל נתוני המשתמש יימחקו."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים באופן שגוי. משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים באופן שגוי. המשתמש הזה יוסר וכל נתוני המשתמש יימחקו."</string>
<string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. המשתמש הזה יוסר וכל נתוני המשתמש יימחקו."</string>
<string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
<string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
index 45d8dc109330..73b02f4fa481 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
@@ -1,37 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+<!--
+ ~ 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.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingMode="stack" >
<item android:id="@android:id/background"
- android:gravity="center_vertical|fill_horizontal">
- <shape android:shape="rectangle"
- android:tint="?android:attr/colorControlActivated">
- <size android:height="@dimen/seek_bar_height" />
- <solid android:color="@color/white_disabled" />
- <corners android:radius="@dimen/seek_bar_corner_radius" />
- </shape>
+ android:gravity="center_vertical|fill_horizontal">
+ <inset
+ android:insetLeft="@dimen/rounded_slider_track_inset"
+ android:insetRight="@dimen/rounded_slider_track_inset" >
+ <shape>
+ <size android:height="@dimen/rounded_slider_track_width" />
+ <corners android:radius="@dimen/rounded_slider_track_corner_radius" />
+ <solid android:color="?android:attr/textColorPrimary" />
+ </shape>
+ </inset>
</item>
<item android:id="@android:id/progress"
android:gravity="center_vertical|fill_horizontal">
- <scale android:scaleWidth="100%">
- <shape android:shape="rectangle"
- android:tint="?android:attr/colorControlActivated">
- <size android:height="@dimen/seek_bar_height" />
- <solid android:color="@android:color/white" />
- <corners android:radius="@dimen/seek_bar_corner_radius" />
- </shape>
- </scale>
+ <com.android.systemui.util.RoundedCornerProgressDrawable
+ android:drawable="@drawable/brightness_progress_full_drawable"
+ />
</item>
-</layer-list>
+</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml
deleted file mode 100644
index 73b02f4fa481..000000000000
--- a/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
- android:paddingMode="stack" >
- <item android:id="@android:id/background"
- android:gravity="center_vertical|fill_horizontal">
- <inset
- android:insetLeft="@dimen/rounded_slider_track_inset"
- android:insetRight="@dimen/rounded_slider_track_inset" >
- <shape>
- <size android:height="@dimen/rounded_slider_track_width" />
- <corners android:radius="@dimen/rounded_slider_track_corner_radius" />
- <solid android:color="?android:attr/textColorPrimary" />
- </shape>
- </inset>
- </item>
- <item android:id="@android:id/progress"
- android:gravity="center_vertical|fill_horizontal">
- <com.android.systemui.util.RoundedCornerProgressDrawable
- android:drawable="@drawable/brightness_progress_full_drawable"
- />
- </item>
-</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout-land/global_actions_column.xml b/packages/SystemUI/res/layout-land/global_actions_column.xml
index 98cb0d0d4c23..bd1acfc56ca6 100644
--- a/packages/SystemUI/res/layout-land/global_actions_column.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_column.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
android:orientation="horizontal"
android:clipToPadding="false"
- android:theme="@style/qs_theme"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
android:gravity="center_horizontal | top"
android:clipChildren="false"
>
diff --git a/packages/SystemUI/res/layout-land/global_actions_column_seascape.xml b/packages/SystemUI/res/layout-land/global_actions_column_seascape.xml
index 5e7604c31731..412beb789deb 100644
--- a/packages/SystemUI/res/layout-land/global_actions_column_seascape.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_column_seascape.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
android:orientation="horizontal"
android:clipToPadding="false"
- android:theme="@style/qs_theme"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
android:gravity="center_horizontal | bottom"
android:clipChildren="false"
>
diff --git a/packages/SystemUI/res/layout-land/global_actions_grid.xml b/packages/SystemUI/res/layout-land/global_actions_grid.xml
index 6a1081239302..da6235ce0682 100644
--- a/packages/SystemUI/res/layout-land/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_grid.xml
@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
- android:theme="@style/qs_theme"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
android:gravity="right | center_vertical"
android:clipChildren="false"
android:clipToPadding="false"
diff --git a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
index 79c51d9576da..e52ad2acadc0 100644
--- a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
- android:theme="@style/qs_theme"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
android:gravity="left | center_vertical"
android:clipChildren="false"
android:clipToPadding="false"
diff --git a/packages/SystemUI/res/layout/global_actions_column.xml b/packages/SystemUI/res/layout/global_actions_column.xml
index b58146b6ce41..0f958a60e8dd 100644
--- a/packages/SystemUI/res/layout/global_actions_column.xml
+++ b/packages/SystemUI/res/layout/global_actions_column.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:clipToPadding="false"
- android:theme="@style/qs_theme"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
android:gravity="center_vertical | right"
android:clipChildren="false"
>
diff --git a/packages/SystemUI/res/layout/global_actions_grid.xml b/packages/SystemUI/res/layout/global_actions_grid.xml
index 456553d404dc..8c621b92a513 100644
--- a/packages/SystemUI/res/layout/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid.xml
@@ -23,7 +23,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:theme="@style/qs_theme"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
index 30ffc32ce1f8..f06a4be5f7b8 100644
--- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
@@ -30,12 +30,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
- <LinearLayout
- android:id="@+id/global_actions_controls"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"/>
-
</LinearLayout>
</com.android.systemui.globalactions.MinHeightScrollView>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_view.xml b/packages/SystemUI/res/layout/global_actions_view.xml
index 454707bc44e2..6773c4911967 100644
--- a/packages/SystemUI/res/layout/global_actions_view.xml
+++ b/packages/SystemUI/res/layout/global_actions_view.xml
@@ -19,7 +19,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:theme="@style/qs_theme"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_marginStart="@dimen/global_actions_side_margin"
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 8b2d4e0a44b9..e775de2d8e06 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -52,8 +52,9 @@
android:id="@+id/preview"
android:layout_width="0px"
android:layout_height="0px"
- android:layout_marginBottom="42dp"
android:paddingHorizontal="48dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="42dp"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="@id/save"
@@ -68,7 +69,8 @@
android:id="@+id/crop_view"
android:layout_width="0px"
android:layout_height="0px"
- android:layout_marginBottom="42dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="42dp"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toTopOf="@id/preview"
diff --git a/packages/SystemUI/res/layout/notification_conversation_info.xml b/packages/SystemUI/res/layout/notification_conversation_info.xml
index fcc1aed65470..112509272e58 100644
--- a/packages/SystemUI/res/layout/notification_conversation_info.xml
+++ b/packages/SystemUI/res/layout/notification_conversation_info.xml
@@ -36,13 +36,62 @@
android:clipChildren="false"
android:paddingTop="@dimen/notification_guts_header_top_padding"
android:clipToPadding="true">
- <ImageView
- android:id="@+id/conversation_icon"
- android:layout_width="@dimen/notification_guts_conversation_icon_size"
- android:layout_height="@dimen/notification_guts_conversation_icon_size"
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
android:layout_centerVertical="false"
android:layout_alignParentStart="true"
- android:layout_marginEnd="12dp" />
+ android:layout_marginEnd="12dp"
+ >
+
+ <!-- Big icon: 52x52, 12dp padding left + top, 16dp padding right -->
+ <ImageView
+ android:id="@+id/conversation_icon"
+ android:layout_width="@*android:dimen/conversation_avatar_size"
+ android:layout_height="@*android:dimen/conversation_avatar_size"
+ android:scaleType="centerCrop"
+ android:importantForAccessibility="no"
+ />
+
+ <FrameLayout
+ android:id="@+id/conversation_icon_badge"
+ android:layout_width="@*android:dimen/conversation_icon_size_badged"
+ android:layout_height="@*android:dimen/conversation_icon_size_badged"
+ android:layout_marginLeft="@*android:dimen/conversation_badge_side_margin"
+ android:layout_marginTop="@*android:dimen/conversation_badge_side_margin"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ >
+ <ImageView
+ android:id="@+id/conversation_icon_badge_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:src="@*android:drawable/conversation_badge_background"
+ android:forceHasOverlappingRendering="false"
+ />
+ <ImageView
+ android:id="@+id/conversation_icon_badge_icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="4dp"
+ android:layout_gravity="center"
+ android:forceHasOverlappingRendering="false"
+ />
+ <ImageView
+ android:id="@+id/conversation_icon_badge_ring"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:src="@*android:drawable/conversation_badge_ring"
+ android:forceHasOverlappingRendering="false"
+ android:clipToPadding="false"
+ android:scaleType="center"
+ />
+ </FrameLayout>
+ </FrameLayout>
<LinearLayout
android:id="@+id/names"
android:layout_weight="1"
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 1ce87c1c0236..f8812ba894fa 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -16,8 +16,9 @@
-->
<com.android.systemui.qs.tileimpl.ButtonRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
+ android:layout_weight="1"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="12dp">
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 9cc09aa42f40..f4d5304d3d0e 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- 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.
@@ -13,69 +13,31 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:layout_gravity="center_vertical"
- style="@style/BrightnessDialogContainer">
+ android:layout_gravity="center">
<com.android.systemui.settings.brightness.BrightnessSliderView
android:id="@+id/brightness_slider"
- android:layout_width="0dp"
+ android:layout_width="match_parent"
android:layout_height="@dimen/brightness_mirror_height"
android:layout_gravity="center_vertical"
- android:layout_weight="1"
android:contentDescription="@string/accessibility_brightness"
- android:importantForAccessibility="no"
- systemui:text="@string/status_bar_settings_auto_brightness_label" >
+ android:importantForAccessibility="no" >
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <CheckBox
- android:id="@+id/toggle"
- android:layout_width="48dp"
- android:layout_height="0dp"
- android:layout_alignParentStart="true"
- android:layout_alignParentTop="true"
- android:layout_alignParentBottom="true"
- android:button="@null"
- android:background="@*android:drawable/switch_track_material"
- android:visibility="gone"
- />
<com.android.systemui.settings.brightness.ToggleSeekBar
android:id="@+id/slider"
- android:layout_width="0dp"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_toEndOf="@id/toggle"
- android:layout_centerVertical="true"
- android:layout_alignParentStart="true"
- android:layout_alignParentEnd="true"
- android:paddingStart="20dp"
- android:paddingEnd="20dp"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
- android:thumb="@drawable/ic_brightness_thumb"
+ android:layout_gravity="center_vertical"
+ android:minHeight="48dp"
+ android:thumb="@null"
+ android:background="@null"
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp"
android:progressDrawable="@drawable/brightness_progress_drawable"
android:splitTrack="false"
/>
- <TextView
- android:id="@+id/label"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_alignStart="@id/toggle"
- android:layout_alignEnd="@id/toggle"
- android:layout_centerVertical="true"
- android:gravity="center"
- android:paddingTop="26dp"
- android:textColor="#666666"
- android:textSize="12sp"
- android:visibility="gone"
- />
-
- </RelativeLayout>
</com.android.systemui.settings.brightness.BrightnessSliderView>
-
-</LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog_thick.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog_thick.xml
deleted file mode 100644
index 6cee38d27876..000000000000
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog_thick.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="center">
-
- <com.android.systemui.settings.brightness.BrightnessSliderView
- android:id="@+id/brightness_slider"
- android:layout_width="match_parent"
- android:layout_height="@dimen/brightness_mirror_height"
- android:layout_gravity="center_vertical"
- android:contentDescription="@string/accessibility_brightness"
- android:importantForAccessibility="no" >
-
- <com.android.systemui.settings.brightness.ToggleSeekBar
- android:id="@+id/slider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:minHeight="48dp"
- android:thumb="@null"
- android:background="@null"
- android:paddingStart="0dp"
- android:paddingEnd="0dp"
- android:progressDrawable="@drawable/brightness_progress_drawable_thick"
- android:splitTrack="false"
- />
- </com.android.systemui.settings.brightness.BrightnessSliderView>
-</FrameLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
index 6f9d7457e245..65f55d0d5903 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
@@ -18,7 +18,7 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/plugin_frame"
- android:theme="@style/qs_theme"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
android:layout_width="@dimen/qs_panel_width"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index df215fad7bf5..0e9b683a3667 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Wekker"</string>
<string name="wallet_title" msgid="5369767670735827105">"Beursie"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Gereed"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuigmodus"</string>
<string name="add_tile" msgid="6239678623873086686">"Voeg teël by"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index da4431d01fcd..5d4853b0135b 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ኤተርኔት"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"ማንቂያ"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"ዝግጁ"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"የስራ መገለጫ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"የአውሮፕላን ሁነታ"</string>
<string name="add_tile" msgid="6239678623873086686">"ሰቅ ያክሉ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index d100430c4edf..5c7cf3bab8c9 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -89,8 +89,7 @@
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"يحظر التطبيق أو تحظر مؤسستك التقاط لقطات شاشة"</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"تعديل"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"تعديل لقطة الشاشة"</string>
- <!-- no translation found for screenshot_scroll_label (2930198809899329367) -->
- <skip />
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"التقاط المزيد من المحتوى"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"إغلاق لقطة الشاشة"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"معاينة لقطة الشاشة"</string>
<string name="screenshot_top_boundary" msgid="1500569103321300856">"الحد العلوي"</string>
@@ -388,11 +387,9 @@
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"قلب الألوان"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"وضع تصحيح الألوان"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"المزيد من الإعدادات"</string>
- <!-- no translation found for quick_settings_more_user_settings (1064187451100861954) -->
- <skip />
+ <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"إعدادات المستخدم"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"تم"</string>
- <!-- no translation found for quick_settings_close_user_panel (5599724542275896849) -->
- <skip />
+ <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>
@@ -545,8 +542,7 @@
<string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"‏هذا الجهاز يخص <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> وتم ربطه بشبكات افتراضية خاصة (VPN)."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"يمكن لمؤسستك مراقبة حركة بيانات الشبكة في الملف الشخصي للعمل"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"يمكن لـ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> مراقبة حركة بيانات الشبكة في ملفك الشخصي للعمل"</string>
- <!-- no translation found for quick_settings_disclosure_managed_profile_network_activity (2636594621387832827) -->
- <skip />
+ <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"تكون أنشطة شبكة الملف الشخصي للعمل مرئية لمشرف تكنولوجيا المعلومات."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"قد تكون الشبكة خاضعة للمراقبة"</string>
<string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"‏تم ربط هذا الجهاز بشبكات افتراضية خاصة (VPN)."</string>
<string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"تم ربط الملف الشخصي للعمل بشبكة <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
@@ -676,7 +672,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"إيثرنت"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"المنبّه"</string>
<string name="wallet_title" msgid="5369767670735827105">"المحفظة"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"جاهزة"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"الملف الشخصي للعمل"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطيران"</string>
<string name="add_tile" msgid="6239678623873086686">"إضافة فئة"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 08824be444e5..d9a8c6a19bb5 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ইথাৰনেট"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"এলাৰ্ম"</string>
<string name="wallet_title" msgid="5369767670735827105">"ৱালেট"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"সাজু"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"এয়াৰপ্লেইন ম\'ড"</string>
<string name="add_tile" msgid="6239678623873086686">"টাইল যোগ দিয়ক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index eb2f7aa1d02d..75e8aa13cc7b 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Zəngli saat"</string>
<string name="wallet_title" msgid="5369767670735827105">"Pulqabı"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Hazır"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"İş profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Təyyarə rejimi"</string>
<string name="add_tile" msgid="6239678623873086686">"Xana əlavə edin"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 2f2ca09c2d8d..283d97675e82 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -663,7 +663,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Eternet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Spremno"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Režim rada u avionu"</string>
<string name="add_tile" msgid="6239678623873086686">"Dodaj pločicu"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 4386e554f729..32b75785d3d9 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -379,7 +379,7 @@
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Прылада без назвы"</string>
<string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"Гатова для трансляцыі"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Няма даступных прылад"</string>
- <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi-Fi не падключаны"</string>
+ <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Няма падключэння да Wi-Fi"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яркасць"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"АЎТА"</string>
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"Інвертаваць колеры"</string>
@@ -666,7 +666,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Будзільнік"</string>
<string name="wallet_title" msgid="5369767670735827105">"Кашалёк"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Гатова"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Працоўны профіль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Рэжым палёту"</string>
<string name="add_tile" msgid="6239678623873086686">"Дадаць плітку"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 929ec21526b0..31ae63fb2fbd 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Будилник"</string>
<string name="wallet_title" msgid="5369767670735827105">"Портфейл"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Готово"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Потребителски профил в Work"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Самолетен режим"</string>
<string name="add_tile" msgid="6239678623873086686">"Добавяне на плочка"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index cf68ab7332b6..0e18e8fd286d 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -89,8 +89,7 @@
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"এই অ্যাপ বা আপনার প্রতিষ্ঠান স্ক্রিনশট নেওয়ার অনুমতি দেয়নি"</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"এডিট করুন"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"স্ক্রিনশট এডিট করুন"</string>
- <!-- no translation found for screenshot_scroll_label (2930198809899329367) -->
- <skip />
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"আরও বেশি ক্যাপচার করুন"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"স্ক্রিনশট বাতিল করুন"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"স্ক্রিনশটের প্রিভিউ"</string>
<string name="screenshot_top_boundary" msgid="1500569103321300856">"স্ক্রিনশটের একদম উপরের দিকে"</string>
@@ -384,11 +383,9 @@
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"বিপরীত রঙ"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"রঙ সংশোধন মোড"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"আরও সেটিংস"</string>
- <!-- no translation found for quick_settings_more_user_settings (1064187451100861954) -->
- <skip />
+ <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"ব্যবহারকারী সেটিংস"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"সম্পন্ন হয়েছে"</string>
- <!-- no translation found for quick_settings_close_user_panel (5599724542275896849) -->
- <skip />
+ <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>
@@ -533,8 +530,7 @@
<string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"এই ডিভাইস <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-এর এবং একাধিক VPN-এ কানেক্ট করা আছে"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"আপনার প্রতিষ্ঠান আপনার কর্মস্থলের প্রোফাইলের নেটওয়ার্ক ট্রাফিকে নজর রাখতে পারে"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> আপনার কর্মস্থলের প্রোফাইলের নেটওয়ার্ক ট্রাফিকে নজর রাখতে পারে"</string>
- <!-- no translation found for quick_settings_disclosure_managed_profile_network_activity (2636594621387832827) -->
- <skip />
+ <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"আপনার আইটি অ্যাডমিন অফিস প্রোফাইল নেটওয়ার্ক অ্যাক্টিভিটি দেখতে পারবেন"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"নেটওয়ার্কের উপরে নজর রাখা হতে পারে"</string>
<string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"এই ডিভাইস একাধিক VPN-এ কানেক্ট করা আছে"</string>
<string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এ আপনার অফিস প্রোফাইল কানেক্ট করা রয়েছে"</string>
@@ -664,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ইথারনেট"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"অ্যালার্ম"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"তৈরি"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"কাজের প্রোফাইল"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"বিমান মোড"</string>
<string name="add_tile" msgid="6239678623873086686">"টাইল যোগ করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index e22790daac50..c7820f4f979c 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -663,7 +663,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Spremno"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil za posao"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Način rada u avionu"</string>
<string name="add_tile" msgid="6239678623873086686">"Dodaj pločicu"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 7e523b429bee..1546113289e9 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"A punt"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de treball"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode d\'avió"</string>
<string name="add_tile" msgid="6239678623873086686">"Afegeix un mosaic"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 5cde6bb096f7..72633914c72f 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -666,7 +666,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Budík"</string>
<string name="wallet_title" msgid="5369767670735827105">"Peněženka"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Připraveno"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Pracovní profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Režim Letadlo"</string>
<string name="add_tile" msgid="6239678623873086686">"Přidat dlaždici"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 50a68f9b8992..9348a1c9fc31 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Afvis"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sæt fingeren på fingeraftrykslæseren"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikon for fingeraftryk"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansigtet kan ikke genkendes. Brug fingeraftryk i stedet."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Brug dit fingeraftryk for at fortsætte"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Fingeraftrykket kan ikke genkendes. Brug skærmlåsen i stedet."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Forsøger at finde dig…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Ansigt"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Knap for kompatibilitetszoom."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Klar"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Arbejdsprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flytilstand"</string>
<string name="add_tile" msgid="6239678623873086686">"Tilføj et felt"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Samtalewidgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tryk på en samtale for at føje den til din startskærm"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Vend tilbage hertil, når du har fået beskeder"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Prioriterede samtaler"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Seneste samtaler"</string>
+ <string name="okay" msgid="6490552955618608554">"Okay"</string>
<string name="timestamp" msgid="6577851592534538533">"For <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"For mindre end <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
<string name="over_timestamp" msgid="4765793502859358634">"For mere end <xliff:g id="DURATION">%1$s</xliff:g> siden"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index ef3cf2130064..f163be85edef 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Weckruf"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Bereit"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Arbeitsprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flugmodus"</string>
<string name="add_tile" msgid="6239678623873086686">"Kachel hinzufügen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index a49b6498f44e..4dad056d6457 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Παράβλεψη"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Αγγίξτε τον αισθητήρα δακτυλικού αποτυπώματος"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Το πρόσωπο δεν αναγνωρίζεται. Χρησιμ. δακτ. αποτ."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Χρησιμοποιήστε δακτυλ. αποτύπωμα για να συνεχίσετε"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Δεν είναι δυνατή η αναγνώριση του δακτυλικού αποτυπώματος. Χρησιμοποιήστε εναλλακτικά το κλείδωμα οθόνης."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Αναζήτηση για εσάς…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Εικονίδιο προσώπου"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Κουμπί εστίασης συμβατότητας."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Ξυπνητήρι"</string>
<string name="wallet_title" msgid="5369767670735827105">"Πορτοφόλι"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Έτοιμο"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Προφίλ εργασίας"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Λειτουργία πτήσης"</string>
<string name="add_tile" msgid="6239678623873086686">"Προσθήκη πλακιδίου"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Γραφικά στοιχεία συνομιλίας"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Πατήστε μια συνομιλία για να την προσθέσετε στην αρχική οθόνη"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Ελέγξτε ξανά εδώ όταν λάβετε ορισμένα μηνύματα"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Συζητήσεις προτεραιότητας"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Πρόσφατες συζητήσεις"</string>
+ <string name="okay" msgid="6490552955618608554">"Εντάξει"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> πριν"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Λιγότερο από <xliff:g id="DURATION">%1$s</xliff:g> πριν"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Περισσότερο από <xliff:g id="DURATION">%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 bd9a0605cdeb..7ee13836bb1c 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -657,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Ready"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
<string name="add_tile" msgid="6239678623873086686">"Add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 2158ed849858..0dfe75b48125 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -657,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Ready"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Airplane mode"</string>
<string name="add_tile" msgid="6239678623873086686">"Add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index bd9a0605cdeb..7ee13836bb1c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -657,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Ready"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
<string name="add_tile" msgid="6239678623873086686">"Add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index bd9a0605cdeb..7ee13836bb1c 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -657,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Ready"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
<string name="add_tile" msgid="6239678623873086686">"Add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 3ed7688ba9c0..588b2cc79d97 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -657,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎Ethernet‎‏‎‎‏‎"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎Alarm‎‏‎‎‏‎"</string>
<string name="wallet_title" msgid="5369767670735827105">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎Wallet‎‏‎‎‏‎"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‏‏‎Ready‎‏‎‎‏‎"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎Work profile‎‏‎‎‏‎"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎Airplane mode‎‏‎‎‏‎"</string>
<string name="add_tile" msgid="6239678623873086686">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎Add tile‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 6bb486da10f9..290b3b34e3a1 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Descartar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca el sensor de huellas dactilares"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ícono de huella dactilar"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"No se reconoce el rostro. Usa la huella dactilar."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Utiliza tu huella dactilar para continuar"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"No se reconoce la huella dactilar. Utiliza el bloqueo de pantalla en su lugar."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Autenticando tu rostro…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Ícono de rostro"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Botón de zoom de compatibilidad"</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Listo"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avión"</string>
<string name="add_tile" msgid="6239678623873086686">"Agregar mosaico"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Presiona una conversación para agregarla a tu pantalla principal"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Vuelve a consultar cuando recibas algunos mensajes"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Conversaciones prioritarias"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Conversaciones recientes"</string>
+ <string name="okay" msgid="6490552955618608554">"Aceptar"</string>
<string name="timestamp" msgid="6577851592534538533">"Hace <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Hace menos de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Hace más de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 9d6e3fa85a92..9d96e1850263 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Listo"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avión"</string>
<string name="add_tile" msgid="6239678623873086686">"Añadir icono"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 14aed4ef7efd..9471baa87cbe 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Äratus"</string>
<string name="wallet_title" msgid="5369767670735827105">"Rahakott"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Valmis"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Tööprofiil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lennukirežiim"</string>
<string name="add_tile" msgid="6239678623873086686">"Paani lisamine"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 2f1c7a585c07..a07851100fe1 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Prest"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Work profila"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Hegaldi modua"</string>
<string name="add_tile" msgid="6239678623873086686">"Gehitu lauza"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 6eba9af6690b..21592bc7c6b6 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"اترنت"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"زنگ"</string>
<string name="wallet_title" msgid="5369767670735827105">"کیف‌پول"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"آماده"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"نمایه کاری"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"حالت هواپیما"</string>
<string name="add_tile" msgid="6239678623873086686">"افزودن کاشی"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 31a54baf396a..36a17bf69a9a 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Herätys"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Valmis"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Työprofiili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lentokonetila"</string>
<string name="add_tile" msgid="6239678623873086686">"Lisää ruutu"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 838b699b7882..d483a8f3a7e3 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -89,8 +89,7 @@
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran"</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string>
- <!-- no translation found for screenshot_scroll_label (2930198809899329367) -->
- <skip />
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturer plus"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Fermer la capture d\'écran"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Aperçu de la capture d\'écran"</string>
<string name="screenshot_top_boundary" msgid="1500569103321300856">"Limite supérieure"</string>
@@ -384,11 +383,9 @@
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"Inverser les couleurs"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"Mode de correction des couleurs"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"Plus de paramètres"</string>
- <!-- no translation found for quick_settings_more_user_settings (1064187451100861954) -->
- <skip />
+ <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"Paramètres utilisateur"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"Terminé"</string>
- <!-- no translation found for quick_settings_close_user_panel (5599724542275896849) -->
- <skip />
+ <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fermer"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"Connecté"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Connecté. Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"Connexion en cours…"</string>
@@ -533,8 +530,7 @@
<string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à des RPV"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Votre organisation peut contrôler le trafic réseau dans votre profil professionnel"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> peut contrôler votre trafic réseau dans votre profil professionnel"</string>
- <!-- no translation found for quick_settings_disclosure_managed_profile_network_activity (2636594621387832827) -->
- <skip />
+ <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Votre administrateur informatique a accès à l\'activité sur le réseau de votre profil professionnel"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Le réseau peut être surveillé"</string>
<string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Cet appareil est connecté à des RPV"</string>
<string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Votre profil professionnel est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -664,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Prêt"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string>
<string name="add_tile" msgid="6239678623873086686">"Ajouter la tuile"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index cba45cd19f50..6054fb8a0738 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Prêt"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string>
<string name="add_tile" msgid="6239678623873086686">"Ajouter un bloc"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index ac792e375f1e..020e4b0c5ed2 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Listo"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de traballo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avión"</string>
<string name="add_tile" msgid="6239678623873086686">"Engade un atallo"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index e178bb4104be..fd3c0eece8e6 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ઇથરનેટ"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"એલાર્મ"</string>
<string name="wallet_title" msgid="5369767670735827105">"વૉલેટ"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"તૈયાર છે"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ઑફિસની પ્રોફાઇલ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"એરપ્લેન મોડ"</string>
<string name="add_tile" msgid="6239678623873086686">"ટાઇલ ઉમેરો"</string>
diff --git a/packages/SystemUI/res/values-h740dp-port/dimens.xml b/packages/SystemUI/res/values-h740dp-port/dimens.xml
index 4a23ee637e2d..966066ffe56b 100644
--- a/packages/SystemUI/res/values-h740dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-h740dp-port/dimens.xml
@@ -19,9 +19,9 @@
<dimen name="qs_tile_margin_vertical">24dp</dimen>
<!-- The height of the qs customize header. Should be
- (qs_panel_padding_top (48dp) + brightness_mirror_height (56dp) + qs_tile_margin_top (18dp)) -
+ (qs_panel_padding_top (48dp) + brightness_mirror_height (48dp) + qs_tile_margin_top (18dp)) -
(Toolbar_minWidth (56dp) + qs_tile_margin_top_bottom (12dp))
-->
- <dimen name="qs_customize_header_min_height">54dp</dimen>
+ <dimen name="qs_customize_header_min_height">46dp</dimen>
<dimen name="qs_tile_margin_top">18dp</dimen>
</resources> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 54a56fcc8467..4e796fecaf17 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ईथरनेट"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string>
<string name="wallet_title" msgid="5369767670735827105">"वॉलेट"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"तैयार"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"वर्क प्रोफ़ाइल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"हवाई जहाज़ मोड"</string>
<string name="add_tile" msgid="6239678623873086686">"टाइल जोड़ें"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index abf4312302b8..39bef2b220ae 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -663,7 +663,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Spremno"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Način rada u zrakoplovu"</string>
<string name="add_tile" msgid="6239678623873086686">"Dodavanje pločice"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index bd75c0839d52..229ddca74477 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Ébresztés"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Kész"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Munkahelyi profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Repülős üzemmód"</string>
<string name="add_tile" msgid="6239678623873086686">"Mozaik hozzáadása"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 282a2ae1111f..59eefc1975c1 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -89,7 +89,7 @@
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում սքրինշոթի ստացումը"</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"Փոփոխել"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Փոփոխել սքրինշոթը"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Նկարեք ավելի մեծ տարածք"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Մեծացնել սքրինշոթի տարածքը"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Փակել սքրինշոթը"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Սքրինշոթի նախադիտում"</string>
<string name="screenshot_top_boundary" msgid="1500569103321300856">"Վերևի սահմանագիծ"</string>
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Զարթուցիչ"</string>
<string name="wallet_title" msgid="5369767670735827105">"Դրամապանակ"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Պատրաստ է"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Android for Work-ի պրոֆիլ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Ավիառեժիմ"</string>
<string name="add_tile" msgid="6239678623873086686">"Սալիկի ավելացում"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 4872a6ebd7ed..33df4ef06694 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Siap"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil kerja"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode pesawat"</string>
<string name="add_tile" msgid="6239678623873086686">"Tambahkan ubin"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 5915c41c9cda..8498676b6753 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Loka"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Snertu fingrafaralesarann"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingrafaratákn"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Andlit þekkist ekki. Notaðu fingrafar í staðinn."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Notaðu fingrafarið þitt til að halda áfram"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Fingrafar þekkist ekki. Notaðu skjálás í staðinn."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Leitar að þér ..."</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Andlitstákn"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Hnappur fyrir samhæfisaðdrátt."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Vekjari"</string>
<string name="wallet_title" msgid="5369767670735827105">"Veski"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Tilbúið"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Vinnusnið"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flugstilling"</string>
<string name="add_tile" msgid="6239678623873086686">"Bæta reit við"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Samtalsgræjur"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Ýttu á samtal til að bæta því á heimaskjáinn"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Komdu aftur hingað þegar þú hefur fengið skilaboð"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Forgangssamtöl"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Nýleg samtöl"</string>
+ <string name="okay" msgid="6490552955618608554">"Í lagi"</string>
<string name="timestamp" msgid="6577851592534538533">"Fyrir <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Fyrir minna en <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Fyrir meira en <xliff:g id="DURATION">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 3adf868006e2..306ce1fe29c7 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ignora"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Tocca il sensore di impronte"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Icona dell\'impronta"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Impossibile riconoscere il volto. Usa l\'impronta."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Utilizza la tua impronta per continuare"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Impossibile riconoscere l\'impronta. Usa il blocco schermo."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"In attesa del volto…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Icona volto"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Pulsante zoom compatibilità."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Sveglia"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Pronto"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profilo di lavoro"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modalità aereo"</string>
<string name="add_tile" msgid="6239678623873086686">"Aggiungi riquadro"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widget di conversazione"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tocca una conversazione per aggiungerla alla schermata Home"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Torna qui dopo aver ricevuto qualche messaggio"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Conversazioni prioritarie"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Conversazioni recenti"</string>
+ <string name="okay" msgid="6490552955618608554">"OK"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> fa"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Meno di <xliff:g id="DURATION">%1$s</xliff:g> fa"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Più di <xliff:g id="DURATION">%1$s</xliff:g> fa"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index e934e7bc4d05..8f00b73576fc 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -44,28 +44,28 @@
<string name="status_bar_settings_auto_brightness_label" msgid="2151934479226017725">"אוטומטי"</string>
<string name="status_bar_settings_notifications" msgid="5285316949980621438">"התראות"</string>
<string name="bluetooth_tethered" msgid="4171071193052799041">"‏ה-Bluetooth שותף"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="2972273031043777851">"הגדר שיטות קלט"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="2972273031043777851">"הגדרת שיטות קלט"</string>
<string name="status_bar_use_physical_keyboard" msgid="4849251850931213371">"מקלדת פיזית"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"לתת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"‏האם לאפשר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nאפליקציה זו לא קיבלה הרשאה להקליט אך יכולה לתעד אודיו באמצעות מכשיר USB זה."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"האם לתת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"האם לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> כדי לעבוד עם <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"‏לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> לטיפול בהתקן <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nהאפליקציה הזו לא קיבלה הרשאה להקליט אך היא יכולה לתעד אודיו באמצעות התקן ה-USB הזה."</string>
- <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"האם לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> כדי לעבוד עם <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"‏אין אפליקציות מותקנות הפועלות עם אביזר ה-USB. למידע נוסף על אביזר זה היכנס לכתובת <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> כדי לעבוד עם <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
+ <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"‏אין אפליקציות מותקנות הפועלות עם אביזר ה-USB. למידע נוסף על האביזר הזה: <xliff:g id="URL">%1$s</xliff:g>"</string>
<string name="title_usb_accessory" msgid="1236358027511638648">"‏אביזר USB"</string>
- <string name="label_view" msgid="6815442985276363364">"הצג"</string>
- <string name="always_use_device" msgid="210535878779644679">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> תמיד תיפתח כשהאביזר <xliff:g id="USB_DEVICE">%2$s</xliff:g> יחובר"</string>
+ <string name="label_view" msgid="6815442985276363364">"הצגה"</string>
+ <string name="always_use_device" msgid="210535878779644679">"תמיד לפתוח את האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> כשההתקן <xliff:g id="USB_DEVICE">%2$s</xliff:g> מחובר"</string>
<string name="always_use_accessory" msgid="1977225429341838444">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> תמיד תיפתח כשההתקן <xliff:g id="USB_ACCESSORY">%2$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>
<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\nכתובת Wi‑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>
@@ -74,15 +74,15 @@
<string name="usb_port_enabled" msgid="531823867664717018">"‏יציאת USB הופעלה לזיהוי מטענים ואביזרים"</string>
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"‏הפעלת USB"</string>
<string name="learn_more" msgid="4690632085667273811">"מידע נוסף"</string>
- <string name="compat_mode_on" msgid="4963711187149440884">"הגדל תצוגה כדי למלא את המסך"</string>
+ <string name="compat_mode_on" msgid="4963711187149440884">"הגדלת התצוגה למילוי המסך"</string>
<string name="compat_mode_off" msgid="7682459748279487945">"מתיחה למילוי של המסך"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"צילום מסך"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"נשלחה תמונה"</string>
<string name="screenshot_saving_ticker" msgid="6519186952674544916">"צילום המסך נשמר..."</string>
- <string name="screenshot_saving_title" msgid="2298349784913287333">"שומר צילום מסך..."</string>
+ <string name="screenshot_saving_title" msgid="2298349784913287333">"המערכת שומרת את צילום המסך..."</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"צילום המסך נשמר"</string>
<string name="screenshot_saved_text" msgid="7778833104901642442">"אפשר להקיש כדי להציג את צילום המסך"</string>
- <string name="screenshot_failed_title" msgid="3259148215671936891">"לא ניתן היה לשמור צילום מסך"</string>
+ <string name="screenshot_failed_title" msgid="3259148215671936891">"לא ניתן היה לשמור את צילום המסך"</string>
<string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"כדי שצילום המסך יישמר, צריך לבטל את הנעילה של המכשיר"</string>
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"אפשר לצלם שוב את המסך"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"לא ניתן לשמור את צילום המסך"</string>
@@ -124,7 +124,7 @@
<string name="use_mtp_button_title" msgid="5036082897886518086">"‏טעינה כנגן מדיה (MTP)"</string>
<string name="use_ptp_button_title" msgid="7676427598943446826">"‏טעינה כמצלמה (PTP)"</string>
<string name="installer_cd_button_title" msgid="5499998592841984743">"‏התקנת האפליקציה \'העברת קבצים ב-Android\' עבור Mac"</string>
- <string name="accessibility_back" msgid="6530104400086152611">"הקודם"</string>
+ <string name="accessibility_back" msgid="6530104400086152611">"חזרה"</string>
<string name="accessibility_home" msgid="5430449841237966217">"בית"</string>
<string name="accessibility_menu" msgid="2701163794470513040">"תפריט"</string>
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"נגישות"</string>
@@ -135,14 +135,14 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"טלפון"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"האסיסטנט"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"ביטול נעילה"</string>
- <string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"ממתין לטביעת אצבע"</string>
- <string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"בטל את הנעילה בלי להשתמש בטביעת האצבע"</string>
+ <string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"בהמתנה לטביעת אצבע"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"ביטול הנעילה בלי להשתמש בטביעת האצבע"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"סורק פנים"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"שליחה"</string>
<string name="accessibility_manage_notification" msgid="582215815790143983">"ניהול התראות"</string>
- <string name="phone_label" msgid="5715229948920451352">"פתח את הטלפון"</string>
+ <string name="phone_label" msgid="5715229948920451352">"פתיחת הטלפון"</string>
<string name="voice_assist_label" msgid="3725967093735929020">"פתיחת האסיסטנט"</string>
- <string name="camera_label" msgid="8253821920931143699">"פתח את המצלמה"</string>
+ <string name="camera_label" msgid="8253821920931143699">"פתיחת המצלמה"</string>
<string name="cancel" msgid="1089011503403416730">"ביטול"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"אישור"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ניסיון נוסף"</string>
@@ -150,7 +150,7 @@
<string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"יש לנסות שוב"</string>
<string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"המערכת מחפשת את הפנים שלך"</string>
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"זיהוי הפנים בוצע"</string>
- <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"מאושר"</string>
+ <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"יש אישור"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"יש להקיש על \'אישור\' לסיום התהליך"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"שימוש בקוד אימות"</string>
@@ -183,7 +183,7 @@
<skip />
<!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
<skip />
- <string name="face_dialog_looking_for_face" msgid="2656848512116189509">"מחפש אותך…"</string>
+ <string name="face_dialog_looking_for_face" msgid="2656848512116189509">"מתבצע חיפוש…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"סמל הפנים"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"לחצן מרחק מתצוגה של תאימות."</string>
<string name="accessibility_compatibility_zoom_example" msgid="2617218726091234073">"שינוי מרחק מתצוגה של מסך קטן לגדול יותר."</string>
@@ -196,7 +196,7 @@
<string name="accessibility_battery_full" msgid="1480463938961288494">"סוללה מלאה."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"אחוז טעינת הסוללה לא ידוע."</string>
<string name="accessibility_wifi_name" msgid="4863440268606851734">"התבצע חיבור אל <xliff:g id="WIFI">%s</xliff:g>."</string>
- <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"מחובר אל <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
+ <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"התבצע חיבור אל <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"מחובר אל <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_no_wimax" msgid="2014864207473859228">"‏ללא WiMAX."</string>
<string name="accessibility_wimax_one_bar" msgid="2996915709342221412">"‏פס אחד של WiMAX."</string>
@@ -242,7 +242,7 @@
<skip />
<!-- no translation found for accessibility_work_mode (1280025758672376313) -->
<skip />
- <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"התראה נדחתה."</string>
+ <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ההתראה נסגרה."</string>
<string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"לוח התראות."</string>
<string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"הגדרות מהירות."</string>
<string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"מסך נעילה."</string>
@@ -262,8 +262,8 @@
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"השתקה מוחלטת"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"רק התראות"</string>
<string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"נא לא להפריע."</string>
- <string name="accessibility_quick_settings_dnd_changed_off" msgid="1457150026842505799">"\'נא לא להפריע\' כבוי."</string>
- <string name="accessibility_quick_settings_dnd_changed_on" msgid="186315911607486129">"\'נא לא להפריע\' פועל."</string>
+ <string name="accessibility_quick_settings_dnd_changed_off" msgid="1457150026842505799">"התכונה \'נא לא להפריע\' כבויה."</string>
+ <string name="accessibility_quick_settings_dnd_changed_on" msgid="186315911607486129">"התכונה \'נא לא להפריע\' פועלת."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_off" msgid="3795983516942423240">"‏Bluetooth כבוי."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"‏Bluetooth מופעל."</string>
@@ -271,10 +271,10 @@
<string name="accessibility_quick_settings_bluetooth_connected" msgid="5237625393869747261">"‏Bluetooth מחובר."</string>
<string name="accessibility_quick_settings_bluetooth_changed_off" msgid="3344226652293797283">"‏Bluetooth נכבה."</string>
<string name="accessibility_quick_settings_bluetooth_changed_on" msgid="1263282011749437549">"‏Bluetooth הופעל."</string>
- <string name="accessibility_quick_settings_location_off" msgid="6122523378294740598">"דיווח מיקום כבוי."</string>
+ <string name="accessibility_quick_settings_location_off" msgid="6122523378294740598">"התכונה \'דיווח מיקום\' כבויה."</string>
<string name="accessibility_quick_settings_location_on" msgid="6869947200325467243">"התכונה \'דיווח מיקום\' מופעלת."</string>
- <string name="accessibility_quick_settings_location_changed_off" msgid="5132776369388699133">"דיווח מיקום נכבה."</string>
- <string name="accessibility_quick_settings_location_changed_on" msgid="7159115433070112154">"דיווח מיקום הופעל."</string>
+ <string name="accessibility_quick_settings_location_changed_off" msgid="5132776369388699133">"התכונה \'דיווח מיקום\' הושבתה."</string>
+ <string name="accessibility_quick_settings_location_changed_on" msgid="7159115433070112154">"התכונה \'דיווח מיקום\' הופעלה."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ההתראה נקבעה ל-<xliff:g id="TIME">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_close" msgid="2974895537860082341">"סגירת הלוח."</string>
<string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"יותר זמן."</string>
@@ -303,7 +303,7 @@
<string name="data_usage_disabled_dialog_4g_title" msgid="1490779000057752281">"‏השימוש בנתוני 4G מושהה"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"חבילת הגלישה מושהה"</string>
<string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"השימוש בנתונים מושהה"</string>
- <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"הגעת למגבלת הנתונים שהגדרת. אתה כבר לא משתמש בחבילת גלישה.\n\nאם תמשיך, ייתכנו חיובים על שימוש בנתונים."</string>
+ <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"הגעת למגבלת הנתונים שהגדרת. כבר לא נעשה שימוש בחבילת הגלישה.\n\nהמשך הפעולה עשוי לגרום לחיובים על שימוש בנתונים."</string>
<string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"המשך"</string>
<string name="gps_notification_searching_text" msgid="231304732649348313">"‏מחפש GPS"</string>
<string name="gps_notification_found_text" msgid="3145873880174658526">"‏המיקום מוגדר על ידי GPS"</string>
@@ -324,11 +324,11 @@
<string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"המסך נעול עכשיו לרוחב."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"המסך נעול כעת לאורך."</string>
<string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"המסך יסתובב עכשיו באופן אוטומטי."</string>
- <string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"המסך נעול כעת לרוחב."</string>
+ <string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"המסך נעול עכשיו לרוחב."</string>
<string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"המסך נעול כעת לאורך."</string>
<string name="dessert_case" msgid="9104973640704357717">"מזנון קינוחים"</string>
<string name="start_dreams" msgid="9131802557946276718">"שומר מסך"</string>
- <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+ <string name="ethernet_label" msgid="2203544727007463351">"אתרנט"</string>
<string name="quick_settings_header_onboarding_text" msgid="1918085351115504765">"יש ללחוץ על הסמלים לחיצה ארוכה כדי לראות אפשרויות נוספות"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"נא לא להפריע"</string>
<string name="quick_settings_dnd_priority_label" msgid="6251076422352664571">"עדיפות בלבד"</string>
@@ -375,9 +375,9 @@
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"‏אין רשתות Wi-Fi זמינות"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"בתהליך הפעלה…"</string>
<string name="quick_settings_cast_title" msgid="2279220930629235211">"העברת מסך"</string>
- <string name="quick_settings_casting" msgid="1435880708719268055">"מעביר"</string>
+ <string name="quick_settings_casting" msgid="1435880708719268055">"‏מתבצעת העברה (cast)"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"מכשיר ללא שם"</string>
- <string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"מוכן להעביר"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"‏המכשיר מוכן להעברה (cast)"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"אין מכשירים זמינים"</string>
<string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"‏אין חיבור ל-Wi-Fi"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"בהירות"</string>
@@ -389,8 +389,8 @@
<string name="quick_settings_done" msgid="2163641301648855793">"בוצע"</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>
+ <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"המכשיר מחובר. סוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="quick_settings_connecting" msgid="2381969772953268809">"מתבצע חיבור..."</string>
<string name="quick_settings_tethering_label" msgid="5257299852322475780">"שיתוף אינטרנט בין מכשירים"</string>
<string name="quick_settings_hotspot_label" msgid="1199196300038363424">"‏נקודת אינטרנט (hotspot)"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ההפעלה מתבצעת…"</string>
@@ -410,7 +410,7 @@
<string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"חריגה מהמגבלה"</string>
<string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"<xliff:g id="DATA_USED">%s</xliff:g> בשימוש"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"הגבלה של <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"אזהרה - <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+ <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"אזהרה – <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_work_mode_label" msgid="2754212289804324685">"פרופיל עבודה"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"תאורת לילה"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"התכונה מופעלת בשקיעה"</string>
@@ -435,9 +435,9 @@
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"יש להחליק מעלה כדי להחליף אפליקציות"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"יש לגרור ימינה כדי לעבור במהירות בין אפליקציות"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"החלפת מצב של מסכים אחרונים"</string>
- <string name="expanded_header_battery_charged" msgid="5307907517976548448">"טעון"</string>
+ <string name="expanded_header_battery_charged" msgid="5307907517976548448">"הסוללה טעונה"</string>
<string name="expanded_header_battery_charging" msgid="1717522253171025549">"בטעינה"</string>
- <string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"<xliff:g id="CHARGING_TIME">%s</xliff:g> עד למילוי"</string>
+ <string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"<xliff:g id="CHARGING_TIME">%s</xliff:g> לטעינה מלאה"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"לא בטעינה"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"ייתכן שהרשת\nמנוטרת"</string>
<string name="description_target_search" msgid="3875069993128855865">"חיפוש"</string>
@@ -446,7 +446,7 @@
<string name="zen_priority_introduction" msgid="3159291973383796646">"כדי לא להפריע לך, המכשיר לא ירטוט ולא ישמיע שום צליל, חוץ מהתראות, תזכורות, אירועים ושיחות ממתקשרים מסוימים לבחירתך. המצב הזה לא ישפיע על צלילים שהם חלק מתוכן שבחרת להפעיל, כמו מוזיקה, סרטונים ומשחקים."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"כדי לא להפריע לך, המכשיר לא ירטוט ולא ישמיע שום צליל, חוץ מהתראות. המצב הזה לא ישפיע על צלילים שהם חלק מתוכן שבחרת להפעיל, כמו מוזיקה, סרטונים ומשחקים."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"התאמה אישית"</string>
- <string name="zen_silence_introduction_voice" msgid="853573681302712348">"פעולה זו מבטלת את כל הצלילים והרטט, כולל צלילים ורטט שמקורם בהתראות, מוזיקה, סרטונים ומשחקים. בכל מקרה, עדיין אפשר להתקשר."</string>
+ <string name="zen_silence_introduction_voice" msgid="853573681302712348">"הפעולה הזו מבטלת את כל הצלילים והרטט, כולל צלילים ורטט שמקורם בהתראות, מוזיקה, סרטונים ומשחקים. עדיין ניתן לבצע שיחות."</string>
<string name="zen_silence_introduction" msgid="6117517737057344014">"הפעולה הזו מבטלת את כל הצלילים והרטט, כולל בהתראות, מוזיקה, סרטונים ומשחקים."</string>
<string name="keyguard_more_overflow_text" msgid="5819512373606638727">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="7248696377626341060">"התראות בדחיפות נמוכה יותר מופיעות בהמשך"</string>
@@ -457,10 +457,10 @@
<string name="do_disclosure_generic" msgid="4896482821974707167">"המכשיר הזה שייך לארגון שלך"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"המכשיר הזה התקבל מ-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <string name="phone_hint" msgid="6682125338461375925">"החלק מהסמל כדי להפעיל את הטלפון"</string>
+ <string name="phone_hint" msgid="6682125338461375925">"צריך להחליק מהסמל כדי להפעיל את הטלפון"</string>
<string name="voice_hint" msgid="7476017460191291417">"יש להחליק מהסמל כדי להפעיל את האסיסטנט"</string>
<string name="camera_hint" msgid="4519495795000658637">"צריך להחליק מהסמל כדי להפעיל את המצלמה"</string>
- <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"שקט מוחלט. הגדרה זו תשתיק גם קוראי מסך."</string>
+ <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"שקט מוחלט. ההגדרה הזו תשתיק גם קוראי מסך."</string>
<string name="interruption_level_none" msgid="219484038314193379">"שקט מוחלט"</string>
<string name="interruption_level_priority" msgid="661294280016622209">"עדיפות בלבד"</string>
<string name="interruption_level_alarms" msgid="2457850481335846959">"התראות בלבד"</string>
@@ -472,26 +472,26 @@
<string name="keyguard_indication_charging_time_fast" msgid="7895986003578341126">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • בטעינה מהירה (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> עד לסיום)"</string>
<string name="keyguard_indication_charging_time_slowly" msgid="245442950133408398">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • בטעינה איטית (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> עד לסיום)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"החלפת משתמש"</string>
- <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"החלף משתמש. המשתמש הנוכחי הוא <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"החלפת משתמש. המשתמש הנוכחי: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"משתמש נוכחי <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
- <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"הצג פרופיל"</string>
+ <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"הצגת פרופיל"</string>
<string name="user_add_user" msgid="4336657383006913022">"הוספת משתמש"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"משתמש חדש"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"להסיר אורח?"</string>
- <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בפעילות זו באתר יימחקו."</string>
+ <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"הסרה"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"שמחים לראותך שוב!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string>
- <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ברצוני להתחיל מחדש"</string>
- <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"כן, המשך"</string>
+ <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"סשן חדש"</string>
+ <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"כן, להמשיך"</string>
<string name="guest_notification_title" msgid="4434456703930764167">"משתמש אורח"</string>
- <string name="guest_notification_text" msgid="4202692942089571351">"הסר את המשתמש האורח כדי למחוק אפליקציות ונתונים"</string>
- <string name="guest_notification_remove_action" msgid="4153019027696868099">"הסר אורח"</string>
+ <string name="guest_notification_text" msgid="4202692942089571351">"יש להסיר את המשתמש האורח כדי למחוק אפליקציות ונתונים"</string>
+ <string name="guest_notification_remove_action" msgid="4153019027696868099">"הסרת אורח"</string>
<string name="user_logout_notification_title" msgid="3644848998053832589">"ניתוק משתמש"</string>
- <string name="user_logout_notification_text" msgid="7441286737342997991">"צא מהמשתמש הנוכחי"</string>
- <string name="user_logout_notification_action" msgid="7974458760719361881">"נתק משתמש"</string>
+ <string name="user_logout_notification_text" msgid="7441286737342997991">"ניתוק המשתמש הנוכחי"</string>
+ <string name="user_logout_notification_action" msgid="7974458760719361881">"ניתוק משתמש"</string>
<string name="user_add_user_title" msgid="4172327541504825032">"להוסיף משתמש חדש?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"בעת הוספת משתמש חדש, על משתמש זה להגדיר את השטח שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
+ <string name="user_add_user_message_short" msgid="2599370307878014791">"כשמוסיפים משתמש חדש, המשתמש הזה צריך להגדיר את השטח שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"הגעת למגבלת המשתמשים שניתן להוסיף"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="two">ניתן להוסיף עד <xliff:g id="COUNT">%d</xliff:g> משתמשים.</item>
@@ -499,7 +499,7 @@
<item quantity="other">ניתן להוסיף עד <xliff:g id="COUNT">%d</xliff:g> משתמשים.</item>
<item quantity="one">ניתן ליצור רק משתמש אחד.</item>
</plurals>
- <string name="user_remove_user_title" msgid="9124124694835811874">"האם להסיר את המשתמש?"</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="battery_saver_notification_title" msgid="8419266546034372562">"תכונת החיסכון בסוללה פועלת"</string>
@@ -509,7 +509,7 @@
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"‏לשירות שמספק את הפונקציה הזו תהיה גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך בזמן הקלטה או העברה (cast). זה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"‏להתחיל להקליט או להעביר (cast)?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"‏להתחיל להקליט או להעביר (cast) באמצעות <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
- <string name="media_projection_remember_text" msgid="6896767327140422951">"אל תציג שוב"</string>
+ <string name="media_projection_remember_text" msgid="6896767327140422951">"לא להציג שוב"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ניקוי הכול"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ניהול"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"היסטוריה"</string>
@@ -562,11 +562,11 @@
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"מנהל המערכת הפעיל את התכונה \'רישום התנועה ברשת\', שמנטרת את תנועת הנתונים במכשיר."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"מנהל המערכת הפעיל את תכונת רישום התנועה ברשת, שמנטרת את תנועת הנתונים בפרופיל העבודה, אבל לא בפרופיל האישי."</string>
<string name="monitoring_description_named_vpn" msgid="5749932930634037027">"התחברת לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
- <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"אתה מחובר לאפליקציות <xliff:g id="VPN_APP_0">%1$s</xliff:g> ו-<xliff:g id="VPN_APP_1">%2$s</xliff:g>, שיכולות לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"התחברת לאפליקציות <xliff:g id="VPN_APP_0">%1$s</xliff:g> ו-<xliff:g id="VPN_APP_1">%2$s</xliff:g>, שיכולות לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
<string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"פרופיל העבודה שלך מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
<string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"הפרופיל האישי שלך מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
<string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"המכשיר שלך מנוהל על ידי <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
- <string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> משתמש באפליקציה <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> כדי לנהל את מכשירך."</string>
+ <string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"ארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> משתמש באפליקציה <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> כדי לנהל את המכשיר שלך."</string>
<string name="monitoring_description_do_body" msgid="7700878065625769970">"מנהל המערכת יכול לנטר ולנהל הגדרות, גישה ארגונית, אפליקציות, נתונים המשויכים למכשיר ומידע על מיקום המכשיר."</string>
<string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
<string name="monitoring_description_do_learn_more" msgid="645149183455573790">"למידע נוסף"</string>
@@ -575,25 +575,25 @@
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"‏להגדרות ה-VPN"</string>
<string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"פתיחה של פרטי הכניסה המהימנים"</string>
- <string name="monitoring_description_network_logging" msgid="577305979174002252">"מנהל המערכת הפעיל את תכונת רישום התנועה ברשת, שמנטרת את תנועת הנתונים במכשיר.\n\nלמידע נוסף, צור קשר עם מנהל המערכת."</string>
+ <string name="monitoring_description_network_logging" msgid="577305979174002252">"מנהל המערכת הפעיל את תכונת רישום התנועה ברשת, שמנטרת את תנועת הנתונים במכשיר.\n\nלמידע נוסף, אפשר ליצור קשר עם מנהל המערכת."</string>
<string name="monitoring_description_vpn" msgid="1685428000684586870">"‏נתת לאפליקציה כלשהי הרשאה להגדיר חיבור ‏VPN‏.\n\nהאפליקציה הזו יכולה לעקוב אחר הפעילות שלך ברשת ובמכשיר, כולל הודעות אימייל, אפליקציות ואתרים."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"‏פרופיל העבודה שלך מנוהל על-ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\n מנהל המערכת שלך יכול לעקוב אחרי הפעילות שלך ברשת, כולל פעילות באימייל, באפליקציות ובאתרים.\n\n למידע נוסף, צור קשר עם מנהל המערכת.\n\nבנוסף, אתה מחובר ל-VPN, שגם באמצעותו ניתן לעקוב אחרי הפעילות שלך ברשת."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"‏פרופיל העבודה שלך מנוהל על-ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\n מנהל המערכת שלך יכול לעקוב אחרי הפעילות שלך ברשת, כולל פעילות באימייל, באפליקציות ובאתרים.\n\n למידע נוסף, יש ליצור קשר עם מנהל המערכת.\n\nבנוסף, התבצע חיבור ל-VPN, שגם באמצעותו ניתן לעקוב אחרי הפעילות שלך ברשת."</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"מכשיר זה מנוהל על ידי ההורה שלך. להורה שלך יש אפשרות לצפות בפרטים כמו האפליקציות שבשימוש, המיקום וזמן המסך שלך, ולנהל אותם."</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
- <string name="monitoring_description_app" msgid="376868879287922929">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
+ <string name="monitoring_description_app" msgid="376868879287922929">"התחברת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
<string name="monitoring_description_app_personal" msgid="1970094872688265987">"התחברת לאפליקציית <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
- <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת הפרטית, כולל הודעות אימייל, אפליקציות ואתרים."</string>
- <string name="monitoring_description_app_work" msgid="3713084153786663662">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nלמידע נוסף, פנה למנהל המערכת."</string>
+ <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"התחברת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת הפרטית, כולל הודעות אימייל, אפליקציות ואתרים."</string>
+ <string name="monitoring_description_app_work" msgid="3713084153786663662">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nלמידע נוסף, יש לפנות למנהל המערכת."</string>
<string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nהפרופיל מחובר גם לאפליקציה <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת."</string>
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"הנעילה נמנעת על ידי סביבה אמינה"</string>
<string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"המכשיר יישאר נעול עד שהנעילה שלו תבוטל באופן ידני"</string>
<string name="keyguard_indication_trust_unlocked_plugged_in" msgid="2323452175329362855">"<xliff:g id="KEYGUARD_INDICATION">%1$s</xliff:g>\n<xliff:g id="POWER_INDICATION">%2$s</xliff:g>"</string>
<string name="hidden_notifications_title" msgid="1782412844777612795">"קבלה מהירה של התראות"</string>
- <string name="hidden_notifications_text" msgid="5899627470450792578">"צפה בהן לפני שתבטל נעילה"</string>
+ <string name="hidden_notifications_text" msgid="5899627470450792578">"הצגת ההתראות לפני ביטול הנעילה"</string>
<string name="hidden_notifications_cancel" msgid="4805370226181001278">"לא, תודה"</string>
<string name="hidden_notifications_setup" msgid="2064795578526982467">"הגדרה"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>‏. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <string name="volume_zen_end_now" msgid="5901885672973736563">"כבה עכשיו"</string>
+ <string name="volume_zen_end_now" msgid="5901885672973736563">"כיבוי"</string>
<string name="accessibility_volume_settings" msgid="1458961116951564784">"הגדרות צליל"</string>
<string name="accessibility_volume_expand" msgid="7653070939304433603">"הרחבה"</string>
<string name="accessibility_volume_collapse" msgid="2746845391013829996">"כיווץ"</string>
@@ -620,7 +620,7 @@
<string name="screen_pinning_exit" msgid="4553787518387346893">"הצמדת האפליקציה בוטלה"</string>
<string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"להסתיר את <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"יופיע מחדש בפעם הבאה שהאפשרות הזו תופעל בהגדרות."</string>
- <string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"הסתר"</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"הסתרה"</string>
<string name="stream_voice_call" msgid="7468348170702375660">"שיחה"</string>
<string name="stream_system" msgid="7663148785370565134">"מערכת"</string>
<string name="stream_ring" msgid="7550670036738697526">"צלצול"</string>
@@ -636,9 +636,9 @@
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"השתקה"</string>
<string name="qs_status_phone_vibrate" msgid="7055409506885541979">"הטלפון במצב רטט"</string>
<string name="qs_status_phone_muted" msgid="3763664791309544103">"הטלפון מושתק"</string>
- <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. הקש כדי לבטל את ההשתקה."</string>
+ <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. יש להקיש כדי לבטל את ההשתקה."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. צריך להקיש כדי להגדיר רטט. ייתכן ששירותי הנגישות מושתקים."</string>
- <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. הקש כדי להשתיק. ייתכן ששירותי הנגישות מושתקים."</string>
+ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. יש להקיש כדי להשתיק. ייתכן ששירותי הנגישות יושתקו."</string>
<string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"‏%1$s. יש להקיש כדי להעביר למצב רטט."</string>
<string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"‏%1$s. יש להקיש כדי להשתיק."</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string>
@@ -650,13 +650,13 @@
<string name="output_title" msgid="3938776561655668350">"פלט מדיה"</string>
<string name="output_calls_title" msgid="7085583034267889109">"פלט שיחת טלפון"</string>
<string name="output_none_found" msgid="5488087293120982770">"לא נמצאו מכשירים"</string>
- <string name="output_none_found_service_off" msgid="935667567681386368">"לא נמצאו מכשירים. יש לנסות להפעיל <xliff:g id="SERVICE">%1$s</xliff:g>"</string>
+ <string name="output_none_found_service_off" msgid="935667567681386368">"לא נמצאו מכשירים. אפשר לנסות להפעיל <xliff:g id="SERVICE">%1$s</xliff:g>"</string>
<string name="output_service_bt" msgid="4315362133973911687">"Bluetooth"</string>
<string name="output_service_wifi" msgid="9003667810868222134">"Wi-Fi"</string>
<string name="output_service_bt_wifi" msgid="7186882540475524124">"‏Bluetooth ו-Wi-Fi"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string>
- <string name="show_battery_percentage" msgid="6235377891802910455">"הצג בשורת הסטטוס את אחוז עוצמת הסוללה"</string>
- <string name="show_battery_percentage_summary" msgid="9053024758304102915">"הצג את אחוז עוצמת הסוללה בתוך הסמל שבשורת הסטטוס כשהמכשיר אינו בטעינה"</string>
+ <string name="show_battery_percentage" msgid="6235377891802910455">"הצגה של אחוז עוצמת הסוללה בשורת הסטטוס"</string>
+ <string name="show_battery_percentage_summary" msgid="9053024758304102915">"הצגה של אחוז עוצמת הסוללה בתוך הסמל שבשורת הסטטוס כשהמכשיר אינו בטעינה"</string>
<string name="quick_settings" msgid="6211774484997470203">"הגדרות מהירות"</string>
<string name="status_bar" msgid="4357390266055077437">"שורת סטטוס"</string>
<string name="overview" msgid="3522318590458536816">"סקירה"</string>
@@ -666,7 +666,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"אתרנט"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"התראה"</string>
<string name="wallet_title" msgid="5369767670735827105">"ארנק"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"מוכן"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"פרופיל עבודה"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"מצב טיסה"</string>
<string name="add_tile" msgid="6239678623873086686">"הוספת אריח"</string>
@@ -679,11 +685,11 @@
<string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"‏נקודת אינטרנט (hotspot)"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"פרופיל עבודה"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"מהנה בשביל חלק מהאנשים, אבל לא בשביל כולם"</string>
- <string name="tuner_warning" msgid="1861736288458481650">"‏System UI Tuner מספק לך דרכים נוספות להתאים אישית את ממשק המשתמש של Android. התכונות הניסיוניות האלה עשויות להשתנות, להתקלקל או להיעלם בגרסאות עתידיות. המשך בזהירות."</string>
- <string name="tuner_persistent_warning" msgid="230466285569307806">"התכונות הניסיוניות האלה עשויות להשתנות, להתקלקל או להיעלם בגרסאות עתידיות. המשך בזהירות."</string>
+ <string name="tuner_warning" msgid="1861736288458481650">"‏התכונה System UI Tuner מספקת לך דרכים נוספות להתאים אישית את ממשק המשתמש של Android. התכונות הניסיוניות האלה עשויות להשתנות, לא לעבוד כראוי או להיעלם בגרסאות עתידיות. יש להמשיך בזהירות."</string>
+ <string name="tuner_persistent_warning" msgid="230466285569307806">"התכונות הניסיוניות האלה עשויות להשתנות, להתקלקל או להיעלם בגרסאות עתידיות. יש להמשיך בזהירות."</string>
<string name="got_it" msgid="477119182261892069">"הבנתי"</string>
- <string name="tuner_toast" msgid="3812684836514766951">"‏מזל טוב! ה-System UI Tuner נוסף ל\'הגדרות\'"</string>
- <string name="remove_from_settings" msgid="633775561782209994">"הסר מההגדרות"</string>
+ <string name="tuner_toast" msgid="3812684836514766951">"‏מעולה, ה-System UI Tuner נוסף ל\'הגדרות\'"</string>
+ <string name="remove_from_settings" msgid="633775561782209994">"הסרה מההגדרות"</string>
<string name="remove_from_settings_prompt" msgid="551565437265615426">"‏האם להסיר את System UI Tuner ולהפסיק להשתמש בכל התכונות שלו?"</string>
<string name="activity_not_found" msgid="8711661533828200293">"האפליקציה אינה מותקנת במכשיר"</string>
<string name="clock_seconds" msgid="8709189470828542071">"הצגת שניות בשעון"</string>
@@ -701,25 +707,25 @@
<string name="tuner_full_importance_settings" msgid="1388025816553459059">"פקדים של הודעות הפעלה"</string>
<string name="tuner_full_importance_settings_on" msgid="917981436602311547">"פועל"</string>
<string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"כבוי"</string>
- <string name="power_notification_controls_description" msgid="1334963837572708952">"בעזרת פקדים של התראות הפעלה, אפשר להגדיר רמת חשיבות מ-0 עד 5 להתראות אפליקציה. \n\n"<b>"רמה 5"</b>" \n- הצגה בראש רשימת ההתראות \n- אפשר הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 4"</b>" \n- מנע הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 3"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n\n"<b>"רמה 2"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n\n"<b>"רמה 1"</b>" \n- מניעת הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n- הסתרה ממסך הנעילה ומשורת הסטטוס \n- הצגה בתחתית רשימת ההתראות \n\n"<b>"רמה 0"</b>" \n- חסימה את כל ההתראות מהאפליקציה"</string>
+ <string name="power_notification_controls_description" msgid="1334963837572708952">"בעזרת פקדים של התראות הפעלה, אפשר להגדיר רמת חשיבות מ-0 עד 5 להתראות אפליקציה. \n\n"<b>"רמה 5"</b>" \n- הצגה בראש רשימת ההתראות \n- לאפשר הפרעה במסך מלא \n- תמיד לאפשר הצצה \n\n"<b>"רמה 4"</b>" \n- מניעת הפרעה במסך מלא \n- תמיד לאפשר הצצה \n\n"<b>"רמה 3"</b>" \n- מניעת הפרעה במסך מלא \n- אף פעם לא לאפשר הצצה \n\n"<b>"רמה 2"</b>" \n- מניעת הפרעה במסך מלא \n- אף פעם לא לאפשר הצצה \n- אף פעם לא לאפשר קול ורטט \n\n"<b>"רמה 1"</b>" \n- מניעת הפרעה במסך מלא \n- אף פעם לא לאפשר הצצה \n- אף פעם לא לאפשר קול ורטט \n- הסתרה ממסך הנעילה ומשורת הסטטוס \n- הצגה בתחתית רשימת ההתראות \n\n"<b>"רמה 0"</b>" \n- חסימת כל ההתראות מהאפליקציה"</string>
<string name="notification_header_default_channel" msgid="225454696914642444">"התראות"</string>
<string name="notification_channel_disabled" msgid="928065923928416337">"ההתראות האלה לא יוצגו לך יותר"</string>
<string name="notification_channel_minimized" msgid="6892672757877552959">"ההתראות האלה ימוזערו"</string>
- <string name="notification_channel_silenced" msgid="1995937493874511359">"התראות אלה יוצגו ללא צליל"</string>
- <string name="notification_channel_unsilenced" msgid="94878840742161152">"הודעות אלה יישלחו כהתראה"</string>
- <string name="inline_blocking_helper" msgid="2891486013649543452">"התראות אלה בדרך כלל נדחות על ידך. \nלהמשיך להציג אותן?"</string>
+ <string name="notification_channel_silenced" msgid="1995937493874511359">"ההתראות האלה יוצגו ללא צליל"</string>
+ <string name="notification_channel_unsilenced" msgid="94878840742161152">"ההודעות אלה יישלחו כהתראות"</string>
+ <string name="inline_blocking_helper" msgid="2891486013649543452">"ההתראות האלה בדרך כלל נדחות על ידך. \nלהמשיך להציג אותן?"</string>
<string name="inline_done_button" msgid="6043094985588909584">"סיום"</string>
<string name="inline_ok_button" msgid="603075490581280343">"החלה"</string>
<string name="inline_keep_showing" msgid="8736001253507073497">"שנמשיך להציג לך את ההתראות האלה?"</string>
<string name="inline_stop_button" msgid="2453460935438696090">"לא, אל תמשיכו"</string>
<string name="inline_deliver_silently_button" msgid="2714314213321223286">"הצגה ללא צליל"</string>
<string name="inline_block_button" msgid="479892866568378793">"חסימה"</string>
- <string name="inline_keep_button" msgid="299631874103662170">"כן, המשיכו"</string>
+ <string name="inline_keep_button" msgid="299631874103662170">"כן, תמשיכו להציג"</string>
<string name="inline_minimize_button" msgid="1474436209299333445">"מזעור"</string>
<string name="inline_silent_button_silent" msgid="525243786649275816">"שקטה"</string>
<string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"בשקט"</string>
<string name="inline_silent_button_alert" msgid="5705343216858250354">"שליחת התראות"</string>
- <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"המשך שליחת התראות"</string>
+ <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"להמשיך לשלוח התראות"</string>
<string name="inline_turn_off_notifications" msgid="8543989584403106071">"השבתת ההתראות"</string>
<string name="inline_keep_showing_app" msgid="4393429060390649757">"שנמשיך להציג לך התראות מהאפליקציה הזאת?"</string>
<string name="notification_silence_title" msgid="8608090968400832335">"שקט"</string>
@@ -743,7 +749,7 @@
<string name="notification_multichannel_desc" msgid="7414593090056236179">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
<string name="notification_delegate_header" msgid="1264510071031479920">"‏התראה דרך שרת proxy"</string>
<string name="notification_channel_dialog_title" msgid="6856514143093200019">"כל ההתראות של <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="see_more_title" msgid="7409317011708185729">"הצגת עוד"</string>
+ <string name="see_more_title" msgid="7409317011708185729">"עוד"</string>
<string name="appops_camera" msgid="5215967620896725715">"האפליקציה הזו משתמשת במצלמה."</string>
<string name="appops_microphone" msgid="8805468338613070149">"האפליקציה הזו משתמשת במיקרופון."</string>
<string name="appops_overlay" msgid="4822261562576558490">"האפליקציה הזו מוצגת מעל אפליקציות אחרות במסך."</string>
@@ -757,12 +763,12 @@
<string name="feedback_silenced" msgid="9116540317466126457">"‏ההתראה הזו &lt;b&gt;הורדה בדרגה ל\'שקט\'&lt;/b&gt; באופן אוטומטי על-ידי המערכת."</string>
<string name="feedback_promoted" msgid="2125562787759780807">"‏ההתראה הזו &lt;b&gt;דורגה גבוה יותר&lt;/b&gt; באופן אוטומטי בהתראות שלך."</string>
<string name="feedback_demoted" msgid="951884763467110604">"‏ההתראה הזו &lt;b&gt;דורגה נמוך יותר&lt;/b&amp;gt באופן אוטומטי בהתראות שלך."</string>
- <string name="feedback_prompt" msgid="3656728972307896379">"אפשר לשלוח למפתח את המשוב שלך. האם פעולה זו הייתה נכונה?"</string>
+ <string name="feedback_prompt" msgid="3656728972307896379">"אפשר לשלוח למפתח את המשוב שלך. הפעולה הזו הייתה נכונה?"</string>
<string name="feedback_response" msgid="4671729244976641339">"תודה על המשוב!"</string>
<string name="feedback_ok" msgid="6481426753298857144">"אישור"</string>
- <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"פקדי ההודעות של <xliff:g id="APP_NAME">%1$s</xliff:g> נפתחו"</string>
- <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"פקדי ההודעות של <xliff:g id="APP_NAME">%1$s</xliff:g> נסגרו"</string>
- <string name="notification_channel_switch_accessibility" msgid="8979885820432540252">"התר התראות מערוץ זה"</string>
+ <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"פקדי ההתראות של <xliff:g id="APP_NAME">%1$s</xliff:g> נפתחו"</string>
+ <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"פקדי ההתראות של <xliff:g id="APP_NAME">%1$s</xliff:g> נסגרו"</string>
+ <string name="notification_channel_switch_accessibility" msgid="8979885820432540252">"אישור קבלת התראות מהערוץ הזה"</string>
<string name="notification_more_settings" msgid="4936228656989201793">"הגדרות נוספות"</string>
<string name="notification_app_settings" msgid="8963648463858039377">"התאמה אישית"</string>
<string name="notification_done" msgid="6215117625922713976">"סיום"</string>
@@ -795,7 +801,7 @@
<item quantity="one">דקה</item>
</plurals>
<string name="battery_panel_title" msgid="5931157246673665963">"שימוש בסוללה"</string>
- <string name="battery_detail_charging_summary" msgid="8821202155297559706">"תכונת החיסכון בסוללה אינה זמינה בעת טעינת המכשיר"</string>
+ <string name="battery_detail_charging_summary" msgid="8821202155297559706">"תכונת החיסכון בסוללה לא זמינה כשהמכשיר בטעינה"</string>
<string name="battery_detail_switch_title" msgid="6940976502957380405">"חיסכון בסוללה"</string>
<string name="battery_detail_switch_summary" msgid="3668748557848025990">"מפחיתה את רמת הביצועים ואת נתוני הרקע"</string>
<string name="keyboard_key_button_template" msgid="8005673627272051429">"לחצן <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -810,11 +816,11 @@
<string name="keyboard_key_space" msgid="6980847564173394012">"רווח"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"BACKSPACE"</string>
- <string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"הפעל/השהה"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"עצור"</string>
+ <string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"הפעלה/השהיה"</string>
+ <string name="keyboard_key_media_stop" msgid="1509943745250377699">"עצירה"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"הבא"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"הקודם"</string>
- <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"הרץ אחורה"</string>
+ <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"הרצה אחורה"</string>
<string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"הרצה קדימה"</string>
<string name="keyboard_key_page_up" msgid="173914303254199845">"דפדוף למעלה"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"דפדוף למטה"</string>
@@ -840,7 +846,7 @@
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"מוזיקה"</string>
<string name="keyboard_shortcut_group_applications_youtube" msgid="5078136084632450333">"‏YouTube"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"יומן"</string>
- <string name="tuner_full_zen_title" msgid="5120366354224404511">"הצג עם פקדי עוצמת הקול"</string>
+ <string name="tuner_full_zen_title" msgid="5120366354224404511">"הצגה עם פקדי עוצמת הקול"</string>
<string name="volume_and_do_not_disturb" msgid="502044092739382832">"נא לא להפריע"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"קיצור דרך ללחצני עוצמת קול"</string>
<string name="volume_up_silent" msgid="1035180298885717790">"יציאה ממצב \'נא לא להפריע\' בלחיצה על הלחצן להגברת עוצמת הקול"</string>
@@ -885,19 +891,19 @@
<string name="right_icon" msgid="1103955040645237425">"סמל ימני"</string>
<string name="drag_to_add_tiles" msgid="8933270127508303672">"יש ללחוץ ולגרור כדי להוסיף אריחים"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"יש ללחוץ ולגרור כדי לסדר מחדש את האריחים"</string>
- <string name="drag_to_remove_tiles" msgid="4682194717573850385">"גרור לכאן כדי להסיר"</string>
+ <string name="drag_to_remove_tiles" msgid="4682194717573850385">"אפשר לגרור לכאן כדי להסיר"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"יש צורך ב-<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> אריחים לפחות"</string>
<string name="qs_edit" msgid="5583565172803472437">"עריכה"</string>
<string name="tuner_time" msgid="2450785840990529997">"שעה"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"הצגת שעות, דקות ושניות"</item>
- <item msgid="1271006222031257266">"הצג שעות ודקות (ברירת מחדל)"</item>
+ <item msgid="1271006222031257266">"הצגת שעות ודקות (ברירת מחדל)"</item>
<item msgid="6135970080453877218">"לא להציג את הסמל הזה"</item>
</string-array>
<string-array name="battery_options">
- <item msgid="7714004721411852551">"הצג תמיד באחוזים"</item>
+ <item msgid="7714004721411852551">"תמיד להציג באחוזים"</item>
<item msgid="3805744470661798712">"הצגת אחוזים בזמן הטעינה (ברירת מחדל)"</item>
- <item msgid="8619482474544321778">"אל תציג את הסמל הזה"</item>
+ <item msgid="8619482474544321778">"אל תציגו את הסמל הזה"</item>
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"הצגת סמלי התראות בעדיפות נמוכה"</string>
<string name="other" msgid="429768510980739978">"אחר"</string>
@@ -920,7 +926,7 @@
<string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"בחירת משתמש"</string>
<string name="data_connection_no_internet" msgid="691058178914184544">"אין אינטרנט"</string>
<string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"פתיחת פרטים."</string>
- <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"לא זמין כי <xliff:g id="REASON">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"לא זמינים כי <xliff:g id="REASON">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"פתיחת הגדרות של <xliff:g id="ID_1">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"עריכת סדר ההגדרות."</string>
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"תפריט הפעלה"</string>
@@ -932,17 +938,17 @@
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"לצפייה בשלבי הטיפול"</string>
<string name="high_temp_title" msgid="2218333576838496100">"הטלפון מתחמם"</string>
<string name="high_temp_notif_message" msgid="1277346543068257549">"חלק מהתכונות מוגבלות כל עוד הטלפון מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string>
- <string name="high_temp_dialog_message" msgid="3793606072661253968">"קירור הטלפון ייעשה באופן אוטומטי. תוכל עדיין להשתמש בטלפון, אבל ייתכן שהוא יפעל לאט יותר.\n\nהטלפון יחזור לפעול כרגיל לאחר שיתקרר."</string>
+ <string name="high_temp_dialog_message" msgid="3793606072661253968">"קירור הטלפון ייעשה באופן אוטומטי. ניתן עדיין להשתמש בטלפון, אבל ייתכן שהוא יפעל לאט יותר.\n\nהטלפון יחזור לפעול כרגיל לאחר שיתקרר."</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"לצפייה בשלבי הטיפול"</string>
<string name="high_temp_alarm_title" msgid="2359958549570161495">"יש לנתק את המטען"</string>
- <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"יש בעיה עם טעינת מכשיר זה. יש לנתק את מתאם המתח בזהירות כיוון שייתכן שהכבל חם."</string>
+ <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"יש בעיה עם הטעינה של המכשיר הזה. צריך לנתק את מתאם המתח בזהירות כי הכבל עלול להיות חם."</string>
<string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"לצפייה בשלבי הטיפול"</string>
<string name="lockscreen_shortcut_left" msgid="1238765178956067599">"קיצור דרך שמאלי"</string>
<string name="lockscreen_shortcut_right" msgid="4138414674531853719">"קיצור דרך ימני"</string>
<string name="lockscreen_unlock_left" msgid="1417801334370269374">"קיצור דרך שמאלי גם מבטל נעילה"</string>
<string name="lockscreen_unlock_right" msgid="4658008735541075346">"קיצור דרך ימני גם מבטל נעילה"</string>
<string name="lockscreen_none" msgid="4710862479308909198">"ללא"</string>
- <string name="tuner_launch_app" msgid="3906265365971743305">"הפעל את האפליקציה <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="tuner_launch_app" msgid="3906265365971743305">"הפעלת האפליקציה <xliff:g id="APP">%1$s</xliff:g>"</string>
<string name="tuner_other_apps" msgid="7767462881742291204">"אפליקציות אחרות"</string>
<string name="tuner_circle" msgid="5270591778160525693">"מעגל"</string>
<string name="tuner_plus" msgid="4130366441154416484">"פלוס"</string>
@@ -974,13 +980,13 @@
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה או על ידי כלל אוטומטי."</string>
<string name="qs_dnd_until" msgid="7844269319043747955">"עד <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="3829697305432866434">"שמירה"</string>
- <string name="qs_dnd_replace" msgid="7712119051407052689">"החלף"</string>
+ <string name="qs_dnd_replace" msgid="7712119051407052689">"שינוי"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"אפליקציות שפועלות ברקע"</string>
- <string name="running_foreground_services_msg" msgid="3009459259222695385">"הקש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
+ <string name="running_foreground_services_msg" msgid="3009459259222695385">"אפשר להקיש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"לכבות את חבילת הגלישה?"</string>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"‏לא תהיה לך גישה לנתונים או לאינטרנט באמצעות <xliff:g id="CARRIER">%s</xliff:g>. אינטרנט יהיה זמין רק באמצעות Wi-Fi."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"הספק שלך"</string>
- <string name="touch_filtered_warning" msgid="8119511393338714836">"יש אפליקציה שמסתירה את בקשת ההרשאה, ולכן להגדרות אין אפשרות לאמת את התשובה."</string>
+ <string name="touch_filtered_warning" msgid="8119511393338714836">"יש אפליקציה שמסתירה את בקשת ההרשאה, ולכן אין אפשרות לאמת את התשובה בהגדרות."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"האם לאפשר ל-<xliff:g id="APP_0">%1$s</xliff:g> להציג חלקים מ-<xliff:g id="APP_2">%2$s</xliff:g>?"</string>
<string name="slice_permission_text_1" msgid="6675965177075443714">"- תהיה לה אפשרות לקרוא מידע מאפליקציית <xliff:g id="APP">%1$s</xliff:g>"</string>
<string name="slice_permission_text_2" msgid="6758906940360746983">"- תהיה לה יכולת לנקוט פעולה בתוך <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -995,7 +1001,7 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"הגדרות"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"הבנתי"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"‏ערימת Dump SysUI"</string>
- <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> משתמשת ב<xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> משתמשת ב<xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"אפליקציות משתמשות ב<xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" וגם "</string>
@@ -1048,8 +1054,8 @@
<item quantity="one">נוסף פקד אחד (<xliff:g id="NUMBER_0">%s</xliff:g>).</item>
</plurals>
<string name="controls_removed" msgid="3731789252222856959">"הוסר"</string>
- <string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כהעדפה"</string>
- <string name="accessibility_control_favorite_position" msgid="54220258048929221">"סומן כהעדפה, במיקום <xliff:g id="NUMBER">%d</xliff:g>"</string>
+ <string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כמועדף"</string>
+ <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>
diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml
index d69d3ed15170..f01321efc967 100644
--- a/packages/SystemUI/res/values-iw/strings_tv.xml
+++ b/packages/SystemUI/res/values-iw/strings_tv.xml
@@ -23,7 +23,7 @@
<string name="app_accessed_mic" msgid="2754428675130470196">"‏לאפליקציה %1$s יש גישה למיקרופון שלך"</string>
<string name="notification_vpn_connected" msgid="3891023882833274730">"‏ה-VPN מחובר"</string>
<string name="notification_vpn_disconnected" msgid="7150747626448044843">"‏ה-VPN מנותק"</string>
- <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"באמצעות <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"דרך <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"התראות"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"אין התראות"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 980506d75fee..bbd75435c278 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"閉じる"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"指紋認証センサーをタップ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"指紋アイコン"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"顔を認識できません。指紋認証を使用してください。"</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"続行するには指紋認証を使用してください"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"指紋を認識できません。代わりに画面ロックを使用してください。"</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"顔を認証しています…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"顔アイコン"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"互換ズームボタン。"</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"イーサネット"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"アラーム"</string>
<string name="wallet_title" msgid="5369767670735827105">"ウォレット"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"準備完了"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"仕事用プロファイル"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"機内モード"</string>
<string name="add_tile" msgid="6239678623873086686">"タイルを追加"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"会話ウィジェット"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"会話をタップするとホーム画面に追加されます"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"メッセージを受信したら、ここでもう一度ご確認ください"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"優先度の高い会話"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"最近の会話"</string>
+ <string name="okay" msgid="6490552955618608554">"OK"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>前"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>前まで"</string>
<string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>以上前"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 8788defc0913..bd65529cc2de 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ეთერნეტი"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"მაღვიძარა"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"მზადაა"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"სამსახურის პროფილი"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"თვითმფრინავის რეჟიმი"</string>
<string name="add_tile" msgid="6239678623873086686">"მოზაიკის დამატება"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 2b7e908adfe0..bbb2161589fa 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Дабыл"</string>
<string name="wallet_title" msgid="5369767670735827105">"Әмиян"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Дайын"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Жұмыс профилі"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Ұшақ режимі"</string>
<string name="add_tile" msgid="6239678623873086686">"Тақтайша қосу"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index a09b21614d96..a5e66b274695 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"អ៊ីសឺរណិត"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"ម៉ោងរោទ៍"</string>
<string name="wallet_title" msgid="5369767670735827105">"កាបូប"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"រួចរាល់"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ប្រវត្តិរូបការងារ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"របៀបក្នុងយន្តហោះ"</string>
<string name="add_tile" msgid="6239678623873086686">"បន្ថែមក្រឡាល្អិត"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index a7a51050db47..0e44a0cdb460 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ಇಥರ್ನೆಟ್"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"ಅಲಾರಮ್"</string>
<string name="wallet_title" msgid="5369767670735827105">"ವಾಲೆಟ್"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"ಸಿದ್ಧವಾಗಿದೆ"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್"</string>
<string name="add_tile" msgid="6239678623873086686">"ಟೈಲ್ ಸೇರಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index bac0570b370c..005449d65e90 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"이더넷"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"알람"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"준비됨"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"직장 프로필"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"비행기 모드"</string>
<string name="add_tile" msgid="6239678623873086686">"타일 추가"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 0f395363ed82..13ed32bea111 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -89,8 +89,7 @@
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Скриншот тартууга колдонмо же ишканаңыз тыюу салган."</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"Түзөтүү"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Скриншотту түзөтүү"</string>
- <!-- no translation found for screenshot_scroll_label (2930198809899329367) -->
- <skip />
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Көбүрөөк тартуу"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Скриншотту четке кагуу"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотту алдын ала көрүү"</string>
<string name="screenshot_top_boundary" msgid="1500569103321300856">"Жогорку чеги"</string>
@@ -384,11 +383,9 @@
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"Түстөрдү инверсиялоо"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"Түстү тууралоо абалы"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"Дагы жөндөөлөр"</string>
- <!-- no translation found for quick_settings_more_user_settings (1064187451100861954) -->
- <skip />
+ <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"Колдонуучунун жөндөөлөрү"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"Бүттү"</string>
- <!-- no translation found for quick_settings_close_user_panel (5599724542275896849) -->
- <skip />
+ <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>
@@ -533,8 +530,7 @@
<string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык жана VPN\'дерге туташтырылган"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Ишканаңыз жумуш профилиңиздин тармак трафигин көзөмөлдөй алат"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> жумуш профилиңиздеги тармак трафигин көзөмөлдөй алат"</string>
- <!-- no translation found for quick_settings_disclosure_managed_profile_network_activity (2636594621387832827) -->
- <skip />
+ <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Жумуш профилинин тармактагы аракеттери IT администраторуна көрүнөт"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Тармак көзөмөлдөнүшү мүмкүн"</string>
<string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Бул түзмөк VPN\'дерге туташтырылган"</string>
<string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Жумуш профилиңиз <xliff:g id="VPN_APP">%1$s</xliff:g> колдонмосуна туташып турат"</string>
@@ -664,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Ойготкуч"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Даяр"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Жумуш профили"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Учак режими"</string>
<string name="add_tile" msgid="6239678623873086686">"Тайл кошуу"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 53cd88b55560..3cd7d34c71fe 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ອີ​ເທ​ເນັດ"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"ໂມງປຸກ"</string>
<string name="wallet_title" msgid="5369767670735827105">"ກະເປົາ"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"ພ້ອມແລ້ວ"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"​ໂປຣ​ໄຟລ໌​ບ່ອນ​ເຮັດ​ວຽກ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ໂໝດເຮືອ​ບິນ"</string>
<string name="add_tile" msgid="6239678623873086686">"ເພີ່ມ​ລາຍ​ຕາ​ກະ​ໂລ່"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index fdfb954d41f5..f9fdf1037ba7 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -666,7 +666,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Eternetas"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Signalas"</string>
<string name="wallet_title" msgid="5369767670735827105">"Piniginė"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Paruošta"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Darbo profilis"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lėktuvo režimas"</string>
<string name="add_tile" msgid="6239678623873086686">"Pridėti išklotinės elementą"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4f6764871fe8..ef482700010d 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -663,7 +663,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Tīkls Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Signāls"</string>
<string name="wallet_title" msgid="5369767670735827105">"Maks"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Gatavs"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Darba profils"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lidojuma režīms"</string>
<string name="add_tile" msgid="6239678623873086686">"Pievienot elementu"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index c72f6720c4e1..bd9c53538c4d 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Етернет"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Аларм"</string>
<string name="wallet_title" msgid="5369767670735827105">"Паричник"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Подготвено"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Работен профил"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Авионски режим"</string>
<string name="add_tile" msgid="6239678623873086686">"Додај плочка"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 47ea733c0c2b..568c19e865ef 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ഇതർനെറ്റ്"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"അലാറം"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"തയ്യാറാണ്"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ഫ്ലൈറ്റ് മോഡ്"</string>
<string name="add_tile" msgid="6239678623873086686">"ടൈൽ ചേർക്കുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index a196280c7a1d..953d414d5338 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Хаах"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Хурууны хээ мэдрэгчид хүрэх"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Хурууны хээний дүрс тэмдэг"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Царай таних боломжгүй. Оронд нь хурууны хээ ашигла"</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Үргэлжлүүлэхийн тулд хурууныхаа хээг ашиглана уу"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Хурууны хээг таних боломжгүй. Оронд нь дэлгэцийн түгжээ ашиглана уу."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Таныг хайж байна…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Царайны дүрс тэмдэг"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Тохиромжтой өсгөх товч."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Этернет"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Сэрүүлэг"</string>
<string name="wallet_title" msgid="5369767670735827105">"Түрийвч"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Бэлэн"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Ажлын профайл"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Нислэгийн горим"</string>
<string name="add_tile" msgid="6239678623873086686">"Вебсайтын цонх нэмэх"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Харилцан ярианы жижиг хэрэгслүүд"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Үндсэн нүүрэндээ нэмэх харилцан яриаг товшино уу"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Та зарим мессеж авсныхаа дараа эндээс буцаж шалгана уу"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Чухал харилцан яриа"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Саяхны харилцан яриа"</string>
+ <string name="okay" msgid="6490552955618608554">"За"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>-н өмнө"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>-с бага хугацааны өмнө"</string>
<string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>-с дээш хугацааны өмнө"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 3df8b926037e..4098426ca54b 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"इथरनेट"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"तयार आहे"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाईल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"विमान मोड"</string>
<string name="add_tile" msgid="6239678623873086686">"टाइल जोडा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 7095ac3b3303..2b6a85242196 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Penggera"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Sedia"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil kerja"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mod pesawat"</string>
<string name="add_tile" msgid="6239678623873086686">"Tambahkan jubin"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index eddf58b097e3..abcbb83d0afb 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"အီသာနက်"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"နှိုးစက်"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"အဆင်သင့်"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"အလုပ် ပရိုဖိုင်"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"လေယာဉ်ပျံမုဒ်"</string>
<string name="add_tile" msgid="6239678623873086686">"လေးထောင့်ကွက် ထည့်ရန်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 0262a7dab5a6..6f766352474d 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -89,7 +89,7 @@
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper"</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger skjermdumpen"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Ta bilde av mer"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Utvidet skjermdump"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Avvis skjermdumpen"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning av skjermdump"</string>
<string name="screenshot_top_boundary" msgid="1500569103321300856">"Øvre grense"</string>
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Klar"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Work-profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flymodus"</string>
<string name="add_tile" msgid="6239678623873086686">"Legg til felt"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index e772622275d2..0be4f5250dc2 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"इथरनेट"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string>
<string name="wallet_title" msgid="5369767670735827105">"वालेट"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"तयार छ"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाइल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"हवाइजहाज मोड"</string>
<string name="add_tile" msgid="6239678623873086686">"टाइल थप्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index c10add2ca853..471f36b3849e 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -92,8 +92,6 @@
<color name="kg_user_switcher_avatar_icon_color">@android:color/background_light</color>
<!-- Icon color for selected user avatars in keyguard user switcher -->
<color name="kg_user_switcher_selected_avatar_icon_color">#202124</color>
- <!-- Color of background circle of user avatars in keyguard user switcher -->
- <color name="kg_user_switcher_avatar_background">#3C4043</color>
<!-- Icon color for user avatars in quick settings user switcher -->
<color name="qs_user_switcher_avatar_icon_color">@android:color/background_light</color>
<!-- Icon color for selected user avatars in quick settings user switcher -->
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 5573f7da54ae..d46d48903916 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Sluiten"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Raak de vingerafdruksensor aan"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Vingerafdrukpictogram"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Gezicht niet herkend. Gebruik je vingerafdruk."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Gebruik je vingerafdruk om door te gaan."</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Vingerafdruk niet herkend. Gebruik in plaats daarvan de schermvergrendeling."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Jouw gezicht zoeken…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Gezichtspictogram"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Knop voor compatibiliteitszoom."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Wekker"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Klaar"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuigmodus"</string>
<string name="add_tile" msgid="6239678623873086686">"Tegel toevoegen"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Gesprekswidgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tik op een gesprek om het toe te voegen aan je startscherm"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Kom hier terug zodra je wat berichten hebt"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Prioriteitsgesprekken"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Recente gesprekken"</string>
+ <string name="okay" msgid="6490552955618608554">"OK"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> geleden"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Minder dan <xliff:g id="DURATION">%1$s</xliff:g> geleden"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Meer dan <xliff:g id="DURATION">%1$s</xliff:g> geleden"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 811ae0b8d4bb..9739b419046b 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ଟିପଚିହ୍ନ ସେନସର୍‌କୁ ଛୁଅଁନ୍ତୁ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ଟିପଚିହ୍ନ ଆଇକନ୍"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ଫେସ୍ ଚିହ୍ନଟ କରିହେବ ନାହିଁ। ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"ଟିପଚିହ୍ନକୁ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"ଆପଣଙ୍କୁ ଚିହ୍ନଟ କରୁଛି…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"ମୁହଁ ଆଇକନ୍"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"କମ୍ପାଟିବିଲିଟୀ ଜୁମ୍ ବଟନ୍।"</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ଇଥରନେଟ୍‌"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"ଆଲାର୍ମ"</string>
<string name="wallet_title" msgid="5369767670735827105">"ୱାଲେଟ୍"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"ପ୍ରସ୍ତୁତ"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍"</string>
<string name="add_tile" msgid="6239678623873086686">"ଟାଇଲ୍‍ ଯୋଡ଼ନ୍ତୁ"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ବାର୍ତ୍ତାଳାପ ୱିଜେଟଗୁଡ଼ିକ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ଏକ ବାର୍ତ୍ତାଳାପକୁ ଆପଣଙ୍କ ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରିବା ପାଇଁ ସେଥିରେ ଟାପ୍ କରନ୍ତୁ"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"ଆପଣ କିଛି ମେସେଜ୍ ପାଇଲେ ଏଠାରେ ପୁଣି ଯାଞ୍ଚ କରନ୍ତୁ"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"ପ୍ରାଥମିକତା ଦିଆଯାଇଥିବା ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"ବର୍ତ୍ତମାନର ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
+ <string name="okay" msgid="6490552955618608554">"ଠିକ୍ ଅଛି"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> ପୂର୍ବେ"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>ରୁ କମ୍ ସମୟ ପୂର୍ବେ"</string>
<string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>ରୁ ଅଧିକ ସମୟ ପୂର୍ବେ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index daae60d9e6e7..1d9cabcdce3a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ਈਥਰਨੈਟ"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"ਅਲਾਰਮ"</string>
<string name="wallet_title" msgid="5369767670735827105">"ਵਾਲੇਟ"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"ਤਿਆਰ"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ"</string>
<string name="add_tile" msgid="6239678623873086686">"ਟਾਇਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 2bd09c88c704..c25d43bc0556 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -666,7 +666,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Portfel"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Gotowe"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil służbowy"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Tryb samolotowy"</string>
<string name="add_tile" msgid="6239678623873086686">"Dodaj nazwę"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 805a673b209d..32153bf4be14 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dispensar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toque no sensor de impressão digital"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ícone de impressão digital"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Não foi possível reconhecer o rosto Use a impressão digital."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Use sua impressão digital para continuar"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Não foi possível reconhecer a impressão digital. Use o bloqueio de tela."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Procurando você…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Ícone facial"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Botão de zoom da compatibilidade."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
<string name="wallet_title" msgid="5369767670735827105">"Carteira"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Pronto"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avião"</string>
<string name="add_tile" msgid="6239678623873086686">"Adicionar bloco"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Volte aqui quando receber mensagens"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Conversas prioritárias"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Conversas recentes"</string>
+ <string name="okay" msgid="6490552955618608554">"Ok"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Menos de <xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Mais de <xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 5a6cdb64715f..5f585d46e44e 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
<string name="wallet_title" msgid="5369767670735827105">"Carteira"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Pronto"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avião"</string>
<string name="add_tile" msgid="6239678623873086686">"Adicionar mosaico"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 805a673b209d..32153bf4be14 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dispensar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toque no sensor de impressão digital"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ícone de impressão digital"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Não foi possível reconhecer o rosto Use a impressão digital."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Use sua impressão digital para continuar"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Não foi possível reconhecer a impressão digital. Use o bloqueio de tela."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Procurando você…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Ícone facial"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Botão de zoom da compatibilidade."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
<string name="wallet_title" msgid="5369767670735827105">"Carteira"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Pronto"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avião"</string>
<string name="add_tile" msgid="6239678623873086686">"Adicionar bloco"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Volte aqui quando receber mensagens"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Conversas prioritárias"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Conversas recentes"</string>
+ <string name="okay" msgid="6490552955618608554">"Ok"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Menos de <xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Mais de <xliff:g id="DURATION">%1$s</xliff:g> atrás"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index de49c91c8144..a70e2a27339a 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -663,7 +663,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarmă"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Gata"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil de serviciu"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mod Avion"</string>
<string name="add_tile" msgid="6239678623873086686">"Adăugați o casetă"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 3c4326616f5f..30b0e3b37109 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -666,7 +666,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Будильник"</string>
<string name="wallet_title" msgid="5369767670735827105">"Кошелек"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Готово"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Рабочий профиль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Режим полета"</string>
<string name="add_tile" msgid="6239678623873086686">"Добавить кнопку быстрого доступа"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 02a20dbbfb70..7206f029c95f 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ඉවත ලන්න"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ඇඟිලි සලකුණු නිරූපකය"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"මුහුණ හැඳිනිය නොහැක. ඒ වෙනුවට ඇඟිලි සලකුණ භාවිත ක."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"ඉදිරියට යාමට ඔබගේ ඇඟිලි සලකුණ භාවිත කරන්න"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"ඇඟිලි සලකුණ හඳුනා ගත නොහැකිය. ඒ වෙනුවට තිර අගුල භාවිත කරන්න."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"ඔබව සොයමින්…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"මුහුණ නිරූපකය"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"ගැළපෙන විශාලන බොත්තම."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"එලාමය"</string>
<string name="wallet_title" msgid="5369767670735827105">"පසුම්බිය"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"සූදානම්"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"කාර්යාල පැතිකඩ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ගුවන්යානා ප්‍රකාරය"</string>
<string name="add_tile" msgid="6239678623873086686">"ටයිල් එක් කරන්න"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"සංවාද විජට්"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ඔබගේ මුල් තිරයට එය එක් කිරීමට සංවාදයක් තට්ටු කරන්න"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"ඔබට පණිවිඩ කිහිපයක් ලැබුණු පසු නැවත මෙහි පරීක්ෂා කරන්න"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"ප්‍රමුඛතා සංවාද"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"මෑත සංවාද"</string>
+ <string name="okay" msgid="6490552955618608554">"හරි"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>කට පෙර"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>කට වඩා අඩු කාලයකට පෙර"</string>
<string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>කට වඩා පෙර"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index a645d210b155..4919352917ab 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Zrušiť"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotknite sa senzora odtlačkov prstov"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona odtlačku prsta"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tvár sa nedá rozpoznať. Použite odtlačok prsta."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Pokračujte nasnímaním odtlačku prsta"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Odtlačok prsta sa nedá rozpoznať. Použite radšej zámku obrazovky."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Hľadáme vás…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Ikona tváre"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Tlačidlo úpravy veľkosti z dôvodu kompatibility."</string>
@@ -666,7 +663,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Budík"</string>
<string name="wallet_title" msgid="5369767670735827105">"Peňaženka"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Pripravené"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Pracovný profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Režim v lietadle"</string>
<string name="add_tile" msgid="6239678623873086686">"Pridať dlaždicu"</string>
@@ -1108,14 +1111,10 @@
<string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikácie konverzácií"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Klepnite na konverzáciu a pridajte ju tak na plochu"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Sem sa vráťte, keď dostanete nejaké správy"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Prioritné konverzácie"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Nedávne konverzácie"</string>
+ <string name="okay" msgid="6490552955618608554">"OK"</string>
<string name="timestamp" msgid="6577851592534538533">"Pred <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Pred menej ako <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Pred viac ako <xliff:g id="DURATION">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 0d3ebe02cad8..c995383540fc 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Opusti"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotaknite se tipala prstnih odtisov"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona prstnih odtisov"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Obraza ni mogoče prepoznati. Uporabite prstni odtis."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Uporabite prstni odtis, če želite nadaljevati."</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Prstnega odtisa ni mogoče prepoznati. Uporabite odklepanje s poverilnico."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Preverjanje vašega obraza …"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Ikona obraza"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Gumb povečave za združljivost."</string>
@@ -666,7 +663,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Opozorilo"</string>
<string name="wallet_title" msgid="5369767670735827105">"Denarnica"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Pripravljeno"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil za Android Work"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Način za letalo"</string>
<string name="add_tile" msgid="6239678623873086686">"Dodajanje ploščice"</string>
@@ -1108,14 +1111,10 @@
<string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Pripomočki za pogovore"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Dotaknite se pogovora, da ga dodate na začetni zaslon."</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Znova preverite tukaj, ko boste prejeli kakšno sporočilo."</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Prednostni pogovori"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Nedavni pogovori"</string>
+ <string name="okay" msgid="6490552955618608554">"V redu"</string>
<string name="timestamp" msgid="6577851592534538533">"pred <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Pred manj kot <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Pred več kot <xliff:g id="DURATION">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 4f0c942ab50e..9d54f5f02bb0 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Eternet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarmi"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Gati"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profili i punës"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modaliteti i aeroplanit"</string>
<string name="add_tile" msgid="6239678623873086686">"Shto një pllakëz"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 58939458f09d..a10d247e0ae2 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -663,7 +663,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Етернет"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Аларм"</string>
<string name="wallet_title" msgid="5369767670735827105">"Новчаник"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Спремно"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Пословни профил"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Режим рада у авиону"</string>
<string name="add_tile" msgid="6239678623873086686">"Додај плочицу"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index ff1324cee8fd..7e43a2a8c45f 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Stäng"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Tryck på fingeravtryckssensorn"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikon för fingeravtryck"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansiktet kändes inte igen. Använd fingeravtryck."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Fortsätt med hjälp av ditt fingeravtryck"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Fingeravtrycket kändes inte igen. Använd låsskärmen i stället."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Håller utkik efter dig …"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Ansiktsikon"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Knapp för kompatibilitetszoom."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Klar"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Jobbprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flygplansläge"</string>
<string name="add_tile" msgid="6239678623873086686">"Lägg till en ruta"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Konversationswidgetar"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tryck på en konversation för att lägga till den på startskärmen"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Besök den här sidan igen när du har fått meddelanden"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Prioriterade konversationer"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Aktuella konversationer"</string>
+ <string name="okay" msgid="6490552955618608554">"Okej"</string>
<string name="timestamp" msgid="6577851592534538533">"För <xliff:g id="DURATION">%1$s</xliff:g> sedan"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Mindre än <xliff:g id="DURATION">%1$s</xliff:g> sedan"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Mer än <xliff:g id="DURATION">%1$s</xliff:g> sedan"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index f1904f473382..27fe2346005c 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethaneti"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Kengele"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Tayari"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Wasifu wa kazini"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Hali ya ndegeni"</string>
<string name="add_tile" msgid="6239678623873086686">"Ongeza kigae"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 79f2125808b3..73f8a56403ee 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ஈதர்நெட்"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"அலாரம்"</string>
<string name="wallet_title" msgid="5369767670735827105">"வாலட்"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"தயாராக உள்ளது"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"பணிக் கணக்கு"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"விமானப் பயன்முறை"</string>
<string name="add_tile" msgid="6239678623873086686">"டைலைச் சேர்க்கும்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index a735020b10a8..e1412100afa5 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ఈథర్‌నెట్"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"అలారం"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"సిద్ధంగా ఉంది"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"కార్యాలయ ప్రొఫైల్‌"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ఎయిర్‌ప్లేన్ మోడ్"</string>
<string name="add_tile" msgid="6239678623873086686">"టైల్‌ను జోడించండి"</string>
diff --git a/packages/SystemUI/res/values-television/styles.xml b/packages/SystemUI/res/values-television/styles.xml
index 97a42d9bc1d2..5772f9d0cc52 100644
--- a/packages/SystemUI/res/values-television/styles.xml
+++ b/packages/SystemUI/res/values-television/styles.xml
@@ -23,7 +23,7 @@
<item name="android:windowExitAnimation">@null</item>
</style>
- <style name="volume_dialog_theme" parent="qs_theme">
+ <style name="volume_dialog_theme" parent="Theme.SystemUI">
<item name="android:colorAccent">@color/tv_volume_dialog_accent</item>
<item name="android:dialogCornerRadius">@dimen/volume_dialog_panel_width_half</item>
</style>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index e851b3d5fa39..65ebb33cb500 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"อีเทอร์เน็ต"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"การปลุก"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"พร้อม"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"โปรไฟล์งาน"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"โหมดบนเครื่องบิน"</string>
<string name="add_tile" msgid="6239678623873086686">"เพิ่มไทล์"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 41f039ba05b4..9c86e44b123f 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Handa na"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profile sa trabaho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Airplane mode"</string>
<string name="add_tile" msgid="6239678623873086686">"Magdagdag ng tile"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b8201e66b390..67e883b3e40c 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="wallet_title" msgid="5369767670735827105">"Cüzdan"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Hazır"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"İş profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Uçak modu"</string>
<string name="add_tile" msgid="6239678623873086686">"Blok ekle"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7ee93772c2b2..f0f51c6423e9 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -666,7 +666,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Сигнал"</string>
<string name="wallet_title" msgid="5369767670735827105">"Гаманець"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Готово"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Робочий профіль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Режим польоту"</string>
<string name="add_tile" msgid="6239678623873086686">"Додавання опції"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index bdd6b1e893b5..4d37244784f9 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -664,7 +664,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ایتھرنیٹ"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"الارم"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"تیار ہے"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"دفتری پروفائل"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ہوائی جہاز وضع"</string>
<string name="add_tile" msgid="6239678623873086686">"ٹائل شامل کریں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 321f36c27d32..01349b44de06 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -177,12 +177,9 @@
<string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Yopish"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Barmoq izi skaneriga tegining"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Barmoq izi belgisi"</string>
- <!-- no translation found for fingerprint_dialog_use_fingerprint_instead (6178228876763024452) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_use_fingerprint (923777032861374285) -->
- <skip />
- <!-- no translation found for fingerprint_dialog_cant_recognize_fp_use_screenlock (4805522676254378353) -->
- <skip />
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Bu yuz notanish. Barmoq izi orqali urining."</string>
+ <string name="fingerprint_dialog_use_fingerprint" msgid="923777032861374285">"Davom etish uchun barmoq izingizdan foydalaning"</string>
+ <string name="fingerprint_dialog_cant_recognize_fp_use_screenlock" msgid="4805522676254378353">"Bu barmoq izi notanish. Ekran qulfi orqali urining."</string>
<string name="face_dialog_looking_for_face" msgid="2656848512116189509">"Yuzingiz tekshirilmoqda…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"Yuz belgisi"</string>
<string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"Kattalashtirish tugmasi mosligi."</string>
@@ -660,7 +657,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Signal"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Tayyor"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Ish profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Parvoz rejimi"</string>
<string name="add_tile" msgid="6239678623873086686">"Tezkor sozlamalar tugmasini qo‘shish"</string>
@@ -1096,14 +1099,10 @@
<string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Suhbat vidjetlari"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Bosh ekranga chiqariladigan suhbat ustiga bosing"</string>
- <!-- no translation found for no_conversations_text (7362374212649891057) -->
- <skip />
- <!-- no translation found for priority_conversations (3967482288896653039) -->
- <skip />
- <!-- no translation found for recent_conversations (8531874684782574622) -->
- <skip />
- <!-- no translation found for okay (6490552955618608554) -->
- <skip />
+ <string name="no_conversations_text" msgid="7362374212649891057">"Keyinroq bu yerda ayrim xabarlar chiqadi"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Muhim suhbatlar"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Oxirgi suhbatlar"</string>
+ <string name="okay" msgid="6490552955618608554">"OK"</string>
<string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g> oldin"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>dan kam vaqt oldin"</string>
<string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>dan ortiq vaqt oldin"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 6ef59c8655e4..dcd029f5751f 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Báo thức"</string>
<string name="wallet_title" msgid="5369767670735827105">"Ví"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Sẵn sàng"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Hồ sơ công việc"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Chế độ máy bay"</string>
<string name="add_tile" msgid="6239678623873086686">"Thêm ô"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index e87f4ddd3ca4..7172e812e6af 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -530,7 +530,7 @@
<string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"此设备归<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>所有,且已连接到多个 VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"您所在的单位可能会监控您工作资料中的网络流量"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"“<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>”可能会监控您工作资料中的网络流量"</string>
- <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT 管理员可以看到工作资料网络活动记录"</string>
+ <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT 管理员可以看到工作资料的网络活动记录"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"网络可能会受到监控"</string>
<string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"此设备已连接到多个 VPN"</string>
<string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"您的工作资料已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"以太网"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"闹钟"</string>
<string name="wallet_title" msgid="5369767670735827105">"电子钱包"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"已可使用"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"工作资料"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飞行模式"</string>
<string name="add_tile" msgid="6239678623873086686">"添加图块"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 8b984580cbde..f243e7c1d452 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"以太網"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"鬧鐘"</string>
<string name="wallet_title" msgid="5369767670735827105">"電子錢包"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"已可使用"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"工作設定檔"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飛行模式"</string>
<string name="add_tile" msgid="6239678623873086686">"加入圖塊"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 714e3e0feda0..ffd235e94761 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"乙太網路"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"鬧鐘"</string>
<string name="wallet_title" msgid="5369767670735827105">"電子錢包"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"已可使用"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"工作資料夾"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飛航模式"</string>
<string name="add_tile" msgid="6239678623873086686">"新增圖塊"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 6d2e37749362..cb6aa0e3b9e0 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -660,7 +660,13 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"I-Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"I-alamu"</string>
<string name="wallet_title" msgid="5369767670735827105">"I-wallet"</string>
+ <!-- no translation found for wallet_button_label_device_unlocked (4653372304880486681) -->
+ <skip />
+ <!-- no translation found for wallet_button_label_device_locked (4418473374652969487) -->
+ <skip />
<string name="wallet_secondary_label" msgid="2017028770884957543">"Isikulungele"</string>
+ <!-- no translation found for wallet_error_generic (257704570182963611) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Iphrofayela yomsebenzi"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Imodi yendiza"</string>
<string name="add_tile" msgid="6239678623873086686">"Engeza ithayili"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index b21c3ae4c2cf..bc7fcde4ae5d 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -79,7 +79,7 @@
(e.g. cannot be switched to) -->
<color name="kg_user_switcher_restricted_avatar_icon_color">@color/GM2_grey_600</color>
<!-- Color of background circle of user avatars in keyguard user switcher -->
- <color name="kg_user_switcher_avatar_background">@color/GM2_grey_300</color>
+ <color name="kg_user_switcher_avatar_background">?android:attr/colorBackgroundFloating</color>
<!-- Icon color for user avatars in user switcher quick settings -->
<color name="qs_user_switcher_avatar_icon_color">#3C4043</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6b7c62821a5f..5a21b30b9aab 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -243,7 +243,7 @@
<dimen name="notification_guts_conversation_action_text_padding_start">32dp</dimen>
<dimen name="conversation_onboarding_bullet_gap_width">6dp</dimen>
- <dimen name="notification_guts_header_top_padding">11dp</dimen>
+ <dimen name="notification_guts_header_top_padding">12dp</dimen>
<!-- The height of the header in inline settings -->
<dimen name="notification_guts_header_height">24dp</dimen>
@@ -449,7 +449,7 @@
<dimen name="notification_panel_width">@dimen/match_parent</dimen>
- <dimen name="brightness_mirror_height">56dp</dimen>
+ <dimen name="brightness_mirror_height">48dp</dimen>
<!-- The width of the panel that holds the quick settings. -->
<dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
@@ -531,10 +531,10 @@
<dimen name="qs_tile_margin_top_bottom">12dp</dimen>
<dimen name="qs_tile_margin_top_bottom_negative">-12dp</dimen>
<!-- The height of the qs customize header. Should be
- (qs_panel_padding_top (48dp) + brightness_mirror_height (56dp) + qs_tile_margin_top (0dp)) -
+ (qs_panel_padding_top (48dp) + brightness_mirror_height (48dp) + qs_tile_margin_top (0dp)) -
(Toolbar_minWidth (56dp) + qs_tile_margin_top_bottom (12dp))
-->
- <dimen name="qs_customize_header_min_height">36dp</dimen>
+ <dimen name="qs_customize_header_min_height">28dp</dimen>
<dimen name="qs_tile_margin_top">0dp</dimen>
<dimen name="qs_tile_icon_background_stroke_width">-1dp</dimen>
<dimen name="qs_tile_background_size">44dp</dimen>
@@ -1437,4 +1437,6 @@
<dimen name="min_wallet_empty_height">208dp</dimen>
<dimen name="wallet_card_border_width">1dp</dimen>
<dimen name="wallet_empty_state_corner_radius">24dp</dimen>
+ <dimen name="wallet_tile_card_view_height">32dp</dimen>
+ <dimen name="wallet_tile_card_view_width">50dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index 6af982ddad72..c39db941af38 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -33,8 +33,6 @@
<!-- AOD/Lockscreen alternate layout -->
<bool name="flag_keyguard_layout">false</bool>
- <bool name="flag_brightness_slider">false</bool>
-
<!-- People Tile flag -->
<bool name="flag_conversations">false</bool>
@@ -52,4 +50,6 @@
<bool name="flag_charging_ripple">false</bool>
<bool name="flag_ongoing_call_status_bar_chip">false</bool>
+
+ <bool name="flag_smartspace">false</bool>
</resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 5f68bdb4f0c6..9665c89cffba 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -167,5 +167,11 @@
<item type="id" name="accessibility_action_move_right"/>
<item type="id" name="accessibility_action_move_up"/>
<item type="id" name="accessibility_action_move_down"/>
+
+ <!-- Accessibility actions for Accessibility floating menu. -->
+ <item type="id" name="action_move_top_left"/>
+ <item type="id" name="action_move_top_right"/>
+ <item type="id" name="action_move_bottom_left"/>
+ <item type="id" name="action_move_bottom_right"/>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8dad40b0cd69..fba62691c951 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1637,8 +1637,12 @@
<string name="wallet_button_label_device_unlocked">Show all</string>
<!-- Label of the button underneath the card carousel when device is locked. [CHAR LIMIT=NONE] -->
<string name="wallet_button_label_device_locked">Unlock to pay</string>
- <!-- Secondary label of the quick access wallet tile. [CHAR LIMIT=32] -->
- <string name="wallet_secondary_label">Ready</string>
+ <!-- Secondary label of the quick access wallet tile if active. [CHAR LIMIT=32] -->
+ <string name="wallet_secondary_label_active">Ready</string>
+ <!-- Secondary label of the quick access wallet tile if no card. [CHAR LIMIT=NONE] -->
+ <string name="wallet_secondary_label_no_card">Set up payment</string>
+ <!-- Secondary label of the quick access wallet tile if device locked. [CHAR LIMIT=NONE] -->
+ <string name="wallet_secondary_label_device_locked">Unlock to use</string>
<!-- Message shown when an unknown failure occurred when fetching cards. [CHAR LIMIT=NONE] -->
<string name="wallet_error_generic">There was a problem getting your cards, please try again later</string>
@@ -1874,13 +1878,13 @@
<string name="notification_channel_summary_automatic_demoted">&lt;b>Status:&lt;/b> Ranked Lower</string>
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary -->
- <string name="notification_channel_summary_priority">Shows at top of conversation section, appears as floating bubble, displays profile picture on lock screen</string>
+ <string name="notification_channel_summary_priority">Always shown at the top of your notifications, even when Priority mode is on</string>
<!--[CHAR LIMIT=30] Linkable text to Settings app -->
<string name="notification_conversation_channel_settings">Settings</string>
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level -->
- <string name="notification_priority_title">Priority</string>
+ <string name="notification_priority_title">Priority conversations</string>
<!-- Text shown in notification guts for conversation notifications that don't implement the full feature -->
<string name="no_shortcut"><xliff:g id="app_name" example="YouTube">%1$s</xliff:g> doesn\u2019t support conversation features</string>
@@ -2648,14 +2652,14 @@
<string name="priority_onboarding_title">Conversation set to priority</string>
<!-- Text explaining that the following actions are the behaviors of priority conversations.
E.g. priority conversations will show at the top of the conversation section [CHAR LIMIT=75] -->
- <string name="priority_onboarding_behavior">Priority conversations will:</string>
- <!-- Text explaining that priority conversations show at the top of the conversation section [CHAR LIMIT=75] -->
- <string name="priority_onboarding_show_at_top_text">Show at top of conversation section</string>
- <!-- Text explaining that priority conversations show an avatar on the lock screen [CHAR LIMIT=75] -->
- <string name="priority_onboarding_show_avatar_text">Show profile picture on lock screen</string>
- <!-- Text explaining that priority conversations will appear as a bubble [CHAR LIMIT=75] -->
- <string name="priority_onboarding_appear_as_bubble_text">Appear as a floating bubble on top of apps</string>
- <!-- Text explaining that priority conversations can interrupt DnD settings [CHAR LIMIT=75] -->
+ <string name="priority_onboarding_behavior">Priority conversations</string>
+ <!-- Text explaining that priority conversations show at the top of the conversation section [CHAR LIMIT=120] -->
+ <string name="priority_onboarding_show_at_top_text">These conversations are shown at the top of your list and can always reach you when Priority mode is on</string>
+ <!-- Text explaining that priority conversations show an avatar on the lock screen [CHAR LIMIT=120] -->
+ <string name="priority_onboarding_show_avatar_text">Profile pictures are shown on the lock screen</string>
+ <!-- Text explaining that priority conversations will appear as a bubble [CHAR LIMIT=120] -->
+ <string name="priority_onboarding_appear_as_bubble_text">You can easily find these conversations in bubbles on your Home screen</string>
+ <!-- Text explaining that priority conversations can interrupt DnD settings [CHAR LIMIT=120] -->
<string name="priority_onboarding_ignores_dnd_text">Interrupt Do Not Disturb</string>
<!-- Title for the affirmative button [CHAR LIMIT=50] -->
<string name="priority_onboarding_done_button_title">Got it</string>
@@ -2693,6 +2697,14 @@
<string name="accessibility_floating_button_migration_tooltip">Accessibility button replaced the accessibility gesture\n\n<annotation id="link">View settings</annotation></string>
<!-- Message for the accessibility floating button docking tooltip. It shows when the user first time drag the button. It will tell the user about docking behavior. [CHAR LIMIT=70] -->
<string name="accessibility_floating_button_docking_tooltip">Move button to the edge to hide it temporarily</string>
+ <!-- Action in accessibility menu to move the accessibility floating button to the top left of the screen. [CHAR LIMIT=30] -->
+ <string name="accessibility_floating_button_action_move_top_left">Move top left</string>
+ <!-- Action in accessibility menu to move the accessibility floating button to the top right of the screen. [CHAR LIMIT=30] -->
+ <string name="accessibility_floating_button_action_move_top_right">Move top right</string>
+ <!-- Action in accessibility menu to move the accessibility floating button to the bottom left of the screen. [CHAR LIMIT=30]-->
+ <string name="accessibility_floating_button_action_move_bottom_left">Move bottom left</string>
+ <!-- Action in accessibility menu to move the accessibility floating button to the bottom right of the screen. [CHAR LIMIT=30]-->
+ <string name="accessibility_floating_button_action_move_bottom_right">Move bottom right</string>
<!-- Device Controls strings -->
<!-- Device Controls empty state, title [CHAR LIMIT=30] -->
@@ -2870,14 +2882,24 @@
<string name="over_timestamp">Over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
<!-- Status text on the Conversation widget for a birthday today [CHAR LIMIT=20] -->
<string name="birthday_status">Birthday</string>
+ <!-- Content description text on the Conversation widget for a birthday today [CHAR LIMIT=150] -->
+ <string name="birthday_status_content_description">It\’s <xliff:g id="name" example="Anna">%1$s</xliff:g>\’s birthday</string>
<!-- Status text on the Conversation widget for an upcoming birthday [CHAR LIMIT=20] -->
<string name="upcoming_birthday_status">Birthday soon</string>
+ <!-- Content description text on the Conversation widget for an upcoming birthday [CHAR LIMIT=150] -->
+ <string name="upcoming_birthday_status_content_description">It\’s <xliff:g id="name" example="Anna">%1$s</xliff:g>\’s birthday soon</string>
<!-- Status text on the Conversation widget for an anniversary [CHAR LIMIT=20] -->
<string name="anniversary_status">Anniversary</string>
+ <!-- Content description text on the Conversation widget for an anniversary [CHAR LIMIT=150] -->
+ <string name="anniversary_status_content_description">It\’s <xliff:g id="name" example="Anna">%1$s</xliff:g>\’s anniversary</string>
<!-- Status text on the Conversation widget for sharing location [CHAR LIMIT=20] -->
<string name="location_status">Sharing location</string>
+ <!-- Content description text on the Conversation widget for sharing location [CHAR LIMIT=150] -->
+ <string name="location_status_content_description"><xliff:g id="name" example="Anna">%1$s</xliff:g> is sharing location</string>
<!-- Status text on the Conversation widget for a new story posted [CHAR LIMIT=20] -->
<string name="new_story_status">New story</string>
+ <!-- Content description text on the Conversation widget for a new story posted on social channels, usually a photograph. [CHAR LIMIT=150] -->
+ <string name="new_story_status_content_description"><xliff:g id="name" example="Anna">%1$s</xliff:g> shared a new story</string>
<!-- Status text on the Conversation widget for watching a video [CHAR LIMIT=20] -->
<string name="video_status">Watching</string>
<!-- Status text on the Conversation widget for listening to audio [CHAR LIMIT=20] -->
@@ -2888,6 +2910,8 @@
<string name="empty_user_name">Friends</string>
<!-- Empty status shown before user has selected a friend for their Conversation widget [CHAR LIMIT=20] -->
<string name="empty_status">Let’s chat tonight!</string>
+ <!-- Empty status shown temporarily before we've been able to load the conversation for their Conversation widget after reboots [CHAR LIMIT=40] -->
+ <string name="status_before_loading">Content will show up soon</string>
<!-- Default text for missed call notifications on their Conversation widget [CHAR LIMIT=20] -->
<string name="missed_call">Missed call</string>
<!-- Text when a Notification may have more messages than the number indicated [CHAR LIMIT=5] -->
@@ -2896,6 +2920,10 @@
<string name="people_tile_description">See recent messages, missed calls, and status updates</string>
<!-- Title text displayed for the Conversation widget [CHAR LIMIT=50] -->
<string name="people_tile_title">Conversation</string>
+ <!-- Content description text on the Conversation widget when a person has sent a new text message [CHAR LIMIT=150] -->
+ <string name="new_notification_text_content_description"><xliff:g id="name" example="Anna">%1$s</xliff:g> sent a message</string>
+ <!-- Content description text on the Conversation widget when a person has sent a new image message [CHAR LIMIT=150] -->
+ <string name="new_notification_image_content_description"><xliff:g id="name" example="Anna">%1$s</xliff:g> sent an image</string>
<!-- Title to display in a notification when ACTION_BATTERY_CHANGED.EXTRA_PRESENT field is false
[CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 0eb4d08d7421..e6fc332fff8f 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -316,7 +316,7 @@
<style name="Animation.StatusBar">
</style>
- <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+ <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.SystemUI">
<item name="lightIconTheme">@style/DualToneLightTheme</item>
<item name="darkIconTheme">@style/DualToneDarkTheme</item>
<item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
@@ -375,7 +375,7 @@
<item name="*android:dotColor">?android:attr/textColorSecondary</item>
</style>
- <style name="qs_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+ <style name="Theme.SystemUI.QuickSettings" parent="@*android:style/Theme.DeviceDefault.SystemUI">
<item name="lightIconTheme">@style/QSIconTheme</item>
<item name="darkIconTheme">@style/QSIconTheme</item>
<item name="android:colorError">@*android:color/error_color_material_dark</item>
@@ -384,7 +384,7 @@
</style>
<!-- Overridden by values-television/styles.xml with tv-specific settings -->
- <style name="volume_dialog_theme" parent="qs_theme"/>
+ <style name="volume_dialog_theme" parent="Theme.SystemUI"/>
<style name="Theme.SystemUI.Dialog" parent="@android:style/Theme.DeviceDefault.Light.Dialog" />
@@ -587,7 +587,7 @@
<item name="android:elevation">10dp</item>
</style>
- <style name="edit_theme" parent="qs_theme">
+ <style name="Theme.SystemUI.QuickSettings.Edit">
<item name="android:colorBackground">?android:attr/colorSecondary</item>
</style>
diff --git a/packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java b/packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java
index ed465de0e766..15312ad9dfd1 100644
--- a/packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java
+++ b/packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.hardware.biometrics.BiometricSourceType;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -73,7 +74,7 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
@NonNull KeyguardStateController keyguardStateController
) {
super(view);
- mView.setOnClickListener(mOnClickListener);
+ mView.setOnTouchListener(mOnTouchListener);
mView.setSensorProperties(authController.getUdfpsProps().get(0));
mStatusBarStateController = statusBarStateController;
@@ -153,11 +154,11 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen);
}
- private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
+ private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
@Override
- public void onClick(View v) {
- // if the device is locked, shows bouncer, else goes to launcher
+ public boolean onTouch(View v, MotionEvent event) {
mKeyguardViewController.showBouncer(/* scrim */ true);
+ return true;
}
};
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 0675200f81e2..24b7cd118ed6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -16,8 +16,15 @@
package com.android.keyguard;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+
import android.app.WallpaperManager;
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.SmartspaceManager;
+import android.app.smartspace.SmartspaceSession;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.res.Resources;
import android.provider.Settings;
import android.text.TextUtils;
@@ -25,6 +32,7 @@ import android.text.format.DateFormat;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.keyguard.clock.ClockManager;
@@ -32,8 +40,12 @@ import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.plugins.ClockPlugin;
+import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
@@ -43,6 +55,7 @@ import com.android.systemui.util.ViewController;
import java.util.Locale;
import java.util.TimeZone;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -68,6 +81,13 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
private AnimatableClockController mNewLockScreenLargeClockViewController;
private FrameLayout mNewLockScreenLargeClockFrame;
+ private PluginManager mPluginManager;
+ private boolean mIsSmartspaceEnabled;
+ PluginListener mPluginListener;
+ private Executor mUiExecutor;
+ private SmartspaceSession mSmartspaceSession;
+ private SmartspaceSession.Callback mSmartspaceCallback;
+
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private final StatusBarStateController.StateListener mStateListener =
@@ -96,6 +116,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
private String mTimeFormat;
+ // If set, will replace keyguard_status_area
+ private BcSmartspaceDataPlugin.SmartspaceView mSmartspaceView;
+
@Inject
public KeyguardClockSwitchController(
KeyguardClockSwitch keyguardClockSwitch,
@@ -105,7 +128,10 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
KeyguardSliceViewController keyguardSliceViewController,
NotificationIconAreaController notificationIconAreaController,
ContentResolver contentResolver,
- BroadcastDispatcher broadcastDispatcher) {
+ BroadcastDispatcher broadcastDispatcher,
+ PluginManager pluginManager,
+ FeatureFlags featureFlags,
+ @Main Executor uiExecutor) {
super(keyguardClockSwitch);
mResources = resources;
mStatusBarStateController = statusBarStateController;
@@ -115,6 +141,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mNotificationIconAreaController = notificationIconAreaController;
mBroadcastDispatcher = broadcastDispatcher;
mTimeFormat = Settings.System.getString(contentResolver, Settings.System.TIME_12_24);
+ mPluginManager = pluginManager;
+ mIsSmartspaceEnabled = featureFlags.isSmartspaceEnabled();
+ mUiExecutor = uiExecutor;
}
/**
@@ -137,6 +166,63 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
updateAodIcons();
mNewLockScreenClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view);
mNewLockScreenLargeClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view_large);
+
+ // If a smartspace plugin is detected, replace the existing smartspace
+ // (keyguard_status_area), and initialize a new session
+ mPluginListener = new PluginListener<BcSmartspaceDataPlugin>() {
+
+ @Override
+ public void onPluginConnected(BcSmartspaceDataPlugin plugin, Context pluginContext) {
+ if (!mIsSmartspaceEnabled) return;
+
+ View ksa = mView.findViewById(R.id.keyguard_status_area);
+ int ksaIndex = mView.indexOfChild(ksa);
+ ksa.setVisibility(View.GONE);
+
+ mSmartspaceView = plugin.getView(mView);
+ mSmartspaceView.registerDataProvider(plugin);
+
+ RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
+ MATCH_PARENT, WRAP_CONTENT);
+ lp.addRule(RelativeLayout.BELOW, R.id.new_lockscreen_clock_view);
+ mView.addView((View) mSmartspaceView, ksaIndex, lp);
+
+ View nic = mView.findViewById(
+ com.android.systemui.R.id.left_aligned_notification_icon_container);
+ lp = (RelativeLayout.LayoutParams) nic.getLayoutParams();
+ lp.addRule(RelativeLayout.BELOW, ((View) mSmartspaceView).getId());
+ nic.setLayoutParams(lp);
+
+ createSmartspaceSession(plugin);
+ }
+
+ @Override
+ public void onPluginDisconnected(BcSmartspaceDataPlugin plugin) {
+ if (!mIsSmartspaceEnabled) return;
+
+ mView.removeView((View) mSmartspaceView);
+ mView.findViewById(R.id.keyguard_status_area).setVisibility(View.VISIBLE);
+
+ View nic = mView.findViewById(
+ com.android.systemui.R.id.left_aligned_notification_icon_container);
+ RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)
+ nic.getLayoutParams();
+ lp.addRule(RelativeLayout.BELOW, R.id.keyguard_status_area);
+ nic.setLayoutParams(lp);
+
+ mSmartspaceView = null;
+ }
+
+ private void createSmartspaceSession(BcSmartspaceDataPlugin plugin) {
+ mSmartspaceSession = getContext().getSystemService(SmartspaceManager.class)
+ .createSmartspaceSession(
+ new SmartspaceConfig.Builder(getContext(), "lockscreen").build());
+ mSmartspaceCallback = targets -> plugin.onTargetsAvailable(targets);
+ mSmartspaceSession.registerSmartspaceUpdates(mUiExecutor, mSmartspaceCallback);
+ mSmartspaceSession.requestSmartspaceUpdate();
+ }
+ };
+ mPluginManager.addPluginListener(mPluginListener, BcSmartspaceDataPlugin.class, false);
}
@Override
@@ -147,6 +233,13 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mStatusBarStateController.removeCallback(mStateListener);
mColorExtractor.removeOnColorsChangedListener(mColorsListener);
mView.setClockPlugin(null, mStatusBarStateController.getState());
+
+ if (mSmartspaceSession != null) {
+ mSmartspaceSession.unregisterSmartspaceUpdates(mSmartspaceCallback);
+ mSmartspaceSession.destroy();
+ mSmartspaceSession = null;
+ }
+ mPluginManager.removePluginListener(mPluginListener);
}
/**
@@ -222,6 +315,11 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_Y,
scale, props, animate);
}
+
+ if (mSmartspaceView != null) {
+ PropertyAnimator.setProperty((View) mSmartspaceView, AnimatableProperty.TRANSLATION_X,
+ x, props, animate);
+ }
mKeyguardSliceViewController.updatePosition(x, props, animate);
mNotificationIconAreaController.updatePosition(x, props, animate);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 621ca594393e..de09eaa666ca 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1777,6 +1777,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
break;
case MSG_TIME_FORMAT_UPDATE:
handleTimeFormatUpdate((String) msg.obj);
+ break;
case MSG_REQUIRE_NFC_UNLOCK:
handleRequireUnlockForNfc();
break;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
index ab05c2a273ad..57be4e8477b2 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -31,6 +31,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
@@ -39,6 +40,8 @@ import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
@@ -284,6 +287,44 @@ public class AccessibilityFloatingMenuView extends FrameLayout
// Do Nothing
}
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ setupAccessibilityActions(info);
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ if (super.performAccessibilityAction(action, arguments)) {
+ return true;
+ }
+
+ fadeIn();
+
+ final Rect bounds = getAvailableBounds();
+ if (action == R.id.action_move_top_left) {
+ snapToLocation(bounds.left, bounds.top);
+ return true;
+ }
+
+ if (action == R.id.action_move_top_right) {
+ snapToLocation(bounds.right, bounds.top);
+ return true;
+ }
+
+ if (action == R.id.action_move_bottom_left) {
+ snapToLocation(bounds.left, bounds.bottom);
+ return true;
+ }
+
+ if (action == R.id.action_move_bottom_right) {
+ snapToLocation(bounds.right, bounds.bottom);
+ return true;
+ }
+
+ return false;
+ }
+
void show() {
if (isShowing()) {
return;
@@ -380,6 +421,33 @@ public class AccessibilityFloatingMenuView extends FrameLayout
mUiHandler.postDelayed(() -> mFadeOutAnimator.start(), FADE_EFFECT_DURATION_MS);
}
+ private void setupAccessibilityActions(AccessibilityNodeInfo info) {
+ final Resources res = mContext.getResources();
+ final AccessibilityAction moveTopLeft =
+ new AccessibilityAction(R.id.action_move_top_left,
+ res.getString(
+ R.string.accessibility_floating_button_action_move_top_left));
+ info.addAction(moveTopLeft);
+
+ final AccessibilityAction moveTopRight =
+ new AccessibilityAction(R.id.action_move_top_right,
+ res.getString(
+ R.string.accessibility_floating_button_action_move_top_right));
+ info.addAction(moveTopRight);
+
+ final AccessibilityAction moveBottomLeft =
+ new AccessibilityAction(R.id.action_move_bottom_left,
+ res.getString(
+ R.string.accessibility_floating_button_action_move_bottom_left));
+ info.addAction(moveBottomLeft);
+
+ final AccessibilityAction moveBottomRight =
+ new AccessibilityAction(R.id.action_move_bottom_right,
+ res.getString(
+ R.string.accessibility_floating_button_action_move_bottom_right));
+ info.addAction(moveBottomRight);
+ }
+
private boolean onTouched(MotionEvent event) {
final int action = event.getAction();
final int currentX = (int) event.getX();
@@ -524,7 +592,8 @@ public class AccessibilityFloatingMenuView extends FrameLayout
updateLocationWith(mAlignment, mPercentageY);
}
- private void snapToLocation(int endX, int endY) {
+ @VisibleForTesting
+ void snapToLocation(int endX, int endY) {
mDragAnimator.cancel();
mDragAnimator.removeAllUpdateListeners();
mDragAnimator.addUpdateListener(anim -> onDragAnimationUpdate(anim, endX, endY));
@@ -662,6 +731,11 @@ public class AccessibilityFloatingMenuView extends FrameLayout
: R.dimen.accessibility_floating_menu_large_single_radius;
}
+ @VisibleForTesting
+ Rect getAvailableBounds() {
+ return new Rect(0, 0, mScreenWidth - getWindowWidth(), mScreenHeight - getWindowHeight());
+ }
+
private int getLayoutWidth() {
return mPadding * 2 + mIconWidth;
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
index 60fdbab8482c..5647e4366075 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
@@ -32,9 +32,10 @@ import android.widget.FrameLayout;
* - optionally can override dozeTimeTick to adjust views for burn-in mitigation
*/
abstract class UdfpsAnimationView extends FrameLayout {
-
+ // mAlpha takes into consideration the status bar expansion amount to fade out icon when
+ // the status bar is expanded
private int mAlpha;
- private boolean mPauseAuth;
+ boolean mPauseAuth;
public UdfpsAnimationView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -75,7 +76,7 @@ abstract class UdfpsAnimationView extends FrameLayout {
getDrawable().setAlpha(calculateAlpha());
}
- protected final int calculateAlpha() {
+ int calculateAlpha() {
return mPauseAuth ? mAlpha : 255;
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java
index 2f025f63034e..f4993f46bf1d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java
@@ -16,10 +16,6 @@
package com.android.systemui.biometrics;
-import static com.android.systemui.statusbar.StatusBarState.FULLSCREEN_USER_SWITCHER;
-import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
-import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
-
import android.annotation.NonNull;
import android.graphics.PointF;
import android.graphics.RectF;
@@ -68,18 +64,13 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
@Override
protected void onViewAttached() {
- mStatusBarStateController.addCallback(mStateListener);
- mStateListener.onStateChanged(mStatusBarStateController.getState());
mStatusBar.addExpansionChangedListener(mStatusBarExpansionChangedListener);
-
mDumpManger.registerDumpable(getDumpTag(), this);
}
@Override
protected void onViewDetached() {
- mStatusBarStateController.removeCallback(mStateListener);
mStatusBar.removeExpansionChangedListener(mStatusBarExpansionChangedListener);
-
mDumpManger.unregisterDumpable(getDumpTag());
}
@@ -106,9 +97,7 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
* authentication.
*/
boolean shouldPauseAuth() {
- return (mNotificationShadeExpanded && mStatusBarState != KEYGUARD)
- || mStatusBarState == SHADE_LOCKED
- || mStatusBarState == FULLSCREEN_USER_SWITCHER;
+ return mNotificationShadeExpanded;
}
/**
@@ -188,13 +177,4 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
updatePauseAuth();
}
};
-
- private final StatusBarStateController.StateListener mStateListener =
- new StatusBarStateController.StateListener() {
- @Override
- public void onStateChanged(int newState) {
- mStatusBarState = newState;
- updatePauseAuth();
- }
- };
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 7b5d7cb5a525..2bdbf518e203 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -52,6 +52,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -90,6 +91,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
@NonNull private final DumpManager mDumpManager;
@NonNull private final AuthRippleController mAuthRippleController;
@NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @NonNull private final KeyguardViewMediator mKeyguardViewMediator;
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
// sensors, this, in addition to a lot of the code here, will be updated.
@VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
@@ -310,7 +312,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
@NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@NonNull DumpManager dumpManager,
@NonNull AuthRippleController authRippleController,
- @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor) {
+ @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
+ @NonNull KeyguardViewMediator keyguardViewMediator) {
mContext = context;
mInflater = inflater;
// The fingerprint manager is queried for UDFPS before this class is constructed, so the
@@ -324,6 +327,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
mDumpManager = dumpManager;
mAuthRippleController = authRippleController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mKeyguardViewMediator = keyguardViewMediator;
mSensorProps = findFirstUdfps();
// At least one UDFPS sensor exists
@@ -491,7 +495,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
mKeyguardViewManager,
mKeyguardUpdateMonitor,
mFgExecutor,
- mDumpManager
+ mDumpManager,
+ mKeyguardViewMediator
);
case IUdfpsOverlayController.REASON_AUTH_BP:
// note: empty controller, currently shows no visual affordance
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index 4590182ac870..fc906f2137f2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -97,6 +97,11 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
}
}
+ @Override
+ int calculateAlpha() {
+ return mPauseAuth ? 0 : 255;
+ }
+
void onDozeAmountChanged(float linear, float eased) {
mFingerprintDrawable.onDozeAmountChanged(linear, eased);
}
@@ -153,6 +158,10 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
return mStatusBarState == StatusBarState.SHADE_LOCKED;
}
+ boolean isHome() {
+ return mStatusBarState == StatusBarState.SHADE;
+ }
+
/**
* Animates out the bg protection circle behind the fp icon to unhighlight the icon.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 9d846fa54e5b..dc0c685bf01e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -16,6 +16,8 @@
package com.android.systemui.biometrics;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+
import android.annotation.NonNull;
import android.hardware.biometrics.BiometricSourceType;
@@ -24,7 +26,9 @@ import androidx.annotation.Nullable;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -45,12 +49,15 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
@NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@NonNull private final DelayableExecutor mExecutor;
+ @NonNull private final KeyguardViewMediator mKeyguardViewMediator;
@Nullable private Runnable mCancelRunnable;
private boolean mShowBouncer;
private boolean mQsExpanded;
private boolean mFaceDetectRunning;
private boolean mHintShown;
+ private boolean mTransitioningFromHome;
+ private int mStatusBarState;
protected UdfpsKeyguardViewController(
@NonNull UdfpsKeyguardView view,
@@ -59,11 +66,13 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
@NonNull DelayableExecutor mainDelayableExecutor,
- @NonNull DumpManager dumpManager) {
+ @NonNull DumpManager dumpManager,
+ @NonNull KeyguardViewMediator keyguardViewMediator) {
super(view, statusBarStateController, statusBar, dumpManager);
mKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mExecutor = mainDelayableExecutor;
+ mKeyguardViewMediator = keyguardViewMediator;
}
@Override
@@ -94,6 +103,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mStatusBarStateController.removeCallback(mStateListener);
mAlternateAuthInterceptor.hideAlternateAuthBouncer();
mKeyguardViewManager.setAlternateAuthInterceptor(null);
+ mTransitioningFromHome = false;
if (mCancelRunnable != null) {
mCancelRunnable.run();
@@ -106,17 +116,18 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
super.dump(fd, pw, args);
pw.println("mShowBouncer=" + mShowBouncer);
pw.println("mFaceDetectRunning=" + mFaceDetectRunning);
+ pw.println("mTransitioningFromHomeToKeyguard=" + mTransitioningFromHome);
}
/**
* Overrides non-bouncer show logic in shouldPauseAuth to still auth.
*/
- private void showBouncer(boolean forceShow) {
- if (mShowBouncer == forceShow) {
+ private void showBouncer(boolean show) {
+ if (mShowBouncer == show) {
return;
}
- mShowBouncer = forceShow;
+ mShowBouncer = show;
updatePauseAuth();
if (mShowBouncer) {
mView.animateUdfpsBouncer();
@@ -128,18 +139,26 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
/**
* Returns true if the fingerprint manager is running but we want to temporarily pause
* authentication. On the keyguard, we may want to show udfps when the shade
- * is expanded, so this can be overridden with the forceShow method.
+ * is expanded, so this can be overridden with the showBouncer method.
*/
public boolean shouldPauseAuth() {
if (mShowBouncer) {
return false;
}
+ if (mStatusBarState != KEYGUARD) {
+ return true;
+ }
+
+ if (mTransitioningFromHome && mKeyguardViewMediator.isAnimatingScreenOff()) {
+ return true;
+ }
+
if (mQsExpanded) {
return true;
}
- return super.shouldPauseAuth();
+ return false;
}
private void cancelDelayedHint() {
@@ -176,12 +195,25 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
new StatusBarStateController.StateListener() {
@Override
public void onDozeAmountChanged(float linear, float eased) {
- mView.onDozeAmountChanged(linear, eased);
if (linear != 0) showBouncer(false);
+ mView.onDozeAmountChanged(linear, eased);
+ if (linear == 1f) {
+ // transition has finished
+ mTransitioningFromHome = false;
+ }
+ updatePauseAuth();
+ }
+
+ @Override
+ public void onStatePreChange(int oldState, int newState) {
+ mTransitioningFromHome = oldState == StatusBarState.SHADE
+ && newState == StatusBarState.KEYGUARD;
+ updatePauseAuth();
}
@Override
public void onStateChanged(int statusBarState) {
+ mStatusBarState = statusBarState;
mView.setStatusBarState(statusBarState);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
index 96f207215f71..8c3ef68f0bde 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
@@ -44,8 +44,9 @@ import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
-import com.android.systemui.globalactions.GlobalActionsDialog
import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_FILE
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_SEEDING_COMPLETED
import com.android.systemui.util.concurrency.DelayableExecutor
import java.io.FileDescriptor
import java.io.PrintWriter
@@ -198,11 +199,11 @@ class ControlsControllerImpl @Inject constructor (
// When a component is uninstalled, allow seeding to happen again if the user
// reinstalls the app
val prefs = userStructure.userContext.getSharedPreferences(
- GlobalActionsDialog.PREFS_CONTROLS_FILE, Context.MODE_PRIVATE)
+ PREFS_CONTROLS_FILE, Context.MODE_PRIVATE)
val completedSeedingPackageSet = prefs.getStringSet(
- GlobalActionsDialog.PREFS_CONTROLS_SEEDING_COMPLETED, mutableSetOf<String>())
+ PREFS_CONTROLS_SEEDING_COMPLETED, mutableSetOf<String>())
val servicePackageSet = serviceInfoSet.map { it.packageName }
- prefs.edit().putStringSet(GlobalActionsDialog.PREFS_CONTROLS_SEEDING_COMPLETED,
+ prefs.edit().putStringSet(PREFS_CONTROLS_SEEDING_COMPLETED,
completedSeedingPackageSet.intersect(servicePackageSet)).apply()
var changed = false
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
index 7dd1d28170b2..6f94943472b1 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.management
+import android.app.ActivityOptions
import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
@@ -34,7 +35,6 @@ import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.controls.controller.StructureInfo
import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
-import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.settings.CurrentUserTracker
import com.android.systemui.util.LifecycleActivity
import javax.inject.Inject
@@ -45,7 +45,6 @@ import javax.inject.Inject
class ControlsEditingActivity @Inject constructor(
private val controller: ControlsControllerImpl,
private val broadcastDispatcher: BroadcastDispatcher,
- private val globalActionsComponent: GlobalActionsComponent,
private val customIconCache: CustomIconCache,
private val uiController: ControlsUiController
) : LifecycleActivity() {
@@ -62,7 +61,6 @@ class ControlsEditingActivity @Inject constructor(
private lateinit var model: FavoritesModel
private lateinit var subtitle: TextView
private lateinit var saveButton: View
- private var backToGlobalActions = true
private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) {
private val startingUser = controller.currentUserId
@@ -86,11 +84,6 @@ class ControlsEditingActivity @Inject constructor(
structure = it
} ?: run(this::finish)
- backToGlobalActions = intent.getBooleanExtra(
- ControlsUiController.BACK_TO_GLOBAL_ACTIONS,
- true
- )
-
bindViews()
bindButtons()
@@ -109,15 +102,6 @@ class ControlsEditingActivity @Inject constructor(
}
override fun onBackPressed() {
- if (backToGlobalActions) {
- globalActionsComponent.handleShowGlobalActionsMenu()
- } else {
- val i = Intent().apply {
- component = ComponentName(applicationContext, ControlsActivity::class.java)
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
- }
- startActivity(i)
- }
animateExitAndFinish()
}
@@ -161,8 +145,12 @@ class ControlsEditingActivity @Inject constructor(
setText(R.string.save)
setOnClickListener {
saveFavorites()
+ startActivity(
+ Intent(applicationContext, ControlsActivity::class.java),
+ ActivityOptions
+ .makeSceneTransitionAnimation(this@ControlsEditingActivity).toBundle()
+ )
animateExitAndFinish()
- globalActionsComponent.handleShowGlobalActionsMenu()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index 309901443393..dca52a9678b9 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -43,7 +43,6 @@ import com.android.systemui.controls.controller.StructureInfo
import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.settings.CurrentUserTracker
import com.android.systemui.util.LifecycleActivity
import java.text.Collator
@@ -56,7 +55,6 @@ class ControlsFavoritingActivity @Inject constructor(
private val controller: ControlsControllerImpl,
private val listingController: ControlsListingController,
private val broadcastDispatcher: BroadcastDispatcher,
- private val globalActionsComponent: GlobalActionsComponent,
private val uiController: ControlsUiController
) : LifecycleActivity() {
@@ -92,7 +90,6 @@ class ControlsFavoritingActivity @Inject constructor(
private lateinit var comparator: Comparator<StructureContainer>
private var cancelLoadRunnable: Runnable? = null
private var isPagerLoaded = false
- private var backToGlobalActions = true
private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) {
private val startingUser = controller.currentUserId
@@ -133,11 +130,6 @@ class ControlsFavoritingActivity @Inject constructor(
component = intent.getParcelableExtra<ComponentName>(Intent.EXTRA_COMPONENT_NAME)
fromProviderSelector = intent.getBooleanExtra(EXTRA_FROM_PROVIDER_SELECTOR, false)
- backToGlobalActions = intent.getBooleanExtra(
- ControlsUiController.BACK_TO_GLOBAL_ACTIONS,
- true
- )
-
bindViews()
}
@@ -311,13 +303,6 @@ class ControlsFavoritingActivity @Inject constructor(
private fun bindButtons() {
otherAppsButton = requireViewById<Button>(R.id.other_apps).apply {
setOnClickListener {
- val i = Intent().apply {
- component = ComponentName(context, ControlsProviderSelectorActivity::class.java)
- putExtra(
- ControlsUiController.BACK_TO_GLOBAL_ACTIONS,
- backToGlobalActions
- )
- }
if (doneButton.isEnabled) {
// The user has made changes
Toast.makeText(
@@ -326,8 +311,11 @@ class ControlsFavoritingActivity @Inject constructor(
Toast.LENGTH_SHORT
).show()
}
- startActivity(i, ActivityOptions
- .makeSceneTransitionAnimation(this@ControlsFavoritingActivity).toBundle())
+ startActivity(
+ Intent(context, ControlsProviderSelectorActivity::class.java),
+ ActivityOptions
+ .makeSceneTransitionAnimation(this@ControlsFavoritingActivity).toBundle()
+ )
animateExitAndFinish()
}
}
@@ -349,15 +337,10 @@ class ControlsFavoritingActivity @Inject constructor(
}
private fun openControlsOrigin() {
- if (backToGlobalActions) {
- globalActionsComponent.handleShowGlobalActionsMenu()
- } else {
- val i = Intent().apply {
- component = ComponentName(applicationContext, ControlsActivity::class.java)
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
- }
- startActivity(i)
- }
+ startActivity(
+ Intent(applicationContext, ControlsActivity::class.java),
+ ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
+ )
}
override fun onPause() {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index fa1c41f01e6c..cba3dabc4ff4 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -36,7 +36,6 @@ import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.settings.CurrentUserTracker
import com.android.systemui.util.LifecycleActivity
import java.util.concurrent.Executor
@@ -50,7 +49,6 @@ class ControlsProviderSelectorActivity @Inject constructor(
@Background private val backExecutor: Executor,
private val listingController: ControlsListingController,
private val controlsController: ControlsController,
- private val globalActionsComponent: GlobalActionsComponent,
private val broadcastDispatcher: BroadcastDispatcher,
private val uiController: ControlsUiController
) : LifecycleActivity() {
@@ -59,7 +57,6 @@ class ControlsProviderSelectorActivity @Inject constructor(
private const val TAG = "ControlsProviderSelectorActivity"
}
- private var backToGlobalActions = true
private lateinit var recyclerView: RecyclerView
private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) {
private val startingUser = listingController.currentUserId
@@ -105,23 +102,13 @@ class ControlsProviderSelectorActivity @Inject constructor(
}
}
requireViewById<View>(R.id.done).visibility = View.GONE
-
- backToGlobalActions = intent.getBooleanExtra(
- ControlsUiController.BACK_TO_GLOBAL_ACTIONS,
- true
- )
}
override fun onBackPressed() {
- if (backToGlobalActions) {
- globalActionsComponent.handleShowGlobalActionsMenu()
- } else {
- val i = Intent().apply {
- component = ComponentName(applicationContext, ControlsActivity::class.java)
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
- }
- startActivity(i)
+ val i = Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
}
+ startActivity(i, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
animateExitAndFinish()
}
@@ -169,10 +156,6 @@ class ControlsProviderSelectorActivity @Inject constructor(
listingController.getAppLabel(it))
putExtra(Intent.EXTRA_COMPONENT_NAME, it)
putExtra(ControlsFavoritingActivity.EXTRA_FROM_PROVIDER_SELECTOR, true)
- putExtra(
- ControlsUiController.BACK_TO_GLOBAL_ACTIONS,
- backToGlobalActions
- )
}
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
animateExitAndFinish()
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
index 0db15e83fc93..8029ba844850 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
@@ -26,7 +26,7 @@ import android.service.controls.Control
interface ControlActionCoordinator {
// If launched from an Activity, continue within this stack
- var activityContext: Context?
+ var activityContext: Context
/**
* Close any dialogs which may have been open
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
index 477c22068851..d3d6e03c9bc7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -63,7 +63,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
private var actionsInProgress = mutableSetOf<String>()
private val isLocked: Boolean
get() = !keyguardStateController.isUnlocked()
- override var activityContext: Context? = null
+ override lateinit var activityContext: Context
companion object {
private const val RESPONSE_TIMEOUT_IN_MILLIS = 3000L
@@ -153,14 +153,9 @@ class ControlActionCoordinatorImpl @Inject constructor(
// pending actions will only run after the control state has been refreshed
pendingAction = action
}
- val wasLocked = isLocked
activityStarter.dismissKeyguardThenExecute({
Log.d(ControlsUiController.TAG, "Device unlocked, invoking controls action")
- if (wasLocked && activityContext == null) {
- globalActionsComponent.handleShowGlobalActionsMenu()
- } else {
- action.invoke()
- }
+ action.invoke()
true
}, { pendingAction = null }, true /* afterKeyguardGone */)
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
index a35b792ac7f1..c241c083a0a3 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -41,6 +41,14 @@ class ControlsActivity @Inject constructor(
setContentView(R.layout.controls_fullscreen)
+ getLifecycle().addObserver(
+ ControlsAnimations.observerForAnimations(
+ requireViewById<ViewGroup>(R.id.control_detail_root),
+ window,
+ intent
+ )
+ )
+
requireViewById<ViewGroup>(R.id.control_detail_root).apply {
setOnApplyWindowInsetsListener {
v: View, insets: WindowInsets ->
@@ -61,7 +69,7 @@ class ControlsActivity @Inject constructor(
parent = requireViewById<ViewGroup>(R.id.global_actions_controls)
parent.alpha = 0f
- uiController.show(parent, { animateExitAndFinish() }, this)
+ uiController.show(parent, { finish() }, this)
}
override fun onResume() {
@@ -71,7 +79,7 @@ class ControlsActivity @Inject constructor(
}
override fun onBackPressed() {
- animateExitAndFinish()
+ finish()
}
override fun onStop() {
@@ -79,8 +87,4 @@ class ControlsActivity @Inject constructor(
uiController.hide()
}
-
- private fun animateExitAndFinish() {
- ControlsAnimations.exitAnimation(parent, { finish() }).start()
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
index f86948ee8957..ac13aadeeb40 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
@@ -28,10 +28,9 @@ interface ControlsUiController {
companion object {
public const val TAG = "ControlsUiController"
public const val EXTRA_ANIMATE = "extra_animate"
- public const val BACK_TO_GLOBAL_ACTIONS = "back_to_global_actions"
}
- fun show(parent: ViewGroup, onDismiss: Runnable, activityContext: Context?)
+ fun show(parent: ViewGroup, onDismiss: Runnable, activityContext: Context)
fun hide()
/**
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index d08882b1dbd2..954bfb3ff891 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -19,6 +19,8 @@ package com.android.systemui.controls.ui
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
+import android.app.Activity
+import android.app.ActivityOptions
import android.content.ComponentName
import android.content.Context
import android.content.Intent
@@ -129,6 +131,7 @@ class ControlsUiControllerImpl @Inject constructor (
override val available: Boolean
get() = controlsController.get().available
+ private lateinit var activityContext: Context
private lateinit var listingCallback: ControlsListingController.ControlsListingCallback
private fun createCallback(
@@ -153,11 +156,12 @@ class ControlsUiControllerImpl @Inject constructor (
override fun show(
parent: ViewGroup,
onDismiss: Runnable,
- activityContext: Context?
+ activityContext: Context
) {
Log.d(ControlsUiController.TAG, "show()")
this.parent = parent
this.onDismiss = onDismiss
+ this.activityContext = activityContext
hidden = false
retainCache = false
@@ -198,7 +202,7 @@ class ControlsUiControllerImpl @Inject constructor (
controlViewsById.clear()
controlsById.clear()
- show(parent, onDismiss, controlActionCoordinator.activityContext)
+ show(parent, onDismiss, activityContext)
val showAnim = ObjectAnimator.ofFloat(parent, "alpha", 0.0f, 1.0f)
showAnim.setInterpolator(DecelerateInterpolator(1.0f))
showAnim.setDuration(FADE_IN_MILLIS)
@@ -220,7 +224,7 @@ class ControlsUiControllerImpl @Inject constructor (
inflater.inflate(R.layout.controls_no_favorites, parent, true)
val viewGroup = parent.requireViewById(R.id.controls_no_favorites_group) as ViewGroup
- viewGroup.setOnClickListener { v: View -> startProviderSelectorActivity(v.context) }
+ viewGroup.setOnClickListener { _: View -> startProviderSelectorActivity() }
val subtitle = parent.requireViewById<TextView>(R.id.controls_subtitle)
subtitle.setText(context.resources.getString(R.string.quick_controls_subtitle))
@@ -234,20 +238,18 @@ class ControlsUiControllerImpl @Inject constructor (
}
}
- private fun startFavoritingActivity(context: Context, si: StructureInfo) {
- startTargetedActivity(context, si, ControlsFavoritingActivity::class.java)
+ private fun startFavoritingActivity(si: StructureInfo) {
+ startTargetedActivity(si, ControlsFavoritingActivity::class.java)
}
- private fun startEditingActivity(context: Context, si: StructureInfo) {
- startTargetedActivity(context, si, ControlsEditingActivity::class.java)
+ private fun startEditingActivity(si: StructureInfo) {
+ startTargetedActivity(si, ControlsEditingActivity::class.java)
}
- private fun startTargetedActivity(context: Context, si: StructureInfo, klazz: Class<*>) {
- val i = Intent(context, klazz).apply {
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
- }
+ private fun startTargetedActivity(si: StructureInfo, klazz: Class<*>) {
+ val i = Intent(activityContext, klazz)
putIntentExtras(i, si)
- startActivity(context, i)
+ startActivity(i)
retainCache = true
}
@@ -261,27 +263,22 @@ class ControlsUiControllerImpl @Inject constructor (
}
}
- private fun startProviderSelectorActivity(context: Context) {
- val i = Intent(context, ControlsProviderSelectorActivity::class.java).apply {
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
- }
- startActivity(context, i)
+ private fun startProviderSelectorActivity() {
+ startActivity(Intent(activityContext, ControlsProviderSelectorActivity::class.java))
}
- private fun startActivity(context: Context, intent: Intent) {
+ private fun startActivity(intent: Intent) {
// Force animations when transitioning from a dialog to an activity
intent.putExtra(ControlsUiController.EXTRA_ANIMATE, true)
- intent.putExtra(
- ControlsUiController.BACK_TO_GLOBAL_ACTIONS,
- controlActionCoordinator.activityContext == null
- )
- onDismiss.run()
- activityStarter.dismissKeyguardThenExecute({
- shadeController.collapsePanel(false)
- context.startActivity(intent)
- true
- }, null, true)
+ if (keyguardStateController.isUnlocked()) {
+ activityContext.startActivity(
+ intent,
+ ActivityOptions.makeSceneTransitionAnimation(activityContext as Activity).toBundle()
+ )
+ } else {
+ activityStarter.postStartActivityDismissingKeyguard(intent, 0 /* delay */)
+ }
}
private fun showControlsView(items: List<SelectionItem>) {
@@ -328,9 +325,9 @@ class ControlsUiControllerImpl @Inject constructor (
) {
when (pos) {
// 0: Add Control
- 0 -> startFavoritingActivity(view.context, selectedStructure)
+ 0 -> startFavoritingActivity(selectedStructure)
// 1: Edit controls
- 1 -> startEditingActivity(view.context, selectedStructure)
+ 1 -> startEditingActivity(selectedStructure)
}
dismiss()
}
@@ -399,15 +396,9 @@ class ControlsUiControllerImpl @Inject constructor (
val inflater = LayoutInflater.from(context)
inflater.inflate(R.layout.controls_with_favorites, parent, true)
- if (controlActionCoordinator.activityContext == null) {
- parent.requireViewById<View>(R.id.controls_spacer).apply {
- visibility = View.VISIBLE
- }
- } else {
- parent.requireViewById<ImageView>(R.id.controls_close).apply {
- setOnClickListener { _: View -> onDismiss.run() }
- visibility = View.VISIBLE
- }
+ parent.requireViewById<ImageView>(R.id.controls_close).apply {
+ setOnClickListener { _: View -> onDismiss.run() }
+ visibility = View.VISIBLE
}
val maxColumns = findMaxColumns()
@@ -522,8 +513,6 @@ class ControlsUiControllerImpl @Inject constructor (
override fun hide() {
hidden = true
- controlActionCoordinator.activityContext = null
-
closeDialogs(true)
controlsController.get().unsubscribe()
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 34d94d8e13bb..ab1de9528586 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -17,8 +17,6 @@ package com.android.systemui.globalactions;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
-import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
-import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
import android.animation.Animator;
@@ -30,10 +28,8 @@ import android.app.IActivityManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
-import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
@@ -47,7 +43,6 @@ import android.telecom.TelecomManager;
import android.transition.AutoTransition;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
-import android.util.Log;
import android.view.IWindowManager;
import android.view.View;
import android.view.ViewGroup;
@@ -69,18 +64,12 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.controls.ControlsServiceInfo;
-import com.android.systemui.controls.controller.ControlsController;
-import com.android.systemui.controls.dagger.ControlsComponent;
-import com.android.systemui.controls.management.ControlsAnimations;
-import com.android.systemui.controls.ui.ControlsUiController;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
-import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -91,12 +80,6 @@ import com.android.systemui.util.leak.RotationUtils;
import com.android.systemui.util.settings.GlobalSettings;
import com.android.systemui.util.settings.SecureSettings;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -105,7 +88,7 @@ import javax.inject.Provider;
/**
* Helper to show the global actions dialog. Each item is an {@link Action} that may show depending
* on whether the keyguard is showing, and whether the device is provisioned.
- * This version includes wallet and controls.
+ * This version includes wallet.
*/
public class GlobalActionsDialog extends GlobalActionsDialogLite
implements DialogInterface.OnDismissListener,
@@ -116,10 +99,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
private static final String TAG = "GlobalActionsDialog";
- public static final String PREFS_CONTROLS_SEEDING_COMPLETED = "SeedingCompleted";
- public static final String PREFS_CONTROLS_FILE = "controls_prefs";
- private static final int SEEDING_MAX = 2;
-
private final LockPatternUtils mLockPatternUtils;
private final KeyguardStateController mKeyguardStateController;
private final NotificationShadeDepthController mDepthController;
@@ -129,13 +108,9 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
private final IStatusBarService mStatusBarService;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private GlobalActionsPanelPlugin mWalletPlugin;
- private Optional<ControlsUiController> mControlsUiControllerOptional;
- private List<ControlsServiceInfo> mControlsServiceInfos = new ArrayList<>();
- private ControlsComponent mControlsComponent;
- private Optional<ControlsController> mControlsControllerOptional;
- private UserContextProvider mUserContextProvider;
+
@VisibleForTesting
- boolean mShowLockScreenCardsAndControls = false;
+ boolean mShowLockScreenCards = false;
/**
* @param context everything needs a context :(
@@ -158,9 +133,7 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
IWindowManager iWindowManager,
@Background Executor backgroundExecutor,
UiEventLogger uiEventLogger,
- RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler,
- ControlsComponent controlsComponent,
- UserContextProvider userContextProvider) {
+ RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler) {
super(context, windowManagerFuncs,
audioManager, iDreamManager,
@@ -186,11 +159,7 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
mSysuiColorExtractor = colorExtractor;
mStatusBarService = statusBarService;
mNotificationShadeWindowController = notificationShadeWindowController;
- mControlsComponent = controlsComponent;
- mControlsUiControllerOptional = controlsComponent.getControlsUiController();
- mControlsControllerOptional = controlsComponent.getControlsController();
mSysUiState = sysUiState;
- mUserContextProvider = userContextProvider;
mActivityStarter = activityStarter;
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
@@ -201,10 +170,7 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
if (dialog.mWalletViewController != null) {
dialog.mWalletViewController.onDeviceLockStateChanged(!unlocked);
}
- if (!dialog.isShowingControls()
- && mControlsComponent.getVisibility() == AVAILABLE) {
- dialog.showControls(mControlsUiControllerOptional.get());
- }
+
if (unlocked) {
dialog.hideLockMessage();
}
@@ -212,25 +178,7 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
}
});
- if (mControlsComponent.getControlsListingController().isPresent()) {
- mControlsComponent.getControlsListingController().get()
- .addCallback(list -> {
- mControlsServiceInfos = list;
- // This callback may occur after the dialog has been shown. If so, add
- // controls into the already visible space or show the lock msg if needed.
- if (mDialog != null) {
- ActionsDialog dialog = (ActionsDialog) mDialog;
- if (!dialog.isShowingControls()
- && mControlsComponent.getVisibility() == AVAILABLE) {
- dialog.showControls(mControlsUiControllerOptional.get());
- } else if (shouldShowLockMessage(dialog)) {
- dialog.showLockMessage();
- }
- }
- });
- }
-
- // Listen for changes to show controls on the power menu while locked
+ // Listen for changes to show pay on the power menu while locked
onPowerMenuLockScreenSettingsChanged();
mGlobalSettings.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT),
@@ -244,65 +192,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
}
/**
- * See if any available control service providers match one of the preferred components. If
- * they do, and there are no current favorites for that component, query the preferred
- * component for a limited number of suggested controls.
- */
- private void seedFavorites() {
- if (!mControlsControllerOptional.isPresent()
- || mControlsServiceInfos.isEmpty()) {
- return;
- }
-
- String[] preferredControlsPackages = getContext().getResources()
- .getStringArray(com.android.systemui.R.array.config_controlsPreferredPackages);
-
- SharedPreferences prefs = mUserContextProvider.getUserContext()
- .getSharedPreferences(PREFS_CONTROLS_FILE, Context.MODE_PRIVATE);
- Set<String> seededPackages = prefs.getStringSet(PREFS_CONTROLS_SEEDING_COMPLETED,
- Collections.emptySet());
-
- List<ComponentName> componentsToSeed = new ArrayList<>();
- for (int i = 0; i < Math.min(SEEDING_MAX, preferredControlsPackages.length); i++) {
- String pkg = preferredControlsPackages[i];
- for (ControlsServiceInfo info : mControlsServiceInfos) {
- if (!pkg.equals(info.componentName.getPackageName())) continue;
- if (seededPackages.contains(pkg)) {
- break;
- } else if (mControlsControllerOptional.get()
- .countFavoritesForComponent(info.componentName) > 0) {
- // When there are existing controls but no saved preference, assume it
- // is out of sync, perhaps through a device restore, and update the
- // preference
- addPackageToSeededSet(prefs, pkg);
- break;
- }
- componentsToSeed.add(info.componentName);
- break;
- }
- }
-
- if (componentsToSeed.isEmpty()) return;
-
- mControlsControllerOptional.get().seedFavoritesForComponents(
- componentsToSeed,
- (response) -> {
- Log.d(TAG, "Controls seeded: " + response);
- if (response.getAccepted()) {
- addPackageToSeededSet(prefs, response.getPackageName());
- }
- });
- }
-
- private void addPackageToSeededSet(SharedPreferences prefs, String pkg) {
- Set<String> seededPackages = prefs.getStringSet(PREFS_CONTROLS_SEEDING_COMPLETED,
- Collections.emptySet());
- Set<String> updatedPkgs = new HashSet<>(seededPackages);
- updatedPkgs.add(pkg);
- prefs.edit().putStringSet(PREFS_CONTROLS_SEEDING_COMPLETED, updatedPkgs).apply();
- }
-
- /**
* Show the global actions dialog (creating if necessary)
*
* @param keyguardShowing True if keyguard is showing
@@ -313,12 +202,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
super.showOrHideDialog(keyguardShowing, isDeviceProvisioned);
}
- @Override
- protected void handleShow() {
- seedFavorites();
- super.handleShow();
- }
-
/**
* Returns the maximum number of power menu items to show based on which GlobalActions
* layout is being used.
@@ -340,14 +223,9 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
initDialogItems();
mDepthController.setShowingHomeControls(true);
- ControlsUiController uiController = null;
- if (mControlsComponent.getVisibility() == AVAILABLE) {
- uiController = mControlsUiControllerOptional.get();
- }
ActionsDialog dialog = new ActionsDialog(getContext(), mAdapter, mOverflowAdapter,
this::getWalletViewController, mDepthController, mSysuiColorExtractor,
mStatusBarService, mNotificationShadeWindowController,
- controlsAvailable(), uiController,
mSysUiState, this::onRotate, isKeyguardShowing(), mPowerAdapter);
if (shouldShowLockMessage(dialog)) {
@@ -407,10 +285,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
private final Provider<GlobalActionsPanelPlugin.PanelViewController> mWalletFactory;
@Nullable private GlobalActionsPanelPlugin.PanelViewController mWalletViewController;
private ResetOrientationData mResetOrientationData;
- private final boolean mControlsAvailable;
-
- private ControlsUiController mControlsUiController;
- private ViewGroup mControlsView;
@VisibleForTesting ViewGroup mLockMessageContainer;
private TextView mLockMessage;
@@ -419,15 +293,12 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
NotificationShadeDepthController depthController,
SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController,
- boolean controlsAvailable, @Nullable ControlsUiController controlsUiController,
SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing,
MyPowerOptionsAdapter powerAdapter) {
super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions,
adapter, overflowAdapter, depthController, sysuiColorExtractor,
statusBarService, notificationShadeWindowController, sysuiState,
onRotateCallback, keyguardShowing, powerAdapter);
- mControlsAvailable = controlsAvailable;
- mControlsUiController = controlsUiController;
mWalletFactory = walletFactory;
// Update window attributes
@@ -448,16 +319,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
initializeLayout();
}
- private boolean isShowingControls() {
- return mControlsUiController != null;
- }
-
- private void showControls(ControlsUiController controller) {
- mControlsUiController = controller;
- mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- null /* activityContext */);
- }
-
private boolean isWalletViewAvailable() {
return mWalletViewController != null && mWalletViewController.getPanelContent() != null;
}
@@ -524,10 +385,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT);
- if (!mControlsAvailable) {
- panelParams.topMargin = mContext.getResources().getDimensionPixelSize(
- com.android.systemui.R.dimen.global_actions_wallet_top_margin);
- }
+ panelParams.topMargin = mContext.getResources().getDimensionPixelSize(
+ com.android.systemui.R.dimen.global_actions_wallet_top_margin);
View walletView = mWalletViewController.getPanelContent();
panelContainer.addView(walletView, panelParams);
// Smooth transitions when wallet is resized, which can happen when a card is added
@@ -554,7 +413,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
@Override
protected void initializeLayout() {
super.initializeLayout();
- mControlsView = findViewById(com.android.systemui.R.id.global_actions_controls);
mLockMessageContainer = requireViewById(
com.android.systemui.R.id.global_actions_lock_message_container);
mLockMessage = requireViewById(com.android.systemui.R.id.global_actions_lock_message);
@@ -577,10 +435,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
windowInsets.getStableInsetBottom());
return WindowInsets.CONSUMED;
});
- if (mControlsUiController != null) {
- mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- null /* activityContext */);
- }
mBackgroundDrawable.setAlpha(0);
float xOffset = mGlobalActionsLayout.getAnimationOffsetX();
@@ -609,20 +463,11 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
@Override
protected void dismissInternal() {
super.dismissInternal();
- if (mControlsUiController != null) mControlsUiController.closeDialogs(false);
- }
-
- private void dismissForControlsActivity() {
- dismissWithAnimation(() -> {
- ViewGroup root = (ViewGroup) mGlobalActionsLayout.getParent();
- ControlsAnimations.exitAnimation(root, this::completeDismiss).start();
- });
}
@Override
protected void completeDismiss() {
dismissWallet();
- if (mControlsUiController != null) mControlsUiController.hide();
resetOrientation();
super.completeDismiss();
}
@@ -647,15 +492,7 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
public void refreshDialog() {
// ensure dropdown menus are dismissed before re-initializing the dialog
dismissWallet();
- if (mControlsUiController != null) {
- mControlsUiController.hide();
- }
-
super.refreshDialog();
- if (mControlsUiController != null) {
- mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- null /* activityContext */);
- }
}
void hideLockMessage() {
@@ -699,15 +536,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
return isPanelDebugModeEnabled(context);
}
- private boolean controlsAvailable() {
- return isDeviceProvisioned()
- && mControlsComponent.isEnabled()
- && !mControlsServiceInfos.isEmpty();
- }
-
private boolean shouldShowLockMessage(ActionsDialog dialog) {
- return mControlsComponent.getVisibility() == AVAILABLE_AFTER_UNLOCK
- || isWalletAvailableAfterUnlock(dialog);
+ return isWalletAvailableAfterUnlock(dialog);
}
// Temporary while we move items out of the power menu
@@ -715,12 +545,12 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
boolean isLockedAfterBoot = mLockPatternUtils.getStrongAuthForUser(getCurrentUser().id)
== STRONG_AUTH_REQUIRED_AFTER_BOOT;
return !mKeyguardStateController.isUnlocked()
- && (!mShowLockScreenCardsAndControls || isLockedAfterBoot)
+ && (!mShowLockScreenCards || isLockedAfterBoot)
&& dialog.isWalletViewAvailable();
}
private void onPowerMenuLockScreenSettingsChanged() {
- mShowLockScreenCardsAndControls = mSecureSettings.getInt(
+ mShowLockScreenCards = mSecureSettings.getInt(
Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT, 0) != 0;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 94b99c3d9f2a..cb58eff650c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -132,7 +132,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
inflater = mInjectionInflater.injectable(
- inflater.cloneInContext(new ContextThemeWrapper(getContext(), R.style.qs_theme)));
+ inflater.cloneInContext(new ContextThemeWrapper(getContext(),
+ R.style.Theme_SystemUI_QuickSettings)));
return inflater.inflate(R.layout.qs_panel, container, false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index faac196b75bc..525bad8a0e25 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -23,7 +23,6 @@ import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
-import android.provider.Settings;
import android.provider.Settings.Secure;
import android.service.quicksettings.Tile;
import android.text.TextUtils;
@@ -57,6 +56,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.leak.GarbageMonitor;
+import com.android.systemui.util.settings.SecureSettings;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -79,6 +79,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final int MAX_QS_INSTANCE_ID = 1 << 20;
+ public static final int POSITION_AT_END = -1;
public static final String TILES_SETTING = Secure.QS_TILES;
private final Context mContext;
@@ -101,6 +102,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
private final Optional<StatusBar> mStatusBarOptional;
private Context mUserContext;
private UserTracker mUserTracker;
+ private SecureSettings mSecureSettings;
@Inject
public QSTileHost(Context context,
@@ -116,7 +118,8 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
Optional<StatusBar> statusBarOptional,
QSLogger qsLogger,
UiEventLogger uiEventLogger,
- UserTracker userTracker) {
+ UserTracker userTracker,
+ SecureSettings secureSettings) {
mIconController = iconController;
mContext = context;
mUserContext = context;
@@ -135,6 +138,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
pluginManager.addPluginListener(this, QSFactory.class, true);
mDumpManager.registerDumpable(TAG, this);
mUserTracker = userTracker;
+ mSecureSettings = secureSettings;
mainHandler.post(() -> {
// This is technically a hack to avoid circular dependency of
@@ -343,19 +347,43 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
if (mAutoTiles != null) mAutoTiles.unmarkTileAsAutoAdded(spec);
}
+ /**
+ * Add a tile to the end
+ *
+ * @param spec string matching a pre-defined tilespec
+ */
public void addTile(String spec) {
- changeTileSpecs(tileSpecs-> !tileSpecs.contains(spec) && tileSpecs.add(spec));
+ addTile(spec, POSITION_AT_END);
+ }
+
+ /**
+ * Add a tile into the requested spot, or at the end if the position is greater than the number
+ * of tiles.
+ * @param spec string matching a pre-defined tilespec
+ * @param requestPosition -1 for end, 0 for beginning, or X for insertion at position X
+ */
+ public void addTile(String spec, int requestPosition) {
+ 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;
+ });
}
- private void saveTilesToSettings(List<String> tileSpecs) {
- Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING,
- TextUtils.join(",", tileSpecs), null /* tag */,
- false /* default */, mCurrentUser, true /* overrideable by restore */);
+ void saveTilesToSettings(List<String> tileSpecs) {
+ mSecureSettings.putStringForUser(TILES_SETTING, TextUtils.join(",", tileSpecs),
+ null /* tag */, false /* default */, mCurrentUser,
+ true /* overrideable by restore */);
}
private void changeTileSpecs(Predicate<List<String>> changeFunction) {
- final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
- TILES_SETTING, mCurrentUser);
+ final String setting = mSecureSettings.getStringForUser(TILES_SETTING, mCurrentUser);
final List<String> tileSpecs = loadTileSpecs(mContext, setting);
if (changeFunction.test(tileSpecs)) {
saveTilesToSettings(tileSpecs);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index dce081f21581..6f789d3c8541 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -63,7 +63,7 @@ public class QSCustomizer extends LinearLayout {
private boolean mIsShowingNavBackdrop;
public QSCustomizer(Context context, AttributeSet attrs) {
- super(new ContextThemeWrapper(context, R.style.edit_theme), attrs);
+ super(new ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings_Edit), attrs);
LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this);
mClipper = new QSDetailClipper(findViewById(R.id.customize_container));
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 e9abef42a282..08aa599d34b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -728,7 +728,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
GridLayoutManager lm = ((GridLayoutManager) parent.getLayoutManager());
SpanSizeLookup span = lm.getSpanSizeLookup();
ViewHolder holder = parent.getChildViewHolder(view);
- int column = span.getSpanIndex(holder.getLayoutPosition(), lm.getSpanCount());
+ int column = span.getSpanIndex(holder.getBindingAdapterPosition(), lm.getSpanCount());
if (view instanceof TextView) {
super.getItemOffsets(outRect, view, parent, state);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index d41bd7ad4d3c..75a7e8e09afa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -32,6 +32,7 @@ import com.android.systemui.statusbar.phone.AutoTileManager;
import com.android.systemui.statusbar.phone.ManagedProfileController;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.DataSaverController;
+import com.android.systemui.statusbar.policy.DeviceControlsController;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.util.settings.SecureSettings;
@@ -61,6 +62,7 @@ public interface QSModule {
NightDisplayListener nightDisplayListener,
CastController castController,
ReduceBrightColorsController reduceBrightColorsController,
+ DeviceControlsController deviceControlsController,
@Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
AutoTileManager manager = new AutoTileManager(
context,
@@ -74,6 +76,7 @@ public interface QSModule {
nightDisplayListener,
castController,
reduceBrightColorsController,
+ deviceControlsController,
isReduceBrightColorsAvailable
);
manager.init();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
index c7ed89ba49b1..3d5a709a5fdd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
@@ -43,7 +43,7 @@ public class QSTileView extends QSTileBaseView {
protected TextView mLabel;
protected TextView mSecondLine;
private ImageView mPadLock;
- private int mState;
+ protected int mState;
protected ViewGroup mLabelContainer;
private View mExpandIndicator;
private View mExpandSpace;
@@ -133,14 +133,7 @@ public class QSTileView extends QSTileBaseView {
protected void handleStateChanged(QSTile.State state) {
super.handleStateChanged(state);
if (!Objects.equals(mLabel.getText(), state.label) || mState != state.state) {
- ColorStateList labelColor;
- if (state.state == Tile.STATE_ACTIVE) {
- labelColor = mColorLabelActive;
- } else if (state.state == Tile.STATE_INACTIVE) {
- labelColor = mColorLabelInactive;
- } else {
- labelColor = mColorLabelUnavailable;
- }
+ ColorStateList labelColor = getLabelColor(state.state);
changeLabelColor(labelColor);
mState = state.state;
mLabel.setText(state.label);
@@ -163,6 +156,15 @@ public class QSTileView extends QSTileBaseView {
mPadLock.setVisibility(state.disabledByPolicy ? View.VISIBLE : View.GONE);
}
+ protected final ColorStateList getLabelColor(int state) {
+ if (state == Tile.STATE_ACTIVE) {
+ return mColorLabelActive;
+ } else if (state == Tile.STATE_INACTIVE) {
+ return mColorLabelInactive;
+ }
+ return mColorLabelUnavailable;
+ }
+
protected void changeLabelColor(ColorStateList color) {
mLabel.setTextColor(color);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt
index 188e89edd89a..7a8b2c696fa0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt
@@ -24,6 +24,8 @@ import android.graphics.drawable.Drawable
import android.graphics.drawable.RippleDrawable
import android.service.quicksettings.Tile.STATE_ACTIVE
import android.view.Gravity
+import android.view.View
+import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import com.android.systemui.R
@@ -41,6 +43,7 @@ open class QSTileViewHorizontal(
private var paintColor = Color.WHITE
private var paintAnimator: ValueAnimator? = null
private var labelAnimator: ValueAnimator? = null
+ private var mSideView: ImageView = ImageView(mContext)
override var heightOverride: Int = HeightOverrideable.NO_OVERRIDE
init {
@@ -56,7 +59,16 @@ open class QSTileViewHorizontal(
val iconSize = context.resources.getDimensionPixelSize(R.dimen.qs_icon_size)
addView(mIcon, 0, LayoutParams(iconSize, iconSize))
+ mSideView.visibility = View.GONE
+ addView(
+ mSideView,
+ -1,
+ LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).apply {
+ gravity = Gravity.CENTER_VERTICAL
+ })
+
mColorLabelActive = ColorStateList.valueOf(getColorForState(getContext(), STATE_ACTIVE))
+ changeLabelColor(getLabelColor(mState)) // Matches the default state of the tile
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
@@ -121,14 +133,13 @@ open class QSTileViewHorizontal(
if (allowAnimations) {
animateBackground(newColor)
} else {
- if (newColor != paintColor) {
- clearBackgroundAnimator()
- colorBackgroundDrawable?.setTintList(ColorStateList.valueOf(newColor))?.also {
- paintColor = newColor
- }
+ clearBackgroundAnimator()
+ colorBackgroundDrawable?.setTintList(ColorStateList.valueOf(newColor))?.also {
paintColor = newColor
}
+ paintColor = newColor
}
+ loadSideViewDrawableIfNecessary(state)
}
private fun animateBackground(newBackgroundColor: Int) {
@@ -181,5 +192,21 @@ open class QSTileViewHorizontal(
labelAnimator?.cancel()?.also { labelAnimator = null }
}
+ private fun loadSideViewDrawableIfNecessary(state: QSTile.State) {
+ if (state.sideViewDrawable != null) {
+ (mSideView.layoutParams as MarginLayoutParams).apply {
+ marginStart =
+ context.resources.getDimensionPixelSize(R.dimen.qs_label_container_margin)
+ }
+ mSideView.setImageDrawable(state.sideViewDrawable)
+ mSideView.visibility = View.VISIBLE
+ mSideView.adjustViewBounds = true
+ mSideView.scaleType = ImageView.ScaleType.FIT_CENTER
+ } else {
+ mSideView.setImageDrawable(null)
+ mSideView.visibility = GONE
+ }
+ }
+
override fun handleExpand(dualTarget: Boolean) {}
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index a74a50e7d6c2..a2c7633c4746 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -39,8 +39,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
-import com.android.systemui.statusbar.FeatureFlags
-import com.android.systemui.util.settings.GlobalSettings
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
@@ -53,9 +51,7 @@ class DeviceControlsTile @Inject constructor(
statusBarStateController: StatusBarStateController,
activityStarter: ActivityStarter,
qsLogger: QSLogger,
- private val controlsComponent: ControlsComponent,
- private val featureFlags: FeatureFlags,
- globalSettings: GlobalSettings
+ private val controlsComponent: ControlsComponent
) : QSTileImpl<QSTile.State>(
host,
backgroundLooper,
@@ -67,11 +63,6 @@ class DeviceControlsTile @Inject constructor(
qsLogger
) {
- companion object {
- const val SETTINGS_FLAG = "controls_lockscreen"
- }
-
- private val controlsLockscreen = globalSettings.getInt(SETTINGS_FLAG, 0) != 0
private var hasControlsApps = AtomicBoolean(false)
private val intent = Intent(Settings.ACTION_DEVICE_CONTROLS_SETTINGS)
@@ -92,9 +83,7 @@ class DeviceControlsTile @Inject constructor(
}
override fun isAvailable(): Boolean {
- return featureFlags.isKeyguardLayoutEnabled &&
- controlsLockscreen &&
- controlsComponent.getControlsController().isPresent
+ return controlsComponent.getControlsController().isPresent
}
override fun newTileState(): QSTile.State {
@@ -114,7 +103,7 @@ class DeviceControlsTile @Inject constructor(
val i = Intent().apply {
component = ComponentName(mContext, ControlsActivity::class.java)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
- putExtra(ControlsUiController.BACK_TO_GLOBAL_ACTIONS, false)
+ putExtra(ControlsUiController.EXTRA_ANIMATE, true)
}
mContext.startActivity(i)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 60c5d1cafde9..bf9655837b25 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -20,11 +20,20 @@ import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
+import android.service.quickaccesswallet.GetWalletCardsError;
+import android.service.quickaccesswallet.GetWalletCardsRequest;
+import android.service.quickaccesswallet.GetWalletCardsResponse;
import android.service.quickaccesswallet.QuickAccessWalletClient;
+import android.service.quickaccesswallet.WalletCard;
import android.service.quicksettings.Tile;
+import android.util.Log;
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
@@ -40,20 +49,30 @@ import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.settings.SecureSettings;
+import java.util.List;
+import java.util.concurrent.Executor;
+
import javax.inject.Inject;
/** Quick settings tile: Quick access wallet **/
public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
+ private static final String TAG = "QuickAccessWalletTile";
private static final String FEATURE_CHROME_OS = "org.chromium.arc";
+
private final CharSequence mLabel = mContext.getString(R.string.wallet_title);
+ private final WalletCardRetriever mCardRetriever = new WalletCardRetriever();
// TODO(b/180959290): Re-create the QAW Client when the default NFC payment app changes.
private final QuickAccessWalletClient mQuickAccessWalletClient;
private final KeyguardStateController mKeyguardStateController;
private final PackageManager mPackageManager;
private final SecureSettings mSecureSettings;
+ private final Executor mExecutor;
private final FeatureFlags mFeatureFlags;
+ @VisibleForTesting Drawable mCardViewDrawable;
+ private boolean mHasCard;
+
@Inject
public QuickAccessWalletTile(
QSHost host,
@@ -68,6 +87,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
KeyguardStateController keyguardStateController,
PackageManager packageManager,
SecureSettings secureSettings,
+ @Background Executor executor,
FeatureFlags featureFlags) {
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
statusBarStateController, activityStarter, qsLogger);
@@ -75,6 +95,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
mKeyguardStateController = keyguardStateController;
mPackageManager = packageManager;
mSecureSettings = secureSettings;
+ mExecutor = executor;
mFeatureFlags = featureFlags;
}
@@ -87,6 +108,14 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
}
@Override
+ protected void handleSetListening(boolean listening) {
+ super.handleSetListening(listening);
+ if (listening) {
+ queryWalletCards();
+ }
+ }
+
+ @Override
protected void handleClick() {
mActivityStarter.postStartActivityDismissingKeyguard(
mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0);
@@ -100,14 +129,27 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
state.icon = ResourceIcon.get(R.drawable.ic_qs_wallet);
boolean isDeviceLocked = !mKeyguardStateController.isUnlocked();
if (mQuickAccessWalletClient.isWalletFeatureAvailable()) {
- state.state = isDeviceLocked ? Tile.STATE_INACTIVE : Tile.STATE_ACTIVE;
- state.secondaryLabel = isDeviceLocked
- ? null
- : mContext.getString(R.string.wallet_secondary_label);
+ if (mHasCard) {
+ if (isDeviceLocked) {
+ state.state = Tile.STATE_INACTIVE;
+ state.secondaryLabel =
+ mContext.getString(R.string.wallet_secondary_label_device_locked);
+ } else {
+ state.state = Tile.STATE_ACTIVE;
+ state.secondaryLabel =
+ mContext.getString(R.string.wallet_secondary_label_active);
+ }
+ } else {
+ state.state = Tile.STATE_INACTIVE;
+ state.secondaryLabel = mContext.getString(R.string.wallet_secondary_label_no_card);
+ }
state.stateDescription = state.secondaryLabel;
} else {
state.state = Tile.STATE_UNAVAILABLE;
}
+ if (!isDeviceLocked) {
+ state.sideViewDrawable = mCardViewDrawable;
+ }
}
@Override
@@ -133,4 +175,43 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
CharSequence qawLabel = mQuickAccessWalletClient.getServiceLabel();
return qawLabel == null ? mLabel : qawLabel;
}
+
+ private void queryWalletCards() {
+ int cardWidth =
+ mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width);
+ int cardHeight =
+ mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_height);
+ int iconSizePx = mContext.getResources().getDimensionPixelSize(R.dimen.wallet_icon_size);
+ GetWalletCardsRequest request =
+ new GetWalletCardsRequest(cardWidth, cardHeight, iconSizePx, /* maxCards= */ 2);
+ mQuickAccessWalletClient.getWalletCards(mExecutor, request, mCardRetriever);
+ }
+
+ private class WalletCardRetriever implements
+ QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
+
+ @Override
+ public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) {
+ Log.i(TAG, "Successfully retrieved wallet cards.");
+ List<WalletCard> cards = response.getWalletCards();
+ if (cards.isEmpty()) {
+ Log.d(TAG, "No wallet cards exist.");
+ mCardViewDrawable = null;
+ mHasCard = false;
+ refreshState();
+ return;
+ }
+ mCardViewDrawable = cards.get(0).getCardImage().loadDrawable(mContext);
+ mHasCard = true;
+ refreshState();
+ }
+
+ @Override
+ public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) {
+ Log.w(TAG, "Error retrieve wallet cards");
+ mCardViewDrawable = null;
+ mHasCard = false;
+ refreshState();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 04d199645b24..9ce0eebfd441 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -411,19 +411,22 @@ public class LongScreenshotActivity extends Activity {
float imageRatio = bounds.width() / (float) bounds.height();
int previewWidth = mPreview.getWidth() - mPreview.getPaddingLeft()
- mPreview.getPaddingRight();
- float viewRatio = previewWidth / (float) mPreview.getHeight();
+ int previewHeight = mPreview.getHeight() - mPreview.getPaddingTop()
+ - mPreview.getPaddingBottom();
+ float viewRatio = previewWidth / (float) previewHeight;
if (imageRatio > viewRatio) {
// Image is full width and height is constrained, compute extra padding to inform
// CropView
- float imageHeight = mPreview.getHeight() * viewRatio / imageRatio;
- int extraPadding = (int) (mPreview.getHeight() - imageHeight) / 2;
- mCropView.setExtraPadding(extraPadding, extraPadding);
+ float imageHeight = previewHeight * viewRatio / imageRatio;
+ int extraPadding = (int) (previewHeight - imageHeight) / 2;
+ mCropView.setExtraPadding(extraPadding + mPreview.getPaddingTop(),
+ extraPadding + mPreview.getPaddingBottom());
mCropView.setImageWidth(previewWidth);
} else {
// Image is full height
- mCropView.setExtraPadding(0, 0);
- mCropView.setImageWidth((int) (mPreview.getHeight() * imageRatio));
+ mCropView.setExtraPadding(mPreview.getPaddingTop(), mPreview.getPaddingBottom());
+ mCropView.setImageWidth((int) (previewHeight * imageRatio));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
index 3dc8ae8ada9f..bbcfdbd99bef 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
@@ -203,7 +203,7 @@ public class ScrollCaptureController {
&& result.captured.height() < result.requested.height();
boolean finish = false;
- if (partialResult || emptyResult) {
+ if (emptyResult) {
// Potentially reached a vertical boundary. Extend in the other direction.
if (mFinishOnBoundary) {
Log.d(TAG, "Partial/empty: finished!");
@@ -217,12 +217,12 @@ public class ScrollCaptureController {
Log.d(TAG, "Partial/empty: cleared, switch direction to finish");
}
} else {
- // Got the full requested result, but may have got enough bitmap data now
+ // Got a non-empty result, but may already have enough bitmap data now
int expectedTiles = mImageTileSet.size() + 1;
if (expectedTiles >= mSession.getMaxTiles()) {
Log.d(TAG, "Hit max tiles: finished");
- // If we ever hit the max tiles, we've got enough bitmap data to finish (even if we
- // weren't sure we'd finish on this pass).
+ // If we ever hit the max tiles, we've got enough bitmap data to finish
+ // (even if we weren't sure we'd finish on this pass).
finish = true;
} else {
if (mScrollingUp && !mFinishOnBoundary) {
@@ -259,10 +259,18 @@ public class ScrollCaptureController {
return;
}
- // Partial or empty results caused the direction the flip, so we can reliably use the
- // requested edges to determine the next top.
- int nextTop = (mScrollingUp) ? result.requested.top - mSession.getTileHeight()
- : result.requested.bottom;
+ int nextTop;
+ if (emptyResult) {
+ // An empty result caused the direction the flip,
+ // so use the requested edges to determine the next top.
+ nextTop = (mScrollingUp)
+ ? result.requested.top - mSession.getTileHeight()
+ : result.requested.bottom;
+ } else {
+ nextTop = (mScrollingUp)
+ ? result.captured.top - mSession.getTileHeight()
+ : result.captured.bottom;
+ }
requestNextTile(nextTop);
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
index bdb392608455..357256cba131 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
@@ -58,10 +58,9 @@ public class BrightnessController implements ToggleSlider.Listener {
private static final int SLIDER_ANIMATION_DURATION = 3000;
private static final int MSG_UPDATE_SLIDER = 1;
- private static final int MSG_SET_CHECKED = 2;
- private static final int MSG_ATTACH_LISTENER = 3;
- private static final int MSG_DETACH_LISTENER = 4;
- private static final int MSG_VR_MODE_CHANGED = 5;
+ private static final int MSG_ATTACH_LISTENER = 2;
+ private static final int MSG_DETACH_LISTENER = 3;
+ private static final int MSG_VR_MODE_CHANGED = 4;
private static final Uri BRIGHTNESS_MODE_URI =
Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE);
@@ -80,7 +79,6 @@ public class BrightnessController implements ToggleSlider.Listener {
private final int mDisplayId;
private final Context mContext;
private final ToggleSlider mControl;
- private final boolean mAutomaticAvailable;
private final DisplayManager mDisplayManager;
private final CurrentUserTracker mUserTracker;
private final IVrManager mVrManager;
@@ -219,16 +217,12 @@ public class BrightnessController implements ToggleSlider.Listener {
private final Runnable mUpdateModeRunnable = new Runnable() {
@Override
public void run() {
- if (mAutomaticAvailable) {
- int automatic;
- automatic = Settings.System.getIntForUser(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
- UserHandle.USER_CURRENT);
- mAutomatic = automatic != Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
- } else {
- mHandler.obtainMessage(MSG_SET_CHECKED, 0).sendToTarget();
- }
+ int automatic;
+ automatic = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
+ UserHandle.USER_CURRENT);
+ mAutomatic = automatic != Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
}
};
@@ -266,9 +260,6 @@ public class BrightnessController implements ToggleSlider.Listener {
case MSG_UPDATE_SLIDER:
updateSlider(Float.intBitsToFloat(msg.arg1), msg.arg2 != 0);
break;
- case MSG_SET_CHECKED:
- mControl.setChecked(msg.arg1 != 0);
- break;
case MSG_ATTACH_LISTENER:
mControl.setOnChangedListener(BrightnessController.this);
break;
@@ -312,9 +303,6 @@ public class BrightnessController implements ToggleSlider.Listener {
mDefaultBacklightForVr = pm.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT_VR);
-
- mAutomaticAvailable = context.getResources().getBoolean(
- com.android.internal.R.bool.config_automatic_brightness_available);
mDisplayManager = context.getSystemService(DisplayManager.class);
mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
Context.VR_SERVICE));
@@ -339,8 +327,7 @@ public class BrightnessController implements ToggleSlider.Listener {
}
@Override
- public void onChanged(boolean tracking, boolean automatic,
- int value, boolean stopTracking) {
+ public void onChanged(boolean tracking, int value, boolean stopTracking) {
if (mExternalChange) return;
if (mSliderAnimator != null) {
@@ -398,12 +385,6 @@ public class BrightnessController implements ToggleSlider.Listener {
});
}
- private void setMode(int mode) {
- Settings.System.putIntForUser(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE, mode,
- mUserTracker.getCurrentUserId());
- }
-
private void setBrightness(float brightness) {
mDisplayManager.setTemporaryBrightness(mDisplayId, brightness);
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
index ab4895e4112c..db8205783173 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
@@ -21,7 +21,6 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.CompoundButton;
import android.widget.SeekBar;
import androidx.annotation.Nullable;
@@ -31,7 +30,6 @@ import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.util.ViewController;
@@ -95,14 +93,12 @@ public class BrightnessSlider extends ViewController<View> implements ToggleSlid
@Override
protected void onViewAttached() {
mBrightnessSliderView.setOnSeekBarChangeListener(mSeekListener);
- mBrightnessSliderView.setOnCheckedChangeListener(mCheckListener);
mBrightnessSliderView.setOnInterceptListener(mOnInterceptListener);
}
@Override
protected void onViewDetached() {
mBrightnessSliderView.setOnSeekBarChangeListener(null);
- mBrightnessSliderView.setOnCheckedChangeListener(null);
mBrightnessSliderView.setOnDispatchTouchEventListener(null);
mBrightnessSliderView.setOnInterceptListener(null);
}
@@ -132,7 +128,6 @@ public class BrightnessSlider extends ViewController<View> implements ToggleSlid
private void setMirror(ToggleSlider toggleSlider) {
mMirror = toggleSlider;
if (mMirror != null) {
- mMirror.setChecked(mBrightnessSliderView.isChecked());
mMirror.setMax(mBrightnessSliderView.getMax());
mMirror.setValue(mBrightnessSliderView.getValue());
mBrightnessSliderView.setOnDispatchTouchEventListener(this::mirrorTouchEvent);
@@ -166,16 +161,6 @@ public class BrightnessSlider extends ViewController<View> implements ToggleSlid
}
@Override
- public void setChecked(boolean checked) {
- mBrightnessSliderView.setChecked(checked);
- }
-
- @Override
- public boolean isChecked() {
- return mBrightnessSliderView.isChecked();
- }
-
- @Override
public void setMax(int max) {
mBrightnessSliderView.setMax(max);
if (mMirror != null) {
@@ -206,7 +191,7 @@ public class BrightnessSlider extends ViewController<View> implements ToggleSlid
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (mListener != null) {
- mListener.onChanged(mTracking, isChecked(), progress, false);
+ mListener.onChanged(mTracking, progress, false);
}
}
@@ -215,12 +200,9 @@ public class BrightnessSlider extends ViewController<View> implements ToggleSlid
mTracking = true;
if (mListener != null) {
- mListener.onChanged(mTracking, isChecked(),
- getValue(), false);
+ mListener.onChanged(mTracking, getValue(), false);
}
- setChecked(false);
-
if (mMirrorController != null) {
mMirrorController.showMirror();
mMirrorController.setLocation((View) mBrightnessSliderView.getParent());
@@ -232,8 +214,7 @@ public class BrightnessSlider extends ViewController<View> implements ToggleSlid
mTracking = false;
if (mListener != null) {
- mListener.onChanged(mTracking, isChecked(),
- getValue(), true);
+ mListener.onChanged(mTracking, getValue(), true);
}
if (mMirrorController != null) {
@@ -242,35 +223,15 @@ public class BrightnessSlider extends ViewController<View> implements ToggleSlid
}
};
- private final CompoundButton.OnCheckedChangeListener mCheckListener =
- new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton toggle, boolean checked) {
- enableSlider(!checked);
-
- if (mListener != null) {
- mListener.onChanged(mTracking, checked, getValue(), false);
- }
-
- if (mMirror != null) {
- mMirror.setChecked(checked);
- }
- }
- };
-
/**
* Creates a {@link BrightnessSlider} with its associated view.
- *
- * The views inflated are determined by {@link FeatureFlags#useNewBrightnessSlider()}.
*/
public static class Factory {
- final FeatureFlags mFeatureFlags;
private final FalsingManager mFalsingManager;
@Inject
- public Factory(FeatureFlags featureFlags, FalsingManager falsingManager) {
- mFeatureFlags = featureFlags;
+ public Factory(FalsingManager falsingManager) {
mFalsingManager = falsingManager;
}
@@ -296,9 +257,7 @@ public class BrightnessSlider extends ViewController<View> implements ToggleSlid
/** Get the layout to inflate based on what slider to use */
private int getLayout() {
- return mFeatureFlags.useNewBrightnessSlider()
- ? R.layout.quick_settings_brightness_dialog_thick
- : R.layout.quick_settings_brightness_dialog;
+ return R.layout.quick_settings_brightness_dialog;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
index 5b71c626bb22..dbd6758b090d 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
@@ -17,18 +17,13 @@
package com.android.systemui.settings.brightness;
import android.content.Context;
-import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.FrameLayout;
import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import com.android.settingslib.RestrictedLockUtils;
import com.android.systemui.Gefingerpoken;
@@ -37,23 +32,11 @@ import com.android.systemui.R;
/**
* {@code FrameLayout} used to show and manipulate a {@link ToggleSeekBar}.
*
- * It can additionally control a {@link CompoundButton} and display a label. For the class to work,
- * add children before inflation with the following ids:
- * <ul>
- * <li>{@code @id/slider} of type {@link ToggleSeekBar}</li>
- * <li>{@code @id/toggle} of type {@link CompoundButton} (optional)</li>
- * <li>{@code @id/label} of type {@link TextView} (optional)</li>
- * </ul>
*/
public class BrightnessSliderView extends FrameLayout {
- @Nullable
- private CompoundButton mToggle;
@NonNull
private ToggleSeekBar mSlider;
- @Nullable
- private TextView mLabel;
- private final CharSequence mText;
private DispatchTouchEventListener mListener;
private Gefingerpoken mOnInterceptListener;
@@ -62,31 +45,15 @@ public class BrightnessSliderView extends FrameLayout {
}
public BrightnessSliderView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public BrightnessSliderView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- final TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.ToggleSliderView, defStyle, 0);
- mText = a.getString(R.styleable.ToggleSliderView_text);
-
- a.recycle();
+ super(context, attrs);
}
// Inflated from quick_settings_brightness_dialog or quick_settings_brightness_dialog_thick
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mToggle = findViewById(R.id.toggle);
mSlider = requireViewById(R.id.slider);
-
- mLabel = findViewById(R.id.label);
- if (mLabel != null) {
- mLabel.setText(mText);
- }
mSlider.setAccessibilityLabel(getContentDescription().toString());
}
@@ -125,25 +92,11 @@ public class BrightnessSliderView extends FrameLayout {
}
/**
- * Attaches a listener to the {@link CompoundButton} in the view (if present) so changes to its
- * state can be observed
- * @param checkListener use {@code null} to remove listener
- */
- public void setOnCheckedChangeListener(OnCheckedChangeListener checkListener) {
- if (mToggle != null) {
- mToggle.setOnCheckedChangeListener(checkListener);
- }
- }
-
- /**
* Enforces admin rules for toggling auto-brightness and changing value of brightness
* @param admin
* @see ToggleSeekBar#setEnforcedAdmin
*/
public void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
- if (mToggle != null) {
- mToggle.setEnabled(admin == null);
- }
mSlider.setEnabled(admin == null);
mSlider.setEnforcedAdmin(admin);
}
@@ -157,26 +110,6 @@ public class BrightnessSliderView extends FrameLayout {
}
/**
- * Sets the state of the {@link CompoundButton} if present
- * @param checked
- */
- public void setChecked(boolean checked) {
- if (mToggle != null) {
- mToggle.setChecked(checked);
- }
- }
-
- /**
- * @return the state of the {@link CompoundButton} if present, or {@code true} if not.
- */
- public boolean isChecked() {
- if (mToggle != null) {
- return mToggle.isChecked();
- }
- return true;
- }
-
- /**
* @return the maximum value of the {@link ToggleSeekBar}.
*/
public int getMax() {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
index 71e4818c605a..a988c7aeb436 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
@@ -23,8 +23,7 @@ import com.android.systemui.statusbar.policy.BrightnessMirrorController;
public interface ToggleSlider {
interface Listener {
- void onChanged(boolean tracking, boolean automatic, int value,
- boolean stopTracking);
+ void onChanged(boolean tracking, int value, boolean stopTracking);
}
void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin);
@@ -32,8 +31,6 @@ public interface ToggleSlider {
boolean mirrorTouchEvent(MotionEvent ev);
void setOnChangedListener(Listener l);
- default void setChecked(boolean checked) {}
- default boolean isChecked() { return false; }
void setMax(int max);
int getMax();
void setValue(int value);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index b937dad269e9..ec3a857dbc84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -62,11 +62,6 @@ public class FeatureFlags {
return mFlagReader.isEnabled(R.bool.flag_keyguard_layout);
}
- /** b/178485354 */
- public boolean useNewBrightnessSlider() {
- return mFlagReader.isEnabled(R.bool.flag_brightness_slider);
- }
-
public boolean useNewLockscreenAnimations() {
return mFlagReader.isEnabled(R.bool.flag_lockscreen_animations);
}
@@ -102,4 +97,8 @@ public class FeatureFlags {
public boolean isOngoingCallStatusBarChipEnabled() {
return mFlagReader.isEnabled(R.bool.flag_ongoing_call_status_bar_chip);
}
+
+ public boolean isSmartspaceEnabled() {
+ return mFlagReader.isEnabled(R.bool.flag_smartspace);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 91a4f94eea43..50cbbd5d4852 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -393,11 +393,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
override fun onDozingChanged(isDozing: Boolean) {
if (isDozing) {
setNotificationsVisible(visible = false, animate = false, increaseSpeed = false)
- } else {
- // We only unset the flag once we fully went asleep. If the user interrupts the
- // animation in the middle, we have to abort the animation as well to make sure
- // the notifications are visible again.
- animatingScreenOff = false
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index c3ccba4c3771..a0b0b3dc57bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -873,14 +873,19 @@ public class NotificationContentView extends FrameLayout {
}
public void setBackgroundTintColor(int color) {
+ boolean colorized = mNotificationEntry.getSbn().getNotification().isColorized();
if (mExpandedSmartReplyView != null) {
- boolean colorized = mNotificationEntry.getSbn().getNotification().isColorized();
mExpandedSmartReplyView.setBackgroundTintColor(color, colorized);
}
if (mHeadsUpSmartReplyView != null) {
- boolean colorized = mNotificationEntry.getSbn().getNotification().isColorized();
mHeadsUpSmartReplyView.setBackgroundTintColor(color, colorized);
}
+ if (mExpandedRemoteInput != null) {
+ mExpandedRemoteInput.setBackgroundTintColor(color, colorized);
+ }
+ if (mHeadsUpRemoteInput != null) {
+ mHeadsUpRemoteInput.setBackgroundTintColor(color, colorized);
+ }
}
public int getVisibleType() {
@@ -1243,8 +1248,7 @@ public class NotificationContentView extends FrameLayout {
View actionContainerCandidate = view.findViewById(
com.android.internal.R.id.actions_container);
if (actionContainerCandidate instanceof FrameLayout) {
- RemoteInputView existing = (RemoteInputView)
- view.findViewWithTag(RemoteInputView.VIEW_TAG);
+ RemoteInputView existing = view.findViewWithTag(RemoteInputView.VIEW_TAG);
if (existing != null) {
existing.onNotificationUpdateOrReset();
@@ -1292,13 +1296,9 @@ public class NotificationContentView extends FrameLayout {
}
}
if (existing != null) {
- if (entry.getSbn().getNotification().isColorized()) {
- existing.setBackgroundTintColor(
- entry.getSbn().getNotification().color, true);
- } else {
- existing.setBackgroundTintColor(
- entry.getRow().getCurrentBackgroundTint(), false);
- }
+ int backgroundColor = entry.getRow().getCurrentBackgroundTint();
+ boolean colorized = mNotificationEntry.getSbn().getNotification().isColorized();
+ existing.setBackgroundTintColor(backgroundColor, colorized);
}
return existing;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index b4ab8cf817dd..8ba036ce03c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -346,9 +346,22 @@ public class NotificationConversationInfo extends LinearLayout implements
}
private void bindIcon(boolean important) {
+ Drawable person = mIconFactory.getBaseIconDrawable(mShortcutInfo);
+ if (person == null) {
+ person = mContext.getDrawable(R.drawable.ic_person).mutate();
+ TypedArray ta = mContext.obtainStyledAttributes(new int[]{android.R.attr.colorAccent});
+ int colorAccent = ta.getColor(0, 0);
+ ta.recycle();
+ person.setTint(colorAccent);
+ }
ImageView image = findViewById(R.id.conversation_icon);
- image.setImageDrawable(mIconFactory.getConversationDrawable(
- mShortcutInfo, mPackageName, mAppUid, important));
+ image.setImageDrawable(person);
+
+ ImageView app = findViewById(R.id.conversation_icon_badge_icon);
+ app.setImageDrawable(mIconFactory.getAppBadge(
+ mPackageName, UserHandle.getUserId(mSbn.getUid())));
+
+ findViewById(R.id.conversation_icon_badge_ring).setVisibility(important ? VISIBLE : GONE);
}
private void bindPackage() {
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 204dd9f5e58c..88e5364cd55f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -36,6 +36,7 @@ import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.DataSaverController.Listener;
+import com.android.systemui.statusbar.policy.DeviceControlsController;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.HotspotController.Callback;
import com.android.systemui.util.UserAwareController;
@@ -58,6 +59,7 @@ public class AutoTileManager implements UserAwareController {
public static final String WORK = "work";
public static final String NIGHT = "night";
public static final String CAST = "cast";
+ public static final String DEVICE_CONTROLS = "controls";
public static final String BRIGHTNESS = "reduce_brightness";
static final String SETTING_SEPARATOR = ":";
@@ -74,6 +76,7 @@ public class AutoTileManager implements UserAwareController {
private final ManagedProfileController mManagedProfileController;
private final NightDisplayListener mNightDisplayListener;
private final CastController mCastController;
+ private final DeviceControlsController mDeviceControlsController;
private final ReduceBrightColorsController mReduceBrightColorsController;
private final boolean mIsReduceBrightColorsAvailable;
private final ArrayList<AutoAddSetting> mAutoAddSettingList = new ArrayList<>();
@@ -88,6 +91,7 @@ public class AutoTileManager implements UserAwareController {
NightDisplayListener nightDisplayListener,
CastController castController,
ReduceBrightColorsController reduceBrightColorsController,
+ DeviceControlsController deviceControlsController,
@Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
mContext = context;
mHost = host;
@@ -102,6 +106,7 @@ public class AutoTileManager implements UserAwareController {
mCastController = castController;
mReduceBrightColorsController = reduceBrightColorsController;
mIsReduceBrightColorsAvailable = isReduceBrightColorsAvailable;
+ mDeviceControlsController = deviceControlsController;
}
/**
@@ -138,6 +143,9 @@ public class AutoTileManager implements UserAwareController {
if (!mAutoTracker.isAdded(BRIGHTNESS) && mIsReduceBrightColorsAvailable) {
mReduceBrightColorsController.addCallback(mReduceBrightColorsCallback);
}
+ if (!mAutoTracker.isAdded(DEVICE_CONTROLS)) {
+ mDeviceControlsController.setCallback(mDeviceControlsCallback);
+ }
int settingsN = mAutoAddSettingList.size();
for (int i = 0; i < settingsN; i++) {
@@ -158,6 +166,7 @@ public class AutoTileManager implements UserAwareController {
mReduceBrightColorsController.removeCallback(mReduceBrightColorsCallback);
}
mCastController.removeCallback(mCastCallback);
+ mDeviceControlsController.removeCallback();
int settingsN = mAutoAddSettingList.size();
for (int i = 0; i < settingsN; i++) {
mAutoAddSettingList.get(i).setListening(false);
@@ -274,6 +283,17 @@ public class AutoTileManager implements UserAwareController {
}
};
+ private final DeviceControlsController.Callback mDeviceControlsCallback =
+ new DeviceControlsController.Callback() {
+ @Override
+ public void onControlsAvailable(int position) {
+ if (mAutoTracker.isAdded(DEVICE_CONTROLS)) return;
+ mHost.addTile(DEVICE_CONTROLS, position);
+ mAutoTracker.setTileAdded(DEVICE_CONTROLS);
+ mHandler.post(() -> mDeviceControlsController.removeCallback());
+ }
+ };
+
@VisibleForTesting
final NightDisplayListener.Callback mNightDisplayCallback =
new NightDisplayListener.Callback() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index aa0be8a39716..8ed9cd66aed1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -239,6 +239,7 @@ import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.tuner.TunerService;
import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
@@ -791,6 +792,7 @@ public class StatusBar extends SystemUI implements DemoMode,
BrightnessSlider.Factory brightnessSliderFactory,
WiredChargingRippleController chargingRippleAnimationController,
OngoingCallController ongoingCallController,
+ TunerService tunerService,
FeatureFlags featureFlags) {
super(context);
mNotificationsController = notificationsController;
@@ -873,6 +875,15 @@ public class StatusBar extends SystemUI implements DemoMode,
mOngoingCallController = ongoingCallController;
mFeatureFlags = featureFlags;
+ tunerService.addTunable(
+ (key, newValue) -> {
+ if (key.equals(Settings.Secure.DOZE_ALWAYS_ON)) {
+ updateLightRevealScrimVisibility();
+ }
+ },
+ Settings.Secure.DOZE_ALWAYS_ON
+ );
+
mExpansionChangedListeners = new ArrayList<>();
mBubbleExpandListener =
@@ -1216,15 +1227,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
mChargingRippleAnimationController.setViewHost(mNotificationShadeWindowView);
-
-
- if (mFeatureFlags.useNewLockscreenAnimations()
- && (mDozeParameters.getAlwaysOn() || mDozeParameters.isQuickPickupEnabled())) {
- mLightRevealScrim.setVisibility(View.VISIBLE);
- mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
- } else {
- mLightRevealScrim.setVisibility(View.GONE);
- }
+ updateLightRevealScrimVisibility();
mNotificationPanelViewController.initDependencies(
this,
@@ -4654,4 +4657,19 @@ public class StatusBar extends SystemUI implements DemoMode,
public void removeExpansionChangedListener(@NonNull ExpansionChangedListener listener) {
mExpansionChangedListeners.remove(listener);
}
+
+ private void updateLightRevealScrimVisibility() {
+ if (mLightRevealScrim == null) {
+ // status bar may not be inflated yet
+ return;
+ }
+
+ if (mFeatureFlags.useNewLockscreenAnimations()
+ && (mDozeParameters.getAlwaysOn() || mDozeParameters.isQuickPickupEnabled())) {
+ mLightRevealScrim.setVisibility(View.VISIBLE);
+ mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
+ } else {
+ mLightRevealScrim.setVisibility(View.GONE);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 785d98ccd8dc..2c2779e53e16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -100,6 +100,7 @@ import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.tuner.TunerService;
import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
@@ -208,6 +209,7 @@ public interface StatusBarPhoneModule {
BrightnessSlider.Factory brightnessSliderFactory,
WiredChargingRippleController chargingRippleAnimationController,
OngoingCallController ongoingCallController,
+ TunerService tunerService,
FeatureFlags featureFlags) {
return new StatusBar(
context,
@@ -291,6 +293,7 @@ public interface StatusBarPhoneModule {
brightnessSliderFactory,
chargingRippleAnimationController,
ongoingCallController,
+ tunerService,
featureFlags);
}
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStorePrivateKey.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
index 06e4c88fa632..b21189802c19 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStorePrivateKey.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,18 +14,22 @@
* limitations under the License.
*/
-package android.security.keystore;
-
-import java.security.PrivateKey;
+package com.android.systemui.statusbar.policy
/**
- * {@link PrivateKey} backed by Android Keystore.
- *
- * @hide
+ * Supports adding a DeviceControls QS tile
*/
-public class AndroidKeyStorePrivateKey extends AndroidKeyStoreKey implements PrivateKey {
-
- public AndroidKeyStorePrivateKey(String alias, int uid, String algorithm) {
- super(alias, uid, algorithm);
+interface DeviceControlsController {
+ interface Callback {
+ /**
+ * If controls become available, initiate this callback with the desired position
+ */
+ fun onControlsAvailable(position: Int)
}
+
+ /** Add callback, supporting only a single callback at once */
+ fun setCallback(callback: Callback)
+
+ /** Remove any existing callback, if any */
+ fun removeCallback()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
new file mode 100644
index 000000000000..d3907ae9a150
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.SharedPreferences
+import android.util.Log
+
+import com.android.systemui.R
+import com.android.systemui.controls.ControlsServiceInfo
+import com.android.systemui.controls.dagger.ControlsComponent
+import com.android.systemui.controls.management.ControlsListingController
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.QSTileHost.POSITION_AT_END
+import com.android.systemui.settings.UserContextProvider
+import com.android.systemui.statusbar.policy.DeviceControlsController.Callback
+
+import javax.inject.Inject
+
+/**
+ * Watches for Device Controls QS Tile activation, which can happen in two ways:
+ * <ol>
+ * <li>Migration from Power Menu - For existing Android 11 users, create a tile in a high
+ * priority position.
+ * <li>Device controls service becomes available - For non-migrated users, create a tile and
+ * place at the end of active tiles, and initiate seeding where possible.
+ * </ol>
+ */
+@SysUISingleton
+public class DeviceControlsControllerImpl @Inject constructor(
+ private val context: Context,
+ private val controlsComponent: ControlsComponent,
+ private val userContextProvider: UserContextProvider
+) : DeviceControlsController {
+
+ private var callback: Callback? = null
+ internal var position: Int? = null
+
+ private val listingCallback = object : ControlsListingController.ControlsListingCallback {
+ override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) {
+ if (!serviceInfos.isEmpty()) {
+ seedFavorites(serviceInfos)
+ }
+ }
+ }
+
+ companion object {
+ private const val TAG = "DeviceControlsControllerImpl"
+ internal const val QS_PRIORITY_POSITION = 3
+ internal const val QS_DEFAULT_POSITION = POSITION_AT_END
+
+ internal const val PREFS_CONTROLS_SEEDING_COMPLETED = "SeedingCompleted"
+ internal const val PREFS_CONTROLS_FILE = "controls_prefs"
+ private const val SEEDING_MAX = 2
+ }
+
+ private fun checkMigrationToQs() {
+ controlsComponent.getControlsController().ifPresent {
+ if (!it.getFavorites().isEmpty()) {
+ position = QS_PRIORITY_POSITION
+ }
+ }
+ }
+
+ /**
+ * This migration logic assumes that something like [AutoTileManager] is tracking state
+ * externally, and won't call this method after receiving a response via
+ * [Callback#onControlsAvailable], once per user. Otherwise the calculated position may be
+ * incorrect.
+ */
+ override fun setCallback(callback: Callback) {
+ // Treat any additional call as a reset before recalculating
+ removeCallback()
+
+ checkMigrationToQs()
+ controlsComponent.getControlsListingController().ifPresent {
+ it.addCallback(listingCallback)
+ }
+
+ this.callback = callback
+ fireControlsAvailable()
+ }
+
+ override fun removeCallback() {
+ position = null
+ callback = null
+ controlsComponent.getControlsListingController().ifPresent {
+ it.removeCallback(listingCallback)
+ }
+ }
+
+ private fun fireControlsAvailable() {
+ position?.let {
+ Log.i(TAG, "Setting DeviceControlsTile position: $it")
+ callback?.onControlsAvailable(it)
+ }
+ }
+
+ /**
+ * See if any available control service providers match one of the preferred components. If
+ * they do, and there are no current favorites for that component, query the preferred
+ * component for a limited number of suggested controls.
+ */
+ private fun seedFavorites(serviceInfos: List<ControlsServiceInfo>) {
+ val preferredControlsPackages = context.getResources().getStringArray(
+ R.array.config_controlsPreferredPackages)
+
+ val prefs = userContextProvider.userContext.getSharedPreferences(
+ PREFS_CONTROLS_FILE, Context.MODE_PRIVATE)
+ val seededPackages = prefs.getStringSet(PREFS_CONTROLS_SEEDING_COMPLETED, emptySet())
+
+ val controlsController = controlsComponent.getControlsController().get()
+ val componentsToSeed = mutableListOf<ComponentName>()
+ var i = 0
+ while (i < Math.min(SEEDING_MAX, preferredControlsPackages.size)) {
+ val pkg = preferredControlsPackages[i]
+ serviceInfos.forEach {
+ if (pkg.equals(it.componentName.packageName) && !seededPackages.contains(pkg)) {
+ if (controlsController.countFavoritesForComponent(it.componentName) > 0) {
+ // When there are existing controls but no saved preference, assume it
+ // is out of sync, perhaps through a device restore, and update the
+ // preference
+ addPackageToSeededSet(prefs, pkg)
+ } else {
+ componentsToSeed.add(it.componentName)
+ }
+ }
+ }
+ i++
+ }
+
+ if (componentsToSeed.isEmpty()) return
+
+ controlsController.seedFavoritesForComponents(
+ componentsToSeed,
+ { response ->
+ Log.d(TAG, "Controls seeded: $response")
+ if (response.accepted) {
+ addPackageToSeededSet(prefs, response.packageName)
+ if (position == null) {
+ position = QS_DEFAULT_POSITION
+ }
+ fireControlsAvailable()
+
+ controlsComponent.getControlsListingController().ifPresent {
+ it.removeCallback(listingCallback)
+ }
+ }
+ })
+ }
+
+ private fun addPackageToSeededSet(prefs: SharedPreferences, pkg: String) {
+ val seededPackages = prefs.getStringSet(PREFS_CONTROLS_SEEDING_COMPLETED, emptySet())
+ val updatedPkgs = seededPackages.toMutableSet()
+ updatedPkgs.add(pkg)
+ prefs.edit().putStringSet(PREFS_CONTROLS_SEEDING_COMPLETED, updatedPkgs).apply()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
index fd37d89a24ec..d52ea890af7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -224,35 +224,29 @@ public class KeyguardQsUserSwitchController extends ViewController<UserAvatarVie
mView.setContentDescription(contentDescription);
}
- if (mCurrentUser.picture == null) {
- mView.setDrawableWithBadge(getDrawable(mCurrentUser).mutate(),
- mCurrentUser.resolveId());
- } else {
- int avatarSize =
- (int) mResources.getDimension(R.dimen.kg_framed_avatar_size);
- Drawable drawable = new CircleFramedDrawable(mCurrentUser.picture, avatarSize);
- drawable.setColorFilter(
- mCurrentUser.isSwitchToEnabled ? null
- : mAdapter.getDisabledUserAvatarColorFilter());
- mView.setDrawableWithBadge(drawable, mCurrentUser.info.id);
- }
+ mView.setDrawableWithBadge(getCurrentUserIcon().mutate(), mCurrentUser.resolveId());
}
- Drawable getDrawable(UserSwitcherController.UserRecord item) {
+ Drawable getCurrentUserIcon() {
Drawable drawable;
- if (item.isCurrent && item.isGuest) {
- drawable = mContext.getDrawable(R.drawable.ic_avatar_guest_user);
- } else {
- drawable = mAdapter.getIconDrawable(mContext, item);
- }
-
- int iconColorRes;
- if (item.isSwitchToEnabled) {
- iconColorRes = R.color.kg_user_switcher_avatar_icon_color;
+ if (mCurrentUser.picture == null) {
+ if (mCurrentUser.isCurrent && mCurrentUser.isGuest) {
+ drawable = mContext.getDrawable(R.drawable.ic_avatar_guest_user);
+ } else {
+ drawable = mAdapter.getIconDrawable(mContext, mCurrentUser);
+ }
+ int iconColorRes;
+ if (mCurrentUser.isSwitchToEnabled) {
+ iconColorRes = R.color.kg_user_switcher_avatar_icon_color;
+ } else {
+ iconColorRes = R.color.kg_user_switcher_restricted_avatar_icon_color;
+ }
+ drawable.setTint(mResources.getColor(iconColorRes, mContext.getTheme()));
} else {
- iconColorRes = R.color.kg_user_switcher_restricted_avatar_icon_color;
+ int avatarSize =
+ (int) mResources.getDimension(R.dimen.kg_framed_avatar_size);
+ drawable = new CircleFramedDrawable(mCurrentUser.picture, avatarSize);
}
- drawable.setTint(mResources.getColor(iconColorRes, mContext.getTheme()));
Drawable bg = mContext.getDrawable(R.drawable.kg_bg_avatar);
drawable = new LayerDrawable(new Drawable[]{bg, drawable});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 5a78ea82ab04..6843eb509b86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -34,6 +34,7 @@ import android.content.pm.ShortcutManager;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -157,52 +158,48 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
/**
* The remote view needs to adapt to colorized notifications when set
* It overrides the background of itself as well as all of its childern
- * @param color colorized notification color
+ * @param backgroundColor colorized notification color
*/
- public void setBackgroundTintColor(int color, boolean colorized) {
- if (colorized == mColorized && color == mTint) return;
+ public void setBackgroundTintColor(final int backgroundColor, boolean colorized) {
+ if (colorized == mColorized && backgroundColor == mTint) return;
mColorized = colorized;
- mTint = color;
- final int[][] states = new int[][]{
- new int[]{com.android.internal.R.attr.state_enabled},
- new int[]{},
- };
- final int[] colors;
+ mTint = backgroundColor;
+ final int editBgColor;
+ final int accentColor;
+ final int textColor;
+ final int hintTextColor;
if (colorized) {
- final boolean dark = !ContrastColorUtil.isColorLight(color);
- final int finalColor = dark
- ? Color.WHITE
- : Color.BLACK;
- colors = new int[]{
- finalColor,
- finalColor & 0x4DFFFFFF // %30 opacity
- };
- mEditText.setUniformBackgroundTintColor(color);
- mEditText.setUniformForegroundColor(finalColor);
-
+ final boolean dark = !ContrastColorUtil.isColorLight(backgroundColor);
+ final int foregroundColor = dark ? Color.WHITE : Color.BLACK;
+ editBgColor = backgroundColor;
+ accentColor = foregroundColor;
+ textColor = foregroundColor;
+ hintTextColor = ColorUtils.setAlphaComponent(foregroundColor, 0x99);
} else {
- mEditText.setTextColor(mContext.getColor(R.color.remote_input_text));
- mEditText.setHintTextColor(mContext.getColorStateList(R.color.remote_input_hint));
- TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
+ textColor = mContext.getColor(R.color.remote_input_text);
+ hintTextColor = mContext.getColor(R.color.remote_input_hint);
+ try (TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
com.android.internal.R.attr.colorAccent,
com.android.internal.R.attr.colorBackgroundFloating,
- });
- int colorAccent = ta.getColor(0, 0);
- int colorBackgroundFloating = ta.getColor(1, 0);
- ta.recycle();
- mEditText.setTextBackgroundColors(colorAccent, colorBackgroundFloating);
- colors = new int[]{
- colorAccent,
- colorBackgroundFloating & 0x4DFFFFFF // %30 opacity
- };
- }
- mEditText.setBackgroundColor(color);
- final ColorStateList tint = new ColorStateList(states, colors);
- mSendButton.setImageTintList(tint);
- mProgressBar.setProgressTintList(tint);
- mProgressBar.setIndeterminateTintList(tint);
- mProgressBar.setSecondaryProgressTintList(tint);
- setBackgroundColor(color);
+ })) {
+ accentColor = ta.getColor(0, textColor);
+ editBgColor = ta.getColor(1, backgroundColor);
+ }
+ }
+ mEditText.setAllColors(backgroundColor, editBgColor,
+ accentColor, textColor, hintTextColor);
+ final ColorStateList accentTint = new ColorStateList(new int[][]{
+ new int[]{com.android.internal.R.attr.state_enabled},
+ new int[]{},
+ }, new int[]{
+ accentColor,
+ accentColor & 0x4DFFFFFF // %30 opacity
+ });
+ mSendButton.setImageTintList(accentTint);
+ mProgressBar.setProgressTintList(accentTint);
+ mProgressBar.setIndeterminateTintList(accentTint);
+ mProgressBar.setSecondaryProgressTintList(accentTint);
+ setBackgroundColor(backgroundColor);
}
@Override
@@ -796,20 +793,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
}
}
- protected void setUniformBackgroundTintColor(int color) {
- mBackgroundColor.setColor(color);
- mTextBackground.setColor(color);
- }
-
- protected void setUniformForegroundColor(int color) {
- int stroke = getContext().getResources()
- .getDimensionPixelSize(R.dimen.remote_input_view_text_stroke);
- mTextBackground.setStroke(stroke, color);
- setTextColor(color);
- setHintTextColor(ColorUtils.setAlphaComponent(color, 0x99));
- setTextCursorDrawable(null);
- }
-
@Override
public void getFocusedRect(Rect r) {
super.getFocusedRect(r);
@@ -938,11 +921,17 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
return remainingItems;
}
- protected void setTextBackgroundColors(int strokeColor, int textBackground) {
- mTextBackground.setColor(textBackground);
+ protected void setAllColors(int backgroundColor, int editBackgroundColor,
+ int accentColor, int textColor, int hintTextColor) {
+ setBackgroundColor(backgroundColor);
+ mBackgroundColor.setColor(backgroundColor);
+ mTextBackground.setColor(editBackgroundColor);
int stroke = getContext().getResources()
.getDimensionPixelSize(R.dimen.remote_input_view_text_stroke);
- mTextBackground.setStroke(stroke, strokeColor);
+ mTextBackground.setStroke(stroke, accentColor);
+ setTextColor(textColor);
+ setHintTextColor(hintTextColor);
+ getTextCursorDrawable().setColorFilter(accentColor, PorterDuff.Mode.SRC_IN);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index 7a4b912d4071..766602261099 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
@@ -26,6 +26,8 @@ import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastControllerImpl;
+import com.android.systemui.statusbar.policy.DeviceControlsController;
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.ExtensionControllerImpl;
import com.android.systemui.statusbar.policy.FlashlightController;
@@ -44,8 +46,6 @@ import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
import com.android.systemui.statusbar.policy.SecurityController;
import com.android.systemui.statusbar.policy.SecurityControllerImpl;
-import com.android.systemui.statusbar.policy.SensorPrivacyController;
-import com.android.systemui.statusbar.policy.SensorPrivacyControllerImpl;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -115,6 +115,11 @@ public interface StatusBarPolicyModule {
/** */
@Binds
+ DeviceControlsController provideDeviceControlsController(
+ DeviceControlsControllerImpl controllerImpl);
+
+ /** */
+ @Binds
NetworkController.AccessPointController provideAccessPointController(
AccessPointControllerImpl accessPointControllerImpl);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 1026a5ca1be5..a8a3d79c67cf 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -301,11 +301,13 @@ public class VolumeDialogImpl implements VolumeDialog,
// the volume dialog container itself, so this is fine.
for (int i = 0; i < mDialogView.getChildCount(); i++) {
final View view = mDialogView.getChildAt(i);
+ final int[] locInWindow = new int[2];
+ view.getLocationInWindow(locInWindow);
mTouchableRegion.op(
- view.getLeft(),
- view.getTop(),
- view.getRight(),
- view.getBottom(),
+ locInWindow[0],
+ locInWindow[1],
+ locInWindow[0] + view.getWidth(),
+ locInWindow[1] + view.getHeight(),
Region.Op.UNION);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index 70a7b7a5acbc..0fcd79b357c3 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -18,26 +18,34 @@ package com.android.keyguard;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+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;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.res.Resources;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
+import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.keyguard.clock.ClockManager;
+import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.NotificationIconContainer;
@@ -50,6 +58,8 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.verification.VerificationMode;
+import java.util.concurrent.Executor;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
@@ -78,6 +88,12 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
ContentResolver mContentResolver;
@Mock
BroadcastDispatcher mBroadcastDispatcher;
+ @Mock
+ private PluginManager mPluginManager;
+ @Mock
+ private FeatureFlags mFeatureFlags;
+ @Mock
+ private Executor mExecutor;
private KeyguardClockSwitchController mController;
@@ -87,6 +103,8 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
when(mView.findViewById(com.android.systemui.R.id.left_aligned_notification_icon_container))
.thenReturn(mNotificationIcons);
+ when(mView.getContext()).thenReturn(getContext());
+ when(mFeatureFlags.isSmartspaceEnabled()).thenReturn(true);
when(mView.isAttachedToWindow()).thenReturn(true);
when(mResources.getString(anyInt())).thenReturn("h:mm");
mController = new KeyguardClockSwitchController(
@@ -98,7 +116,10 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
mKeyguardSliceViewController,
mNotificationIconAreaController,
mContentResolver,
- mBroadcastDispatcher);
+ mBroadcastDispatcher,
+ mPluginManager,
+ mFeatureFlags,
+ mExecutor);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
@@ -182,6 +203,45 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE);
}
+ @Test
+ public void testSmartspacePluginConnectedRemovesKeyguardStatusArea() {
+ mController.init();
+
+ View statusArea = mock(View.class);
+ when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(statusArea);
+
+ View nic = mock(View.class);
+ when(mView.findViewById(R.id.left_aligned_notification_icon_container)).thenReturn(nic);
+ when(nic.getLayoutParams()).thenReturn(mock(RelativeLayout.LayoutParams.class));
+
+ BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
+ TestView view = mock(TestView.class);
+ when(plugin.getView(any())).thenReturn(view);
+
+ mController.mPluginListener.onPluginConnected(plugin, mContext);
+ verify(statusArea).setVisibility(View.GONE);
+ }
+
+ @Test
+ public void testSmartspacePluginDisconnectedShowsKeyguardStatusArea() {
+ mController.init();
+
+ View statusArea = mock(View.class);
+ when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(statusArea);
+
+ View nic = mock(View.class);
+ when(mView.findViewById(R.id.left_aligned_notification_icon_container)).thenReturn(nic);
+ when(nic.getLayoutParams()).thenReturn(mock(RelativeLayout.LayoutParams.class));
+
+ BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
+ TestView view = mock(TestView.class);
+ when(plugin.getView(any())).thenReturn(view);
+
+ mController.mPluginListener.onPluginConnected(plugin, mContext);
+ mController.mPluginListener.onPluginDisconnected(plugin);
+ verify(statusArea).setVisibility(View.VISIBLE);
+ }
+
private void verifyAttachment(VerificationMode times) {
verify(mClockManager, times).addOnClockChangedListener(
any(ClockManager.ClockChangedListener.class));
@@ -191,4 +251,12 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
any(ColorExtractor.OnColorsChangedListener.class));
verify(mView, times).updateColors(mGradientColors);
}
+
+ private static class TestView extends View implements BcSmartspaceDataPlugin.SmartspaceView {
+ TestView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void registerDataProvider(BcSmartspaceDataPlugin plugin) { }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
index 8683dd6c33bd..814f073edbb0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
@@ -40,6 +41,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
@@ -78,6 +80,8 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
private RecyclerView mListView;
+ private Rect mAvailableBounds = new Rect(100, 200, 300, 400);
+
private int mMenuHalfWidth;
private int mMenuHalfHeight;
private int mScreenHalfWidth;
@@ -339,6 +343,66 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
assertThat(mMenuView.mShapeType).isEqualTo(/* halfOval */ 1);
}
+ @Test
+ public void getAccessibilityActionList_matchResult() {
+ final AccessibilityNodeInfo infos = new AccessibilityNodeInfo();
+ mMenuView.onInitializeAccessibilityNodeInfo(infos);
+
+ assertThat(infos.getActionList().size()).isEqualTo(4);
+ }
+
+ @Test
+ public void accessibilityActionMove_moveTopLeft_success() {
+ final AccessibilityFloatingMenuView menuView =
+ spy(new AccessibilityFloatingMenuView(mContext));
+ doReturn(mAvailableBounds).when(menuView).getAvailableBounds();
+
+ final boolean isActionPerformed =
+ menuView.performAccessibilityAction(R.id.action_move_top_left, null);
+
+ assertThat(isActionPerformed).isTrue();
+ verify(menuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.top);
+ }
+
+ @Test
+ public void accessibilityActionMove_moveTopRight_success() {
+ final AccessibilityFloatingMenuView menuView =
+ spy(new AccessibilityFloatingMenuView(mContext));
+ doReturn(mAvailableBounds).when(menuView).getAvailableBounds();
+
+ final boolean isActionPerformed =
+ menuView.performAccessibilityAction(R.id.action_move_top_right, null);
+
+ assertThat(isActionPerformed).isTrue();
+ verify(menuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.top);
+ }
+
+ @Test
+ public void accessibilityActionMove_moveBottomLeft_success() {
+ final AccessibilityFloatingMenuView menuView =
+ spy(new AccessibilityFloatingMenuView(mContext));
+ doReturn(mAvailableBounds).when(menuView).getAvailableBounds();
+
+ final boolean isActionPerformed =
+ menuView.performAccessibilityAction(R.id.action_move_bottom_left, null);
+
+ assertThat(isActionPerformed).isTrue();
+ verify(menuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.bottom);
+ }
+
+ @Test
+ public void accessibilityActionMove_moveBottomRight_success() {
+ final AccessibilityFloatingMenuView menuView =
+ spy(new AccessibilityFloatingMenuView(mContext));
+ doReturn(mAvailableBounds).when(menuView).getAvailableBounds();
+
+ final boolean isActionPerformed =
+ menuView.performAccessibilityAction(R.id.action_move_bottom_right, null);
+
+ assertThat(isActionPerformed).isTrue();
+ verify(menuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.bottom);
+ }
+
@After
public void tearDown() {
mInterceptMotionEvent = null;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index beca96549fb9..9504970af19c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -47,6 +47,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -103,6 +104,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
+ private KeyguardViewMediator mKeyguardViewMediator;
+ @Mock
private IUdfpsOverlayControllerCallback mUdfpsOverlayControllerCallback;
private FakeExecutor mFgExecutor;
@@ -155,7 +158,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
mStatusBarKeyguardViewManager,
mDumpManager,
mAuthRippleController,
- mKeyguardUpdateMonitor);
+ mKeyguardUpdateMonitor,
+ mKeyguardViewMediator);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index 879cdbfb775f..2383c7b985c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -18,7 +18,7 @@ package com.android.systemui.biometrics;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -44,7 +45,6 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.List;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -65,12 +65,13 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
private DelayableExecutor mExecutor;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @Mock
+ private KeyguardViewMediator mKeyguardViewMediator;
private UdfpsKeyguardViewController mController;
// Capture listeners so that they can be used to send events
@Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerCaptor;
- private StatusBarStateController.StateListener mParentStatusBarStateListener;
private StatusBarStateController.StateListener mStatusBarStateListener;
@Captor private ArgumentCaptor<StatusBar.ExpansionChangedListener> mExpansionListenerCaptor;
@@ -83,6 +84,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(false);
mController = new UdfpsKeyguardViewController(
mView,
mStatusBarStateController,
@@ -90,7 +92,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
mStatusBarKeyguardViewManager,
mKeyguardUpdateMonitor,
mExecutor,
- mDumpManager);
+ mDumpManager,
+ mKeyguardViewMediator);
}
@Test
@@ -108,7 +111,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
@Test
public void testViewControllerQueriesSBStateOnAttached() {
mController.onViewAttached();
- verify(mStatusBarStateController, times(2)).getState();
+ verify(mStatusBarStateController).getState();
verify(mStatusBarStateController).getDozeAmount();
final float dozeAmount = .88f;
@@ -117,7 +120,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
captureStatusBarStateListeners();
mController.onViewAttached();
- verify(mView).setPauseAuth(true);
+ verify(mView, atLeast(1)).setPauseAuth(true);
verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount);
}
@@ -128,7 +131,6 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
captureExpansionListener();
mController.onViewDetached();
- verify(mStatusBarStateController).removeCallback(mParentStatusBarStateListener);
verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
verify(mStatusBar).removeExpansionChangedListener(mExpansionListener);
}
@@ -168,6 +170,47 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
}
@Test
+ public void testShouldPauseAuthOnShade() {
+ mController.onViewAttached();
+ captureStatusBarStateListeners();
+ captureExpansionListener();
+
+ // WHEN not on keyguard yet (shade = home)
+ sendStatusBarStateChanged(StatusBarState.SHADE);
+
+ // THEN pause auth
+ assertTrue(mController.shouldPauseAuth());
+ }
+
+ @Test
+ public void testShouldPauseAuthAnimatingScreenOffFromShade() {
+ mController.onViewAttached();
+ captureStatusBarStateListeners();
+ captureExpansionListener();
+
+ // WHEN transitioning from home/shade => keyguard + animating screen off
+ mStatusBarStateListener.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD);
+ when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(true);
+
+ // THEN pause auth
+ assertTrue(mController.shouldPauseAuth());
+ }
+
+ @Test
+ public void testDoNotPauseAuthAnimatingScreenOffFromLS() {
+ mController.onViewAttached();
+ captureStatusBarStateListeners();
+ captureExpansionListener();
+
+ // WHEN animating screen off transition from LS => AOD
+ sendStatusBarStateChanged(StatusBarState.KEYGUARD);
+ when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(true);
+
+ // THEN don't pause auth
+ assertFalse(mController.shouldPauseAuth());
+ }
+
+ @Test
public void testOverrideShouldPauseAuthOnShadeLocked() {
mController.onViewAttached();
captureStatusBarStateListeners();
@@ -203,15 +246,11 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
private void sendStatusBarStateChanged(int statusBarState) {
mStatusBarStateListener.onStateChanged(statusBarState);
- mParentStatusBarStateListener.onStateChanged(statusBarState);
}
private void captureStatusBarStateListeners() {
- verify(mStatusBarStateController, times(2)).addCallback(mStateListenerCaptor.capture());
- List<StatusBarStateController.StateListener> stateListeners =
- mStateListenerCaptor.getAllValues();
- mParentStatusBarStateListener = stateListeners.get(0);
- mStatusBarStateListener = stateListeners.get(1);
+ verify(mStatusBarStateController).addCallback(mStateListenerCaptor.capture());
+ mStatusBarStateListener = mStateListenerCaptor.getValue();
}
private void captureExpansionListener() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
index 93769c4600de..3130e977dc83 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -58,15 +58,10 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.controls.controller.ControlsController;
-import com.android.systemui.controls.dagger.ControlsComponent;
-import com.android.systemui.controls.management.ControlsListingController;
-import com.android.systemui.controls.ui.ControlsUiController;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.GlobalActions;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
-import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -118,11 +113,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
@Mock private SysuiColorExtractor mColorExtractor;
@Mock private IStatusBarService mStatusBarService;
@Mock private NotificationShadeWindowController mNotificationShadeWindowController;
- @Mock private ControlsUiController mControlsUiController;
@Mock private IWindowManager mWindowManager;
@Mock private Executor mBackgroundExecutor;
- @Mock private ControlsListingController mControlsListingController;
- @Mock private ControlsController mControlsController;
@Mock private UiEventLogger mUiEventLogger;
@Mock private RingerModeTracker mRingerModeTracker;
@Mock private RingerModeLiveData mRingerModeLiveData;
@@ -130,10 +122,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
@Mock GlobalActionsPanelPlugin mWalletPlugin;
@Mock GlobalActionsPanelPlugin.PanelViewController mWalletController;
@Mock private Handler mHandler;
- @Mock private UserContextProvider mUserContextProvider;
@Mock private UserTracker mUserTracker;
@Mock private SecureSettings mSecureSettings;
- private ControlsComponent mControlsComponent;
private TestableLooper mTestableLooper;
@@ -144,18 +134,6 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
allowTestableLooperAsMainThread();
when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData);
- when(mUserContextProvider.getUserContext()).thenReturn(mContext);
- mControlsComponent = new ControlsComponent(
- true,
- mContext,
- () -> mControlsController,
- () -> mControlsUiController,
- () -> mControlsListingController,
- mLockPatternUtils,
- mKeyguardStateController,
- mUserTracker,
- mSecureSettings
- );
mGlobalActionsDialog = new GlobalActionsDialog(mContext,
mWindowManagerFuncs,
@@ -186,9 +164,7 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
mUiEventLogger,
mRingerModeTracker,
mSysUiState,
- mHandler,
- mControlsComponent,
- mUserContextProvider
+ mHandler
);
mGlobalActionsDialog.setZeroDialogPressDelayForTesting();
@@ -511,7 +487,7 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
when(mKeyguardStateController.isUnlocked()).thenReturn(false);
when(mActivityManager.getCurrentUser()).thenReturn(newUserInfo());
when(mLockPatternUtils.getStrongAuthForUser(anyInt())).thenReturn(STRONG_AUTH_NOT_REQUIRED);
- mGlobalActionsDialog.mShowLockScreenCardsAndControls = false;
+ mGlobalActionsDialog.mShowLockScreenCards = false;
setupDefaultActions();
when(mWalletPlugin.onPanelShown(any(), anyBoolean())).thenReturn(mWalletController);
when(mWalletController.getPanelContent()).thenReturn(new FrameLayout(mContext));
@@ -528,14 +504,14 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
}
@Test
- public void testShouldNotShowLockScreenMessage_whenWalletOrControlsShownOnLockScreen()
+ public void testShouldNotShowLockScreenMessage_whenWalletShownOnLockScreen()
throws RemoteException {
mGlobalActionsDialog = spy(mGlobalActionsDialog);
mGlobalActionsDialog.mDialog = null;
when(mKeyguardStateController.isUnlocked()).thenReturn(false);
when(mActivityManager.getCurrentUser()).thenReturn(newUserInfo());
when(mLockPatternUtils.getStrongAuthForUser(anyInt())).thenReturn(STRONG_AUTH_NOT_REQUIRED);
- mGlobalActionsDialog.mShowLockScreenCardsAndControls = true;
+ mGlobalActionsDialog.mShowLockScreenCards = true;
setupDefaultActions();
when(mWalletPlugin.onPanelShown(any(), anyBoolean())).thenReturn(mWalletController);
when(mWalletController.getPanelContent()).thenReturn(new FrameLayout(mContext));
@@ -552,7 +528,7 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
}
@Test
- public void testShouldNotShowLockScreenMessage_whenControlsAndWalletBothDisabled()
+ public void testShouldNotShowLockScreenMessage_whenWalletBothDisabled()
throws RemoteException {
mGlobalActionsDialog = spy(mGlobalActionsDialog);
mGlobalActionsDialog.mDialog = null;
@@ -560,11 +536,10 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
when(mActivityManager.getCurrentUser()).thenReturn(newUserInfo());
when(mLockPatternUtils.getStrongAuthForUser(anyInt())).thenReturn(STRONG_AUTH_NOT_REQUIRED);
- mGlobalActionsDialog.mShowLockScreenCardsAndControls = true;
+ mGlobalActionsDialog.mShowLockScreenCards = true;
setupDefaultActions();
when(mWalletPlugin.onPanelShown(any(), anyBoolean())).thenReturn(mWalletController);
when(mWalletController.getPanelContent()).thenReturn(null);
- when(mControlsUiController.getAvailable()).thenReturn(false);
mGlobalActionsDialog.showOrHideDialog(false, true, mWalletPlugin);
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 1260eaf23c52..b0e3e3e936a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -61,6 +61,7 @@ import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.InjectionInflationController;
+import com.android.systemui.util.settings.SecureSettings;
import org.junit.Before;
import org.junit.Ignore;
@@ -130,7 +131,8 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
mock(PluginManager.class), mock(TunerService.class),
() -> mock(AutoTileManager.class), mock(DumpManager.class),
mock(BroadcastDispatcher.class), Optional.of(mock(StatusBar.class)),
- mock(QSLogger.class), mock(UiEventLogger.class), mock(UserTracker.class));
+ mock(QSLogger.class), mock(UiEventLogger.class), mock(UserTracker.class),
+ mock(SecureSettings.class));
qs.setHost(host);
qs.setListening(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index 5422ae831de3..e4b95af1af04 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -196,7 +196,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
}
@Test
- public void testNetworkLoggingEnabled() {
+ public void testNetworkLoggingEnabled_deviceOwner() {
when(mSecurityController.isDeviceManaged()).thenReturn(true);
when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true);
mFooter.refreshState();
@@ -222,6 +222,18 @@ public class QSSecurityFooterTest extends SysuiTestCase {
}
@Test
+ public void testNetworkLoggingEnabled_managedProfileOwner() {
+ when(mSecurityController.hasWorkProfile()).thenReturn(true);
+ when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true);
+ mFooter.refreshState();
+
+ TestableLooper.get(this).processAllMessages();
+ assertEquals(mContext.getString(
+ R.string.quick_settings_disclosure_managed_profile_network_activity),
+ mFooterText.getText());
+ }
+
+ @Test
public void testManagedCACertsInstalled() {
when(mSecurityController.isDeviceManaged()).thenReturn(true);
when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true);
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 2ca8082f777a..57e9d2b1ffe8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -21,20 +21,21 @@ 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.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
-import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -64,11 +65,13 @@ import com.android.systemui.statusbar.phone.AutoTileManager;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.settings.SecureSettings;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
@@ -78,7 +81,6 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
-import java.util.Objects;
import java.util.Optional;
import javax.inject.Provider;
@@ -119,6 +121,8 @@ public class QSTileHostTest extends SysuiTestCase {
private UiEventLogger mUiEventLogger;
@Mock
private UserTracker mUserTracker;
+ @Mock
+ private SecureSettings mSecureSettings;
private Handler mHandler;
private TestableLooper mLooper;
@@ -138,11 +142,12 @@ public class QSTileHostTest extends SysuiTestCase {
mHandler = new Handler(mLooper.getLooper());
mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler,
mLooper.getLooper(), mPluginManager, mTunerService, mAutoTiles, mDumpManager,
- mBroadcastDispatcher, mStatusBar, mQSLogger, mUiEventLogger, mUserTracker);
+ mBroadcastDispatcher, mStatusBar, mQSLogger, mUiEventLogger, mUserTracker,
+ mSecureSettings);
setUpTileFactory();
- Settings.Secure.putStringForUser(mContext.getContentResolver(), QSTileHost.TILES_SETTING,
- "", ActivityManager.getCurrentUser());
+ when(mSecureSettings.getStringForUser(eq(QSTileHost.TILES_SETTING), anyInt()))
+ .thenReturn("");
}
@After
@@ -162,6 +167,8 @@ public class QSTileHostTest extends SysuiTestCase {
return new TestTile1(mQSTileHost);
} else if ("spec2".equals(spec)) {
return new TestTile2(mQSTileHost);
+ } else if ("spec3".equals(spec)) {
+ return new TestTile3(mQSTileHost);
} else if ("na".equals(spec)) {
return new NotAvailableTile(mQSTileHost);
} else if (CUSTOM_TILE_SPEC.equals(spec)) {
@@ -232,6 +239,8 @@ public class QSTileHostTest extends SysuiTestCase {
@Test
public void testNoRepeatedSpecs_addTile() {
+ mContext.getOrCreateTestableResources()
+ .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec2");
mQSTileHost.addTile("spec1");
@@ -242,6 +251,48 @@ public class QSTileHostTest extends SysuiTestCase {
}
@Test
+ public void testAddTileAtValidPosition() {
+ mContext.getOrCreateTestableResources()
+ .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
+ mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+
+ mQSTileHost.addTile("spec2", 1);
+
+ assertEquals(3, mQSTileHost.mTileSpecs.size());
+ assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
+ assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
+ assertEquals("spec3", mQSTileHost.mTileSpecs.get(2));
+ }
+
+ @Test
+ public void testAddTileAtInvalidPositionAddsToEnd() {
+ mContext.getOrCreateTestableResources()
+ .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
+ mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+
+ mQSTileHost.addTile("spec2", 100);
+
+ assertEquals(3, mQSTileHost.mTileSpecs.size());
+ assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
+ assertEquals("spec3", mQSTileHost.mTileSpecs.get(1));
+ assertEquals("spec2", mQSTileHost.mTileSpecs.get(2));
+ }
+
+ @Test
+ public void testAddTileAtEnd() {
+ mContext.getOrCreateTestableResources()
+ .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
+ mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+
+ mQSTileHost.addTile("spec2", QSTileHost.POSITION_AT_END);
+
+ assertEquals(3, mQSTileHost.mTileSpecs.size());
+ assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
+ assertEquals("spec3", mQSTileHost.mTileSpecs.get(1));
+ assertEquals("spec2", mQSTileHost.mTileSpecs.get(2));
+ }
+
+ @Test
public void testNoRepeatedSpecs_customTile() {
mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, CUSTOM_TILE_SPEC);
@@ -318,16 +369,17 @@ public class QSTileHostTest extends SysuiTestCase {
verify(mQSLogger, never()).logTileDestroyed(isNull(), anyString());
}
- private static class TestQSTileHost extends QSTileHost {
+ private class TestQSTileHost extends QSTileHost {
TestQSTileHost(Context context, StatusBarIconController iconController,
QSFactory defaultFactory, Handler mainHandler, Looper bgLooper,
PluginManager pluginManager, TunerService tunerService,
Provider<AutoTileManager> autoTiles, DumpManager dumpManager,
BroadcastDispatcher broadcastDispatcher, StatusBar statusBar, QSLogger qsLogger,
- UiEventLogger uiEventLogger, UserTracker userTracker) {
+ UiEventLogger uiEventLogger, UserTracker userTracker,
+ SecureSettings secureSettings) {
super(context, iconController, defaultFactory, mainHandler, bgLooper, pluginManager,
tunerService, autoTiles, dumpManager, broadcastDispatcher,
- Optional.of(statusBar), qsLogger, uiEventLogger, userTracker);
+ Optional.of(statusBar), qsLogger, uiEventLogger, userTracker, secureSettings);
}
@Override
@@ -339,18 +391,16 @@ public class QSTileHostTest extends SysuiTestCase {
}
@Override
- public void changeTiles(List<String> previousTiles, List<String> newTiles) {
- String previousSetting = Settings.Secure.getStringForUser(
- getContext().getContentResolver(), TILES_SETTING,
- ActivityManager.getCurrentUser());
- super.changeTiles(previousTiles, newTiles);
+ void saveTilesToSettings(List<String> tileSpecs) {
+ super.saveTilesToSettings(tileSpecs);
+
+ ArgumentCaptor<String> specs = ArgumentCaptor.forClass(String.class);
+ verify(mSecureSettings, atLeastOnce()).putStringForUser(eq(QSTileHost.TILES_SETTING),
+ specs.capture(), isNull(), eq(false), anyInt(), eq(true));
+
// After tiles are changed, make sure to call onTuningChanged with the new setting if it
// changed
- String newSetting = Settings.Secure.getStringForUser(getContext().getContentResolver(),
- TILES_SETTING, ActivityManager.getCurrentUser());
- if (!Objects.equals(newSetting, previousSetting)) {
- onTuningChanged(TILES_SETTING, newSetting);
- }
+ onTuningChanged(TILES_SETTING, specs.getValue());
}
}
@@ -415,6 +465,13 @@ public class QSTileHostTest extends SysuiTestCase {
}
}
+ private class TestTile3 extends TestTile {
+
+ protected TestTile3(QSHost host) {
+ super(host);
+ }
+ }
+
private class NotAvailableTile extends TestTile {
protected NotAvailableTile(QSHost host) {
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 2a3bc31cb2a4..641f917bcfbe 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
@@ -53,6 +53,7 @@ import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.settings.SecureSettings;
import org.junit.After;
import org.junit.Before;
@@ -95,6 +96,8 @@ public class TileServicesTest extends SysuiTestCase {
private UiEventLogger mUiEventLogger;
@Mock
private UserTracker mUserTracker;
+ @Mock
+ private SecureSettings mSecureSettings;
@Before
public void setUp() throws Exception {
@@ -114,7 +117,8 @@ public class TileServicesTest extends SysuiTestCase {
Optional.of(mStatusBar),
mQSLogger,
mUiEventLogger,
- mUserTracker);
+ mUserTracker,
+ mSecureSettings);
mTileService = new TestTileServices(host, Looper.getMainLooper(), mBroadcastDispatcher,
mUserTracker);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index 9fe568718908..a59f45d53597 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -38,11 +38,9 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
-import com.android.systemui.statusbar.FeatureFlags
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.settings.FakeSettings
-import com.android.systemui.util.settings.GlobalSettings
import com.android.systemui.util.settings.SecureSettings
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -83,9 +81,6 @@ class DeviceControlsTileTest : SysuiTestCase() {
@Mock
private lateinit var controlsController: ControlsController
@Mock
- private lateinit var featureFlags: FeatureFlags
- private lateinit var globalSettings: GlobalSettings
- @Mock
private lateinit var serviceInfo: ControlsServiceInfo
@Mock
private lateinit var uiEventLogger: UiEventLogger
@@ -116,11 +111,6 @@ class DeviceControlsTileTest : SysuiTestCase() {
setupControlsComponent()
- globalSettings = FakeSettings()
-
- globalSettings.putInt(DeviceControlsTile.SETTINGS_FLAG, 1)
- `when`(featureFlags.isKeyguardLayoutEnabled).thenReturn(true)
-
tile = createTile()
}
@@ -156,13 +146,6 @@ class DeviceControlsTileTest : SysuiTestCase() {
}
@Test
- fun testNotAvailableFeature() {
- `when`(featureFlags.isKeyguardLayoutEnabled).thenReturn(false)
-
- assertThat(tile.isAvailable).isFalse()
- }
-
- @Test
fun testNotAvailableControls() {
featureEnabled = false
tile = createTile()
@@ -179,14 +162,6 @@ class DeviceControlsTileTest : SysuiTestCase() {
}
@Test
- fun testNotAvailableControlsLockscreenFlag() {
- globalSettings.putInt(DeviceControlsTile.SETTINGS_FLAG, 0)
- tile = createTile()
-
- assertThat(tile.isAvailable).isFalse()
- }
-
- @Test
fun testObservingCallback() {
verify(controlsListingController).observe(
any(LifecycleOwner::class.java),
@@ -329,9 +304,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
statusBarStateController,
activityStarter,
qsLogger,
- controlsComponent,
- featureFlags,
- globalSettings
+ controlsComponent
)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index 33166ccadc27..f57283ff950d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -19,21 +19,36 @@ package com.android.systemui.qs.tiles;
import static android.content.pm.PackageManager.FEATURE_NFC_HOST_CARD_EMULATION;
import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT;
+import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
import android.os.Handler;
+import android.service.quickaccesswallet.GetWalletCardsError;
+import android.service.quickaccesswallet.GetWalletCardsRequest;
+import android.service.quickaccesswallet.GetWalletCardsResponse;
import android.service.quickaccesswallet.QuickAccessWalletClient;
+import android.service.quickaccesswallet.QuickAccessWalletService;
+import android.service.quickaccesswallet.WalletCard;
import android.service.quicksettings.Tile;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -56,17 +71,30 @@ import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.settings.SecureSettings;
+import com.google.common.util.concurrent.MoreExecutors;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Collections;
+
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class QuickAccessWalletTileTest extends SysuiTestCase {
+ private static final String CARD_ID = "card_id";
+ private static final Icon CARD_IMAGE =
+ Icon.createWithBitmap(Bitmap.createBitmap(70, 50, Bitmap.Config.ARGB_8888));
+
+ private final Intent mWalletIntent = new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET)
+ .setComponent(new ComponentName(mContext.getPackageName(), "WalletActivity"));
+
@Mock
private QSTileHost mHost;
@Mock
@@ -88,6 +116,10 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
private SecureSettings mSecureSettings;
@Mock
private FeatureFlags mFeatureFlags;
+ @Captor
+ ArgumentCaptor<GetWalletCardsRequest> mRequestCaptor;
+ @Captor
+ ArgumentCaptor<QuickAccessWalletClient.OnWalletCardsRetrievedCallback> mCallbackCaptor;
private TestableLooper mTestableLooper;
private QuickAccessWalletTile mTile;
@@ -101,6 +133,7 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
when(mHost.getContext()).thenReturn(mContext);
when(mHost.getUiEventLogger()).thenReturn(mUiEventLogger);
when(mFeatureFlags.isQuickAccessWalletEnabled()).thenReturn(true);
+ when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
mTile = new QuickAccessWalletTile(
mHost,
@@ -115,6 +148,7 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
mKeyguardStateController,
mPackageManager,
mSecureSettings,
+ MoreExecutors.directExecutor(),
mFeatureFlags);
}
@@ -156,11 +190,11 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
@Test
public void testHandleUpdateState_updateLabelAndIcon() {
- QSTile.Icon icon = QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_wallet);
QSTile.State state = new QSTile.State();
+ QSTile.Icon icon = QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_wallet);
when(mQuickAccessWalletClient.getServiceLabel()).thenReturn("QuickAccessWallet");
- mTile.handleUpdateState(state, new Object());
+ mTile.handleUpdateState(state, null);
assertEquals("QuickAccessWallet", state.label.toString());
assertTrue(state.label.toString().contentEquals(state.contentDescription));
@@ -168,40 +202,170 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
}
@Test
- public void testHandleUpdateState_deviceLocked_tileInactive() {
- QSTile.State state = new QSTile.State();
+ public void testHandleUpdateState_hasCard_deviceLocked_tileInactive() {
when(mKeyguardStateController.isUnlocked()).thenReturn(false);
- when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
+ QSTile.State state = new QSTile.State();
+ setUpWalletCard(/* hasCard= */ true);
- mTile.handleUpdateState(state, new Object());
+ mTile.handleUpdateState(state, null);
assertEquals(Tile.STATE_INACTIVE, state.state);
- assertNull(state.stateDescription);
+ assertEquals(
+ mContext.getString(R.string.wallet_secondary_label_device_locked),
+ state.secondaryLabel);
+ assertNotNull(state.stateDescription);
+ assertNull(state.sideViewDrawable);
}
@Test
- public void testHandleUpdateState_deviceLocked_tileActive() {
- QSTile.State state = new QSTile.State();
+ public void testHandleUpdateState_hasCard_deviceUnlocked_tileActive() {
when(mKeyguardStateController.isUnlocked()).thenReturn(true);
- when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
+ QSTile.State state = new QSTile.State();
+ setUpWalletCard(/* hasCard= */ true);
- mTile.handleUpdateState(state, new Object());
+ mTile.handleUpdateState(state, null);
assertEquals(Tile.STATE_ACTIVE, state.state);
- assertTrue(state.secondaryLabel.toString().contentEquals(state.stateDescription));
assertEquals(
- getContext().getString(R.string.wallet_secondary_label),
- state.secondaryLabel.toString());
+ mContext.getString(R.string.wallet_secondary_label_active),
+ state.secondaryLabel);
+ assertNotNull(state.stateDescription);
+ assertNotNull(state.sideViewDrawable);
}
+
@Test
- public void testHandleUpdateState_qawFeatureUnavailable_tileUnavailable() {
+ public void testHandleUpdateState_noCard_tileInactive() {
QSTile.State state = new QSTile.State();
- when(mKeyguardStateController.isUnlocked()).thenReturn(true);
+ setUpWalletCard(/* hasCard= */ false);
+
+ mTile.handleUpdateState(state, null);
+
+ assertEquals(Tile.STATE_INACTIVE, state.state);
+ assertEquals(
+ mContext.getString(R.string.wallet_secondary_label_no_card),
+ state.secondaryLabel);
+ assertNotNull(state.stateDescription);
+ assertNull(state.sideViewDrawable);
+ }
+
+ @Test
+ public void testHandleUpdateState_qawFeatureUnavailable_tileUnavailable() {
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(false);
+ QSTile.State state = new QSTile.State();
- mTile.handleUpdateState(state, new Object());
+ mTile.handleUpdateState(state, null);
assertEquals(Tile.STATE_UNAVAILABLE, state.state);
+ assertNull(state.stateDescription);
+ assertNull(state.sideViewDrawable);
+ }
+
+ @Test
+ public void testHandleSetListening_queryCards() {
+ mTile.handleSetListening(true);
+
+ verify(mQuickAccessWalletClient)
+ .getWalletCards(any(), mRequestCaptor.capture(), mCallbackCaptor.capture());
+
+ GetWalletCardsRequest request = mRequestCaptor.getValue();
+ assertEquals(
+ mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width),
+ request.getCardWidthPx());
+ assertEquals(
+ mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_height),
+ request.getCardHeightPx());
+ assertEquals(2, request.getMaxCards());
+ assertThat(mCallbackCaptor.getValue()).isInstanceOf(
+ QuickAccessWalletClient.OnWalletCardsRetrievedCallback.class);
+ }
+
+ @Test
+ public void testQueryCards_hasCards_updateSideViewDrawable() {
+ when(mKeyguardStateController.isUnlocked()).thenReturn(true);
+ setUpWalletCard(/* hasCard= */ true);
+
+ assertNotNull(mTile.getState().sideViewDrawable);
+ }
+
+ @Test
+ public void testState_queryCards_hasCards_then_noCards() {
+ when(mKeyguardStateController.isUnlocked()).thenReturn(true);
+ GetWalletCardsResponse responseWithCards =
+ new GetWalletCardsResponse(
+ Collections.singletonList(createWalletCard(mContext)), 0);
+ GetWalletCardsResponse responseWithoutCards =
+ new GetWalletCardsResponse(Collections.EMPTY_LIST, 0);
+
+ mTile.handleSetListening(true);
+
+ verify(mQuickAccessWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
+
+ // query wallet cards, has cards
+ mCallbackCaptor.getValue().onWalletCardsRetrieved(responseWithCards);
+ mTestableLooper.processAllMessages();
+
+ assertNotNull(mTile.getState().sideViewDrawable);
+
+ mTile.handleSetListening(true);
+
+ verify(mQuickAccessWalletClient, times(2))
+ .getWalletCards(any(), any(), mCallbackCaptor.capture());
+
+ // query wallet cards, has no cards
+ mCallbackCaptor.getValue().onWalletCardsRetrieved(responseWithoutCards);
+ mTestableLooper.processAllMessages();
+
+ assertNull(mTile.getState().sideViewDrawable);
+ }
+
+ @Test
+ public void testQueryCards_noCards_notUpdateSideViewDrawable() {
+ setUpWalletCard(/* hasCard= */ false);
+
+ assertNull(mTile.getState().sideViewDrawable);
+ }
+
+ @Test
+ public void testQueryCards_error_notUpdateSideViewDrawable() {
+ String errorMessage = "getWalletCardsError";
+ GetWalletCardsError error = new GetWalletCardsError(CARD_IMAGE, errorMessage);
+
+ mTile.handleSetListening(true);
+
+ verify(mQuickAccessWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
+
+ mCallbackCaptor.getValue().onWalletCardRetrievalError(error);
+ mTestableLooper.processAllMessages();
+
+ assertNull(mTile.getState().sideViewDrawable);
+ }
+
+ @Test
+ public void testHandleSetListening_notListening_notQueryCards() {
+ mTile.handleSetListening(false);
+
+ verifyZeroInteractions(mQuickAccessWalletClient);
+ }
+
+ private void setUpWalletCard(boolean hasCard) {
+ GetWalletCardsResponse response =
+ new GetWalletCardsResponse(
+ hasCard
+ ? Collections.singletonList(createWalletCard(mContext))
+ : Collections.EMPTY_LIST, 0);
+
+ mTile.handleSetListening(true);
+
+ verify(mQuickAccessWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
+
+ mCallbackCaptor.getValue().onWalletCardsRetrieved(response);
+ mTestableLooper.processAllMessages();
+ }
+
+ private WalletCard createWalletCard(Context context) {
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE);
+ return new WalletCard.Builder(CARD_ID, CARD_IMAGE, "description", pendingIntent).build();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
index 1c32cd4b612a..5bab1bcddb6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
@@ -77,6 +77,58 @@ public class ScrollCaptureControllerTest extends SysuiTestCase {
}
@Test
+ public void testInfiniteWithPartialResultsTop() {
+ ScrollCaptureController controller = new TestScenario()
+ .withPageHeight(100)
+ .withPageVisibleRange(5, 100) // <-- simulate 5px of invisible top
+ .withMaxPages(2.5f)
+ .withTileHeight(50)
+ .withAvailableRange(Integer.MIN_VALUE, Integer.MAX_VALUE)
+ .createController(mContext);
+
+ ScrollCaptureController.LongScreenshot screenshot =
+ getUnchecked(controller.run(EMPTY_RESPONSE));
+
+ // Each tile is cropped to the visible page size, which is inset 5px from the TOP
+ // requested result
+ // 0, 50 5, 50
+ // -45, 5 -40, 5 <-- clear previous / top
+ // 5, 55 5, 55 (not cropped, target is positioned fully within visible range)
+ // 55, 105 55, 105
+ // 105, 155 105, 155
+ // 155, 205 155, 205 <-- bottom
+
+ assertEquals("top", -40, screenshot.getTop());
+ assertEquals("bottom", 205, screenshot.getBottom());
+ }
+
+ @Test
+ public void testInfiniteWithPartialResultsBottom() {
+ ScrollCaptureController controller = new TestScenario()
+ .withPageHeight(100)
+ .withPageVisibleRange(0, 95) // <-- simulate 5px of invisible bottom
+ .withMaxPages(2.5f)
+ .withTileHeight(50)
+ .withAvailableRange(Integer.MIN_VALUE, Integer.MAX_VALUE)
+ .createController(mContext);
+
+ ScrollCaptureController.LongScreenshot screenshot =
+ getUnchecked(controller.run(EMPTY_RESPONSE));
+
+ // Each tile is cropped to the visible page size, which is inset 5px from the BOTTOM
+ // requested result
+ // 0, 50 0, 50 // not cropped, positioned within visible range
+ // -50, 0 -50, 0 <-- clear previous/reverse
+ // 0, 50 - 0, 45 // target now positioned at page bottom, bottom cropped
+ // 45, 95, 45, 90
+ // 90, 140, 140, 135
+ // 135, 185 185, 180 <-- bottom
+
+ assertEquals("top", -50, screenshot.getTop());
+ assertEquals("bottom", 180, screenshot.getBottom());
+ }
+
+ @Test
public void testLimitedBottom() {
ScrollCaptureController controller = new TestScenario()
.withPageHeight(100)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureFrameworkSmokeTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureFrameworkSmokeTest.java
index 06b39abd1d0e..54d973266ff3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureFrameworkSmokeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureFrameworkSmokeTest.java
@@ -82,7 +82,11 @@ public class ScrollCaptureFrameworkSmokeTest extends SysuiTestCase {
latch.await(1000, TimeUnit.MILLISECONDS);
assertNotNull(mResponse);
- assertTrue(mResponse.isConnected());
- assertTrue(mResponse.getWindowTitle().contains(ScrollViewActivity.class.getSimpleName()));
+ if (!mResponse.isConnected()) {
+ Log.e(TAG, "Received response with no connection: " + mResponse);
+ fail("expected response.isConnected() == true");
+ }
+ assertTrue("expected a connection to ScrollViewActivity",
+ mResponse.getWindowTitle().contains(ScrollViewActivity.class.getSimpleName()));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt
index 6d293b5f63b5..3ed8ecf1d809 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt
@@ -20,7 +20,6 @@ import android.testing.AndroidTestingRunner
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
-import android.widget.CompoundButton
import android.widget.SeekBar
import androidx.test.filters.SmallTest
import com.android.settingslib.RestrictedLockUtils
@@ -37,14 +36,12 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyBoolean
-import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.isNull
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.notNull
-import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
@@ -72,10 +69,6 @@ class BrightnessSliderTest : SysuiTestCase() {
private lateinit var seekBarChangeCaptor: ArgumentCaptor<SeekBar.OnSeekBarChangeListener>
@Mock
private lateinit var seekBar: SeekBar
- @Captor
- private lateinit var checkedChangeCaptor: ArgumentCaptor<CompoundButton.OnCheckedChangeListener>
- @Mock
- private lateinit var compoundButton: CompoundButton
private var mFalsingManager: FalsingManagerFake = FalsingManagerFake()
private lateinit var mController: BrightnessSlider
@@ -101,7 +94,6 @@ class BrightnessSliderTest : SysuiTestCase() {
fun testListenersAddedOnAttach() {
mController.onViewAttached()
- verify(brightnessSliderView).setOnCheckedChangeListener(notNull())
verify(brightnessSliderView).setOnSeekBarChangeListener(notNull())
}
@@ -111,7 +103,6 @@ class BrightnessSliderTest : SysuiTestCase() {
mController.onViewDetached()
verify(brightnessSliderView).setOnSeekBarChangeListener(isNull())
- verify(brightnessSliderView).setOnCheckedChangeListener(isNull())
verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
}
@@ -127,7 +118,6 @@ class BrightnessSliderTest : SysuiTestCase() {
verify(brightnessSliderView, never()).max
verify(brightnessSliderView, never()).value
- verify(brightnessSliderView, never()).isChecked
verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
}
@@ -139,7 +129,6 @@ class BrightnessSliderTest : SysuiTestCase() {
verify(brightnessSliderView, never()).max
verify(brightnessSliderView, never()).value
- verify(brightnessSliderView, never()).isChecked
verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
}
@@ -150,40 +139,15 @@ class BrightnessSliderTest : SysuiTestCase() {
val checked = true
whenever(brightnessSliderView.max).thenReturn(maxValue)
whenever(brightnessSliderView.value).thenReturn(progress)
- whenever(brightnessSliderView.isChecked).thenReturn(checked)
mController.setMirrorControllerAndMirror(mirrorController)
verify(mirror).max = maxValue
- verify(mirror).isChecked = checked
verify(mirror).value = progress
verify(brightnessSliderView).setOnDispatchTouchEventListener(notNull())
}
@Test
- fun testSetCheckedRelayed_true() {
- mController.isChecked = true
- verify(brightnessSliderView).isChecked = true
- }
-
- @Test
- fun testSetCheckedRelayed_false() {
- mController.isChecked = false
- verify(brightnessSliderView).isChecked = false
- }
-
- @Test
- fun testGetChecked() {
- whenever(brightnessSliderView.isChecked).thenReturn(true)
-
- assertThat(mController.isChecked).isTrue()
-
- whenever(brightnessSliderView.isChecked).thenReturn(false)
-
- assertThat(mController.isChecked).isFalse()
- }
-
- @Test
fun testSetMaxRelayed() {
mController.max = 120
verify(brightnessSliderView).max = 120
@@ -229,13 +193,12 @@ class BrightnessSliderTest : SysuiTestCase() {
@Test
fun testSeekBarProgressChanged() {
mController.onViewAttached()
- whenever(brightnessSliderView.isChecked).thenReturn(true)
verify(brightnessSliderView).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
seekBarChangeCaptor.value.onProgressChanged(seekBar, 23, true)
- verify(listener).onChanged(anyBoolean(), eq(true), eq(23), eq(false))
+ verify(listener).onChanged(anyBoolean(), eq(23), eq(false))
}
@Test
@@ -243,7 +206,6 @@ class BrightnessSliderTest : SysuiTestCase() {
val parent = mock(ViewGroup::class.java)
whenever(brightnessSliderView.value).thenReturn(42)
whenever(brightnessSliderView.parent).thenReturn(parent)
- whenever(brightnessSliderView.isChecked).thenReturn(true)
mController.onViewAttached()
mController.setMirrorControllerAndMirror(mirrorController)
@@ -251,7 +213,7 @@ class BrightnessSliderTest : SysuiTestCase() {
seekBarChangeCaptor.value.onStartTrackingTouch(seekBar)
- verify(listener).onChanged(eq(true), eq(true), eq(42), eq(false))
+ verify(listener).onChanged(eq(true), eq(42), eq(false))
verify(mirrorController).showMirror()
verify(mirrorController).setLocation(parent)
}
@@ -259,7 +221,6 @@ class BrightnessSliderTest : SysuiTestCase() {
@Test
fun testSeekBarTrackingStopped() {
whenever(brightnessSliderView.value).thenReturn(23)
- whenever(brightnessSliderView.isChecked).thenReturn(true)
mController.onViewAttached()
mController.setMirrorControllerAndMirror(mirrorController)
@@ -267,38 +228,7 @@ class BrightnessSliderTest : SysuiTestCase() {
seekBarChangeCaptor.value.onStopTrackingTouch(seekBar)
- verify(listener).onChanged(eq(false), eq(true), eq(23), eq(true))
+ verify(listener).onChanged(eq(false), eq(23), eq(true))
verify(mirrorController).hideMirror()
}
-
- @Test
- fun testButtonCheckedChanged_false() {
- val checked = false
-
- mController.onViewAttached()
- mController.setMirrorControllerAndMirror(mirrorController)
- verify(brightnessSliderView).setOnCheckedChangeListener(capture(checkedChangeCaptor))
-
- checkedChangeCaptor.value.onCheckedChanged(compoundButton, checked)
-
- verify(brightnessSliderView).enableSlider(!checked)
- verify(listener).onChanged(anyBoolean(), eq(checked), anyInt(), eq(false))
- // Called once with false when the mirror is set
- verify(mirror, times(2)).isChecked = checked
- }
-
- @Test
- fun testButtonCheckedChanged_true() {
- val checked = true
-
- mController.onViewAttached()
- mController.setMirrorControllerAndMirror(mirrorController)
- verify(brightnessSliderView).setOnCheckedChangeListener(capture(checkedChangeCaptor))
-
- checkedChangeCaptor.value.onCheckedChanged(compoundButton, checked)
-
- verify(brightnessSliderView).enableSlider(!checked)
- verify(listener).onChanged(anyBoolean(), eq(checked), anyInt(), eq(false))
- verify(mirror).isChecked = checked
- }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index d4b21c6f6949..12e341a5f135 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -199,8 +199,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
when(mShortcutInfo.getLabel()).thenReturn("Convo name");
List<ShortcutInfo> shortcuts = Arrays.asList(mShortcutInfo);
when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
- when(mIconFactory.getConversationDrawable(
- any(ShortcutInfo.class), anyString(), anyInt(), anyBoolean()))
+ when(mIconFactory.getBaseIconDrawable(any(ShortcutInfo.class)))
.thenReturn(mIconDrawable);
mNotificationChannel = new NotificationChannel(
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 094a70e24572..ac160d6dd9fb 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
@@ -54,6 +54,7 @@ import com.android.systemui.qs.SecureSetting;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
import com.android.systemui.statusbar.policy.DataSaverController;
+import com.android.systemui.statusbar.policy.DeviceControlsController;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.settings.SecureSettings;
@@ -94,6 +95,7 @@ public class AutoTileManagerTest extends SysuiTestCase {
@Mock private ManagedProfileController mManagedProfileController;
@Mock private NightDisplayListener mNightDisplayListener;
@Mock private ReduceBrightColorsController mReduceBrightColorsController;
+ @Mock private DeviceControlsController mDeviceControlsController;;
@Mock(answer = Answers.RETURNS_SELF)
private AutoAddTracker.Builder mAutoAddTrackerBuilder;
@Mock private Context mUserContext;
@@ -139,6 +141,7 @@ public class AutoTileManagerTest extends SysuiTestCase {
NightDisplayListener nightDisplayListener,
CastController castController,
ReduceBrightColorsController reduceBrightColorsController,
+ DeviceControlsController deviceControlsController,
@Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
return new AutoTileManager(context, autoAddTrackerBuilder, mQsTileHost,
Handler.createAsync(TestableLooper.get(this).getLooper()),
@@ -149,13 +152,15 @@ public class AutoTileManagerTest extends SysuiTestCase {
nightDisplayListener,
castController,
reduceBrightColorsController,
+ deviceControlsController,
isReduceBrightColorsAvailable);
}
private AutoTileManager createAutoTileManager(Context context) {
return createAutoTileManager(context, mAutoAddTrackerBuilder, mHotspotController,
mDataSaverController, mManagedProfileController, mNightDisplayListener,
- mCastController, mReduceBrightColorsController, mIsReduceBrightColorsAvailable);
+ mCastController, mReduceBrightColorsController, mDeviceControlsController,
+ mIsReduceBrightColorsAvailable);
}
@Test
@@ -169,10 +174,11 @@ public class AutoTileManagerTest extends SysuiTestCase {
NightDisplayListener nDS = mock(NightDisplayListener.class);
CastController cC = mock(CastController.class);
ReduceBrightColorsController rBC = mock(ReduceBrightColorsController.class);
+ DeviceControlsController dCC = mock(DeviceControlsController.class);
AutoTileManager manager =
createAutoTileManager(mock(Context.class), builder, hC, dSC, mPC, nDS, cC, rBC,
- true);
+ dCC, true);
verify(tracker, never()).initialize();
verify(hC, never()).addCallback(any());
@@ -181,6 +187,7 @@ public class AutoTileManagerTest extends SysuiTestCase {
verify(nDS, never()).setCallback(any());
verify(cC, never()).addCallback(any());
verify(rBC, never()).addCallback(any());
+ verify(dCC, never()).setCallback(any());
assertNull(manager.getSecureSettingForKey(TEST_SETTING));
assertNull(manager.getSecureSettingForKey(TEST_SETTING_COMPONENT));
}
@@ -229,6 +236,10 @@ public class AutoTileManagerTest extends SysuiTestCase {
inOrderCast.verify(mCastController).removeCallback(any());
inOrderCast.verify(mCastController).addCallback(any());
+ InOrder inOrderDevices = inOrder(mDeviceControlsController);
+ inOrderDevices.verify(mDeviceControlsController).removeCallback();
+ inOrderDevices.verify(mDeviceControlsController).setCallback(any());
+
SecureSetting setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING);
assertEquals(USER + 1, setting.getCurrentUser());
assertTrue(setting.isListening());
@@ -273,6 +284,10 @@ public class AutoTileManagerTest extends SysuiTestCase {
inOrderCast.verify(mCastController).removeCallback(any());
inOrderCast.verify(mCastController, never()).addCallback(any());
+ InOrder inOrderDevices = inOrder(mDeviceControlsController);
+ inOrderDevices.verify(mDeviceControlsController).removeCallback();
+ inOrderDevices.verify(mDeviceControlsController).setCallback(any());
+
SecureSetting setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING);
assertEquals(USER + 1, setting.getCurrentUser());
assertFalse(setting.isListening());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 39f0db5228bc..98a44875fbd7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -143,6 +143,7 @@ import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.volume.VolumeComponent;
@@ -265,6 +266,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private BrightnessSlider.Factory mBrightnessSliderFactory;
@Mock private WiredChargingRippleController mWiredChargingRippleController;
@Mock private OngoingCallController mOngoingCallController;
+ @Mock private TunerService mTunerService;
@Mock private FeatureFlags mFeatureFlags;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -430,6 +432,7 @@ public class StatusBarTest extends SysuiTestCase {
mBrightnessSliderFactory,
mWiredChargingRippleController,
mOngoingCallController,
+ mTunerService,
mFeatureFlags);
when(mNotificationShadeWindowView.findViewById(R.id.lock_icon_container)).thenReturn(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
new file mode 100644
index 000000000000..95a363ee110e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.ServiceInfo
+import android.testing.AndroidTestingRunner
+
+import androidx.test.filters.SmallTest
+
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.controls.ControlsServiceInfo
+import com.android.systemui.controls.dagger.ControlsComponent
+import com.android.systemui.controls.controller.ControlsController
+import com.android.systemui.controls.controller.SeedResponse
+import com.android.systemui.controls.controller.StructureInfo
+import com.android.systemui.controls.management.ControlsListingController
+import com.android.systemui.controls.management.ControlsListingController.ControlsListingCallback
+import com.android.systemui.settings.UserContextProvider
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_FILE
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_SEEDING_COMPLETED
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.QS_DEFAULT_POSITION
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.QS_PRIORITY_POSITION
+
+import java.util.Optional
+import java.util.function.Consumer
+
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.ArgumentMatchers.anyInt
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DeviceControlsControllerImplTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var controlsComponent: ControlsComponent
+ @Mock
+ private lateinit var controlsController: ControlsController
+ @Mock
+ private lateinit var controlsListingController: ControlsListingController
+ @Mock
+ private lateinit var callback: DeviceControlsController.Callback
+ @Captor
+ private lateinit var listingCallbackCaptor: ArgumentCaptor<ControlsListingCallback>
+ @Mock
+ private lateinit var structureInfo: StructureInfo
+ @Mock
+ private lateinit var serviceInfo: ServiceInfo
+ @Mock
+ private lateinit var userContextProvider: UserContextProvider
+ @Captor
+ private lateinit var seedCallback: ArgumentCaptor<Consumer<SeedResponse>>
+
+ private lateinit var controlsServiceInfo: ControlsServiceInfo
+ private lateinit var controller: DeviceControlsControllerImpl
+
+ companion object {
+ fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
+ fun <T> eq(value: T): T = Mockito.eq(value) ?: value
+ private val TEST_PKG = "test.pkg"
+ private val TEST_COMPONENT = ComponentName(TEST_PKG, "test.class")
+ }
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ `when`(controlsComponent.getControlsController())
+ .thenReturn(Optional.of(controlsController))
+ `when`(controlsComponent.getControlsListingController())
+ .thenReturn(Optional.of(controlsListingController))
+
+ controller = DeviceControlsControllerImpl(mContext, controlsComponent, userContextProvider)
+
+ `when`(serviceInfo.componentName).thenReturn(TEST_COMPONENT)
+ controlsServiceInfo = ControlsServiceInfo(mContext, serviceInfo)
+
+ `when`(userContextProvider.userContext).thenReturn(mContext)
+ mContext.getSharedPreferences(PREFS_CONTROLS_FILE, Context.MODE_PRIVATE).edit()
+ .putStringSet(PREFS_CONTROLS_SEEDING_COMPLETED, emptySet())
+ .apply()
+ }
+
+ @Test
+ fun testNoCallbackWhenNoServicesAvailable() {
+ `when`(controlsController.getFavorites()).thenReturn(emptyList())
+ controller.setCallback(callback)
+
+ verify(controlsListingController).addCallback(capture(listingCallbackCaptor))
+ listingCallbackCaptor.value.onServicesUpdated(emptyList())
+ verify(callback, never()).onControlsAvailable(anyInt())
+ }
+
+ @Test
+ fun testSetPriorityPositionIsSetWhenFavoritesAreAvailable() {
+ `when`(controlsController.getFavorites()).thenReturn(listOf(structureInfo))
+ controller.setCallback(callback)
+
+ verify(controlsListingController).addCallback(capture(listingCallbackCaptor))
+ listingCallbackCaptor.value.onServicesUpdated(listOf(controlsServiceInfo))
+ verify(callback).onControlsAvailable(QS_PRIORITY_POSITION)
+ }
+
+ @Test
+ fun testSetDefaultPositionIsSetWhenNoFavoritesAreAvailable() {
+ `when`(controlsController.getFavorites()).thenReturn(emptyList())
+ controller.setCallback(callback)
+
+ mContext.getOrCreateTestableResources().addOverride(
+ R.array.config_controlsPreferredPackages,
+ arrayOf(TEST_PKG))
+
+ verify(controlsListingController).addCallback(capture(listingCallbackCaptor))
+ listingCallbackCaptor.value.onServicesUpdated(listOf(controlsServiceInfo))
+
+ verify(controlsController).seedFavoritesForComponents(
+ eq(listOf(TEST_COMPONENT)),
+ capture(seedCallback)
+ )
+ seedCallback.value.accept(SeedResponse(TEST_PKG, true))
+ verify(callback).onControlsAvailable(QS_DEFAULT_POSITION)
+ }
+}
diff --git a/packages/WAPPushManager/AndroidManifest.xml b/packages/WAPPushManager/AndroidManifest.xml
index a75fb2d47bbd..15f01e678b43 100644
--- a/packages/WAPPushManager/AndroidManifest.xml
+++ b/packages/WAPPushManager/AndroidManifest.xml
@@ -27,7 +27,8 @@
<original-package android:name="com.android.smspush" />
<application
- android:allowClearUserData="false">
+ android:allowClearUserData="false"
+ android:directBootAware="true">
<service android:name=".WapPushManager"
android:permission="com.android.smspush.WAPPUSH_MANAGER_BIND"
android:exported="true">
diff --git a/packages/WAPPushManager/src/com/android/smspush/WapPushManager.java b/packages/WAPPushManager/src/com/android/smspush/WapPushManager.java
index dc2707b6ff8b..951e64fab015 100755
--- a/packages/WAPPushManager/src/com/android/smspush/WapPushManager.java
+++ b/packages/WAPPushManager/src/com/android/smspush/WapPushManager.java
@@ -26,17 +26,21 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
-import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.UserManager;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IWapPushManager;
import com.android.internal.telephony.WapPushManagerParams;
+import java.io.File;
+
/**
* The WapPushManager service is implemented to process incoming
* WAP Push messages and to maintain the Receiver Application/Application
@@ -67,8 +71,13 @@ public class WapPushManager extends Service {
/**
* Inner class that deals with application ID table
*/
- private class WapPushManDBHelper extends SQLiteOpenHelper {
- WapPushManDBHelper(Context context) {
+ @VisibleForTesting
+ public static class WapPushManDBHelper extends SQLiteOpenHelper {
+ /**
+ * Constructor
+ */
+ @VisibleForTesting
+ public WapPushManDBHelper(Context context) {
super(context, DATABASE_NAME, null, WAP_PUSH_MANAGER_VERSION);
if (LOCAL_LOGV) Log.v(LOG_TAG, "helper instance created.");
}
@@ -269,10 +278,6 @@ public class WapPushManager extends Service {
int app_type, boolean need_signature, boolean further_processing) {
WapPushManDBHelper dbh = getDatabase(mContext);
SQLiteDatabase db = dbh.getWritableDatabase();
- WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
- boolean ret = false;
- boolean insert = false;
- int sq = 0;
if (!appTypeCheck(app_type)) {
Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
@@ -280,34 +285,8 @@ public class WapPushManager extends Service {
+ WapPushManagerParams.APP_TYPE_SERVICE);
return false;
}
-
- if (lastapp == null) {
- insert = true;
- sq = 0;
- } else if (!lastapp.packageName.equals(package_name) ||
- !lastapp.className.equals(class_name)) {
- insert = true;
- sq = lastapp.installOrder + 1;
- }
-
- if (insert) {
- ContentValues values = new ContentValues();
-
- values.put("x_wap_application", x_app_id);
- values.put("content_type", content_type);
- values.put("package_name", package_name);
- values.put("class_name", class_name);
- values.put("app_type", app_type);
- values.put("need_signature", need_signature ? 1 : 0);
- values.put("further_processing", further_processing ? 1 : 0);
- values.put("install_order", sq);
- db.insert(APPID_TABLE_NAME, null, values);
- if (LOCAL_LOGV) Log.v(LOG_TAG, "add:" + x_app_id + ":" + content_type
- + " " + package_name + "." + class_name
- + ", newsq:" + sq);
- ret = true;
- }
-
+ boolean ret = insertPackage(dbh, db, x_app_id, content_type, package_name, class_name,
+ app_type, need_signature, further_processing);
db.close();
return ret;
@@ -404,11 +383,91 @@ public class WapPushManager extends Service {
protected WapPushManDBHelper getDatabase(Context context) {
if (mDbHelper == null) {
if (LOCAL_LOGV) Log.v(LOG_TAG, "create new db inst.");
- mDbHelper = new WapPushManDBHelper(context);
+ mDbHelper = new WapPushManDBHelper(context.createDeviceProtectedStorageContext());
}
+ // Migrate existing legacy database into the device encrypted storage.
+ migrateWapPushManDBIfNeeded(context);
return mDbHelper;
}
+ /**
+ * Inserts a package information into a database
+ */
+ @VisibleForTesting
+ public boolean insertPackage(WapPushManDBHelper dbh, SQLiteDatabase db, String appId,
+ String contentType, String packageName, String className, int appType,
+ boolean needSignature, boolean furtherProcessing) {
+
+ WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, appId, contentType);
+ boolean insert = false;
+ int sq = 0;
+
+ if (lastapp == null) {
+ insert = true;
+ sq = 0;
+ } else if (!lastapp.packageName.equals(packageName)
+ || !lastapp.className.equals(className)) {
+ insert = true;
+ sq = lastapp.installOrder + 1;
+ }
+
+ if (insert) {
+ ContentValues values = new ContentValues();
+
+ values.put("x_wap_application", appId);
+ values.put("content_type", contentType);
+ values.put("package_name", packageName);
+ values.put("class_name", className);
+ values.put("app_type", appType);
+ values.put("need_signature", needSignature ? 1 : 0);
+ values.put("further_processing", furtherProcessing ? 1 : 0);
+ values.put("install_order", sq);
+ db.insert(APPID_TABLE_NAME, null, values);
+ if (LOCAL_LOGV) {
+ Log.v(LOG_TAG, "add:" + appId + ":" + contentType + " " + packageName
+ + "." + className + ", newsq:" + sq);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Migrates a legacy database into the device encrypted storage
+ */
+ private void migrateWapPushManDBIfNeeded(Context context) {
+ UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ File file = context.getDatabasePath(DATABASE_NAME);
+ if (!userManager.isUserUnlocked() || !file.exists()) {
+ // Check if the device is unlocked because a legacy database can't access during
+ // DirectBoot.
+ return;
+ }
+
+ // Migration steps below:
+ // 1. Merge the package info to legacy database if there is any package info which is
+ // registered during DirectBoot.
+ // 2. Move the data base to the device encryped storage.
+ WapPushManDBHelper legacyDbHelper = new WapPushManDBHelper(context);
+ SQLiteDatabase legacyDb = legacyDbHelper.getWritableDatabase();
+ SQLiteDatabase db = mDbHelper.getWritableDatabase();
+ Cursor cur = db.query(APPID_TABLE_NAME, null, null, null, null, null, null);
+ while (cur.moveToNext()) {
+ insertPackage(legacyDbHelper, legacyDb,
+ cur.getString(cur.getColumnIndex("x_wap_application")),
+ cur.getString(cur.getColumnIndex("content_type")),
+ cur.getString(cur.getColumnIndex("package_name")),
+ cur.getString(cur.getColumnIndex("class_name")),
+ cur.getInt(cur.getColumnIndex("app_type")),
+ cur.getInt(cur.getColumnIndex("need_signature")) == 1,
+ cur.getInt(cur.getColumnIndex("further_processing")) == 1);
+ }
+ cur.close();
+ legacyDb.close();
+ db.close();
+ context.createDeviceProtectedStorageContext().moveDatabaseFrom(context, DATABASE_NAME);
+ Log.i(LOG_TAG, "Migrated the legacy database.");
+ }
/**
* This method is used for testing
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java
index f7afc57f3199..b9dac4e2b28e 100644
--- a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java
@@ -21,6 +21,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.database.sqlite.SQLiteDatabase;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.Telephony.Sms.Intents;
@@ -33,7 +34,9 @@ import com.android.internal.telephony.WspTypeDecoder;
import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.util.HexDump;
import com.android.smspush.WapPushManager;
+import com.android.smspush.WapPushManager.WapPushManDBHelper;
+import java.io.File;
import java.util.Random;
/**
@@ -467,8 +470,9 @@ public class WapPushTest extends ServiceTestCase<WapPushManager> {
try {
super.setUp();
// get verifier
- getContext().bindService(new Intent(IDataVerify.class.getName()),
- mConn, Context.BIND_AUTO_CREATE);
+ Intent intent = new Intent(IDataVerify.class.getName());
+ intent.setPackage("com.android.smspush.unitTests");
+ getContext().bindService(intent, mConn, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
Log.w(LOG_TAG, "super exception");
}
@@ -552,15 +556,15 @@ public class WapPushTest extends ServiceTestCase<WapPushManager> {
}
/**
- * Add sqlite injection test
+ * Sqlite injection test
*/
- public void testAddPackage0() {
+ public void testSqliteInjection() {
String inject = "' union select 0,'com.android.settings','com.android.settings.Settings',0,0,0--";
- // insert new data
+ // update data
IWapPushManager iwapman = getInterface();
try {
- assertFalse(iwapman.addPackage(
+ assertFalse(iwapman.updatePackage(
inject,
Integer.toString(mContentTypeValue),
mPackageName, mClassName,
@@ -2528,4 +2532,45 @@ public class WapPushTest extends ServiceTestCase<WapPushManager> {
mMessageBody = originalMessageBody;
}
+ /**
+ * DataBase migration test.
+ */
+ public void testDataBaseMigration() {
+ IWapPushManager iwapman = getInterface();
+ WapPushManager wpman = getService();
+ Context context = getContext();
+
+ addPackageToLegacyDB(mAppIdValue, mContentTypeValue, mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, true, true);
+ addPackageToLegacyDB(mAppIdValue + 10, mContentTypeValue, mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, true, true);
+
+ File oldDbFile = context.getDatabasePath("wappush.db");
+ assertTrue(oldDbFile.exists());
+ assertTrue(wpman.verifyData(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, true, true));
+ assertFalse(oldDbFile.exists());
+
+ // Clean up DB
+ try {
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ }
+
+ private void addPackageToLegacyDB(int appId, int contextType, String packagename,
+ String classnName, int appType, boolean signature, boolean furtherProcessing) {
+ WapPushManager wpman = getService();
+ WapPushManDBHelper dbh = new WapPushManDBHelper(getContext());
+ SQLiteDatabase db = dbh.getWritableDatabase();
+
+ wpman.insertPackage(dbh, db, Integer.toString(appId), Integer.toString(contextType),
+ packagename, classnName, appType, signature, furtherProcessing);
+ }
}
diff --git a/services/Android.bp b/services/Android.bp
index c160842ee379..25b270ea1a79 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -66,6 +66,11 @@ filegroup {
visibility: ["//visibility:private"],
}
+java_library {
+ name: "Slogf",
+ srcs: ["core/java/com/android/server/utils/Slogf.java"],
+}
+
// merge all required services into one jar
// ============================================================
java_library {
@@ -118,6 +123,7 @@ java_library {
libs: [
"android.hidl.manager-V1.0-java",
"framework-tethering.stubs.module_lib",
+ "service-art.stubs.system_server",
],
// Uncomment to enable output of certain warnings (deprecated, unchecked)
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 57a93fa69a03..185cdfc1aa42 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1294,14 +1294,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
+ mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
// Listen for user add/removes to inform PermissionMonitor.
// Should run on mHandler to avoid any races.
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_USER_ADDED);
- intentFilter.addAction(Intent.ACTION_USER_REMOVED);
+ final IntentFilter userIntentFilter = new IntentFilter();
+ userIntentFilter.addAction(Intent.ACTION_USER_ADDED);
+ userIntentFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter,
+ null /* broadcastPermission */, mHandler);
- mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
- mUserAllContext.registerReceiver(mIntentReceiver, intentFilter,
+ // Listen to package add/removes for netd
+ final IntentFilter packageIntentFilter = new IntentFilter();
+ packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+ packageIntentFilter.addDataScheme("package");
+ mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter,
null /* broadcastPermission */, mHandler);
mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNetd);
@@ -1914,6 +1922,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
}
newNc.setAdministratorUids(new int[0]);
+ if (!checkAnyPermissionOf(
+ callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) {
+ newNc.setSubIds(Collections.emptySet());
+ }
return newNc;
}
@@ -4052,7 +4064,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
}
- decrementRequestCount(nri);
+ nri.decrementRequestCount();
mNetworkRequestInfoLogs.log("RELEASE " + nri);
if (null != nri.getActiveRequest()) {
@@ -4163,14 +4175,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
? mSystemNetworkRequestCounter : mNetworkRequestCounter;
}
- private void incrementRequestCountOrThrow(NetworkRequestInfo nri) {
- getRequestCounter(nri).incrementCountOrThrow(nri.mUid);
- }
-
- private void decrementRequestCount(NetworkRequestInfo nri) {
- getRequestCounter(nri).decrementCount(nri.mUid);
- }
-
@Override
public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
enforceNetworkStackSettingsOrSetup();
@@ -4981,7 +4985,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
@Override
- public void setGlobalProxy(final ProxyInfo proxyProperties) {
+ public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) {
PermissionUtils.enforceNetworkStackPermission(mContext);
mProxyTracker.setGlobalProxy(proxyProperties);
}
@@ -5326,14 +5330,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private void onUserAdded(UserHandle user) {
+ private void onUserAdded(@NonNull final UserHandle user) {
mPermissionMonitor.onUserAdded(user);
if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
handleSetOemNetworkPreference(mOemNetworkPreferences, null);
}
}
- private void onUserRemoved(UserHandle user) {
+ private void onUserRemoved(@NonNull final UserHandle user) {
mPermissionMonitor.onUserRemoved(user);
// If there was a network preference for this user, remove it.
handleSetProfileNetworkPreference(new ProfileNetworkPreferences.Preference(user, null),
@@ -5343,7 +5347,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ private void onPackageChanged(@NonNull final String packageName) {
+ // This is necessary in case a package is added or removed, but also when it's replaced to
+ // run as a new UID by its manifest rules. Also, if a separate package shares the same UID
+ // as one in the preferences, then it should follow the same routing as that other package,
+ // which means updating the rules is never to be needed in this case (whether it joins or
+ // leaves a UID with a preference).
+ if (isMappedInOemNetworkPreference(packageName)) {
+ handleSetOemNetworkPreference(mOemNetworkPreferences, null);
+ }
+ }
+
+ private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ensureRunningOnConnectivityServiceThread();
@@ -5366,6 +5381,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
};
+ private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ ensureRunningOnConnectivityServiceThread();
+ switch (intent.getAction()) {
+ case Intent.ACTION_PACKAGE_ADDED:
+ case Intent.ACTION_PACKAGE_REMOVED:
+ case Intent.ACTION_PACKAGE_REPLACED:
+ onPackageChanged(intent.getData().getSchemeSpecificPart());
+ break;
+ default:
+ Log.wtf(TAG, "received unexpected intent: " + intent.getAction());
+ }
+ }
+ };
+
private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>();
private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
@@ -5458,6 +5489,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Nullable
final String mCallingAttributionTag;
+ // Counter keeping track of this NRI.
+ final PerUidCounter mPerUidCounter;
+
// Effective UID of this request. This is different from mUid when a privileged process
// files a request on behalf of another UID. This UID is used to determine blocked status,
// UID matching, and so on. mUid above is used for permission checks and to enforce the
@@ -5508,7 +5542,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
mPid = getCallingPid();
mUid = mDeps.getCallingUid();
mAsUid = asUid;
- incrementRequestCountOrThrow(this);
+ mPerUidCounter = getRequestCounter(this);
+ mPerUidCounter.incrementCountOrThrow(mUid);
/**
* Location sensitive data not included in pending intent. Only included in
* {@link NetworkCallback}.
@@ -5540,7 +5575,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
mUid = mDeps.getCallingUid();
mAsUid = asUid;
mPendingIntent = null;
- incrementRequestCountOrThrow(this);
+ mPerUidCounter = getRequestCounter(this);
+ mPerUidCounter.incrementCountOrThrow(mUid);
mCallbackFlags = callbackFlags;
mCallingAttributionTag = callingAttributionTag;
linkDeathRecipient();
@@ -5578,7 +5614,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
mUid = nri.mUid;
mAsUid = nri.mAsUid;
mPendingIntent = nri.mPendingIntent;
- incrementRequestCountOrThrow(this);
+ mPerUidCounter = getRequestCounter(this);
+ mPerUidCounter.incrementCountOrThrow(mUid);
mCallbackFlags = nri.mCallbackFlags;
mCallingAttributionTag = nri.mCallingAttributionTag;
linkDeathRecipient();
@@ -5610,6 +5647,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
return Collections.unmodifiableList(tempRequests);
}
+ void decrementRequestCount() {
+ mPerUidCounter.decrementCount(mUid);
+ }
+
void linkDeathRecipient() {
if (null != mBinder) {
try {
@@ -5667,6 +5708,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
"Insufficient permissions to request a specific signal strength");
}
mAppOpsManager.checkPackage(callerUid, callerPackageName);
+
+ if (!nc.getSubIds().isEmpty()) {
+ enforceNetworkFactoryPermission();
+ }
}
private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) {
@@ -6188,6 +6233,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
@NonNull
private ProfileNetworkPreferences mProfileNetworkPreferences = new ProfileNetworkPreferences();
+ /**
+ * Determine whether a given package has a mapping in the current OemNetworkPreferences.
+ * @param packageName the package name to check existence of a mapping for.
+ * @return true if a mapping exists, false otherwise
+ */
+ private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) {
+ return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName);
+ }
+
// The always-on request for an Internet-capable network that apps without a specific default
// fall back to.
@VisibleForTesting
@@ -6208,7 +6262,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
* @return the NetworkRequestInfo tracking the given uid.
*/
@NonNull
- private NetworkRequestInfo getDefaultRequestTrackingUid(@NonNull final int uid) {
+ private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) {
for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
if (nri == mDefaultRequest) {
continue;
@@ -6726,7 +6780,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mDeps.reportNetworkInterfaceForTransports(mContext, iface,
caps.getTransportTypes());
} catch (Exception e) {
- loge("Exception adding interface: " + e);
+ logw("Exception adding interface: " + e);
}
}
}
@@ -8875,7 +8929,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Decrement the reference count for this NetworkRequestInfo. The reference count is
// incremented when the NetworkRequestInfo is created as part of
// enforceRequestCountLimit().
- decrementRequestCount(nri);
+ nri.decrementRequestCount();
return;
}
@@ -8941,7 +8995,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Decrement the reference count for this NetworkRequestInfo. The reference count is
// incremented when the NetworkRequestInfo is created as part of
// enforceRequestCountLimit().
- decrementRequestCount(nri);
+ nri.decrementRequestCount();
iCb.unlinkToDeath(cbInfo, 0);
}
@@ -9517,14 +9571,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
throw new IllegalArgumentException("Must explicitly specify a user handle ("
+ "UserHandle.CURRENT not supported)");
}
- final UserManager um;
- try {
- um = mContext.createContextAsUser(profile, 0 /* flags */)
- .getSystemService(UserManager.class);
- } catch (IllegalStateException e) {
- throw new IllegalArgumentException("Profile does not exist");
- }
- if (!um.isManagedProfile()) {
+ final UserManager um = mContext.getSystemService(UserManager.class);
+ if (!um.isManagedProfile(profile.getIdentifier())) {
throw new IllegalArgumentException("Profile must be a managed profile");
}
// Strictly speaking, mOemNetworkPreferences should only be touched on the
@@ -9691,7 +9739,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(preference);
replaceDefaultNetworkRequestsForPreference(nris);
mOemNetworkPreferences = preference;
- // TODO http://b/176496396 persist data to shared preferences.
if (null != listener) {
try {
@@ -9848,7 +9895,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
// packages are sent on a network preference as the system will watch for
// package installations associated with this network preference and update
// accordingly. This is done so as to minimize race conditions on app install.
- // TODO b/177092163 add app install watching.
continue;
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 09f4c221f3fe..f5918025db0b 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -249,6 +249,8 @@ class StorageManagerService extends IStorageManager.Stub
@Override
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
mStorageManagerService.mCurrentUserId = to.getUserIdentifier();
+ // To reset public volume mounts
+ mStorageManagerService.onUserSwitching(mStorageManagerService.mCurrentUserId);
}
@Override
@@ -1218,6 +1220,28 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ private void onUserSwitching(int userId) {
+ boolean reset = false;
+ List<VolumeInfo> volumesToRemount = new ArrayList<>();
+ synchronized (mLock) {
+ for (int i = 0; i < mVolumes.size(); i++) {
+ final VolumeInfo vol = mVolumes.valueAt(i);
+ if (!vol.isPrimary() && vol.isMountedWritable() && vol.isVisible()
+ && vol.getMountUserId() != mCurrentUserId) {
+ // If there's a visible secondary volume mounted,
+ // we need to update the currentUserId and remount
+ vol.mountUserId = mCurrentUserId;
+ volumesToRemount.add(vol);
+ }
+ }
+ }
+
+ for (VolumeInfo vol : volumesToRemount) {
+ mHandler.obtainMessage(H_VOLUME_UNMOUNT, vol).sendToTarget();
+ mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
+ }
+ }
+
private boolean supportsBlockCheckpoint() throws RemoteException {
enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
return mVold.supportsBlockCheckpoint();
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index ed579f2df4fc..ed77147b6a97 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
@@ -35,7 +37,9 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
+import android.net.Network;
import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
import android.net.vcn.IVcnManagementService;
import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -161,6 +165,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
@NonNull private final VcnContext mVcnContext;
@NonNull private final BroadcastReceiver mPkgChangeReceiver;
+ @NonNull
+ private final TrackingNetworkCallback mTrackingNetworkCallback = new TrackingNetworkCallback();
+
/** Can only be assigned when {@link #systemReady()} is called, since it uses AppOpsManager. */
@Nullable private LocationPermissionChecker mLocationPermissionChecker;
@@ -356,6 +363,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
public void systemReady() {
mContext.getSystemService(ConnectivityManager.class)
.registerNetworkProvider(mNetworkProvider);
+ mContext.getSystemService(ConnectivityManager.class)
+ .registerNetworkCallback(
+ new NetworkRequest.Builder().clearCapabilities().build(),
+ mTrackingNetworkCallback);
mTelephonySubscriptionTracker.register();
mLocationPermissionChecker = mDeps.newLocationPermissionChecker(mVcnContext.getContext());
}
@@ -530,16 +541,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
if (mVcns.containsKey(subscriptionGroup)) {
final Vcn vcn = mVcns.get(subscriptionGroup);
- final int status = vcn.getStatus();
vcn.updateConfig(config);
-
- // TODO(b/183174340): Remove this once opportunistic-safe-mode is supported
- // Only notify VcnStatusCallbacks if this VCN was previously in Safe Mode
- if (status == VCN_STATUS_CODE_SAFE_MODE) {
- // TODO(b/181789060): invoke asynchronously after Vcn notifies through VcnCallback
- notifyAllPermissionedStatusCallbacksLocked(
- subscriptionGroup, VCN_STATUS_CODE_ACTIVE);
- }
} else {
startVcnLocked(subscriptionGroup, config);
}
@@ -791,8 +793,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
}
+ final NetworkCapabilities result = ncBuilder.build();
return new VcnUnderlyingNetworkPolicy(
- false /* isTearDownRequested */, ncBuilder.build());
+ mTrackingNetworkCallback.requiresRestartForCarrierWifi(result), result);
});
}
@@ -928,8 +931,8 @@ public class VcnManagementService extends IVcnManagementService.Stub {
// TODO(b/180452282): Make name more generic and implement directly with VcnManagementService
/** Callback for Vcn signals sent up to VcnManagementService. */
public interface VcnCallback {
- /** Called by a Vcn to signal that it has entered safe mode. */
- void onEnteredSafeMode();
+ /** Called by a Vcn to signal that its safe mode status has changed. */
+ void onSafeModeStatusChanged(boolean isInSafeMode);
/** Called by a Vcn to signal that an error occurred. */
void onGatewayConnectionError(
@@ -939,6 +942,49 @@ public class VcnManagementService extends IVcnManagementService.Stub {
@Nullable String exceptionMessage);
}
+ /**
+ * TrackingNetworkCallback tracks all active networks
+ *
+ * <p>This is used to ensure that no underlying networks have immutable capabilities changed
+ * without requiring a Network restart.
+ */
+ private class TrackingNetworkCallback extends ConnectivityManager.NetworkCallback {
+ private final Map<Network, NetworkCapabilities> mCaps = new ArrayMap<>();
+
+ @Override
+ public void onCapabilitiesChanged(Network network, NetworkCapabilities caps) {
+ synchronized (mCaps) {
+ mCaps.put(network, caps);
+ }
+ }
+
+ @Override
+ public void onLost(Network network) {
+ synchronized (mCaps) {
+ mCaps.remove(network);
+ }
+ }
+
+ private boolean requiresRestartForCarrierWifi(NetworkCapabilities caps) {
+ if (!caps.hasTransport(TRANSPORT_WIFI) || caps.getSubIds() == null) {
+ return false;
+ }
+
+ synchronized (mCaps) {
+ for (NetworkCapabilities existing : mCaps.values()) {
+ if (existing.hasTransport(TRANSPORT_WIFI)
+ && caps.getSubIds().equals(existing.getSubIds())) {
+ // Restart if any immutable capabilities have changed
+ return existing.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ != caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED);
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+
/** VcnCallbackImpl for Vcn signals sent up to VcnManagementService. */
private class VcnCallbackImpl implements VcnCallback {
@NonNull private final ParcelUuid mSubGroup;
@@ -948,15 +994,18 @@ public class VcnManagementService extends IVcnManagementService.Stub {
}
@Override
- public void onEnteredSafeMode() {
+ public void onSafeModeStatusChanged(boolean isInSafeMode) {
synchronized (mLock) {
// Ignore if this subscription group doesn't exist anymore
if (!mVcns.containsKey(mSubGroup)) {
return;
}
+ final int status =
+ isInSafeMode ? VCN_STATUS_CODE_SAFE_MODE : VCN_STATUS_CODE_ACTIVE;
+
notifyAllPolicyListenersLocked();
- notifyAllPermissionedStatusCallbacksLocked(mSubGroup, VCN_STATUS_CODE_SAFE_MODE);
+ notifyAllPermissionedStatusCallbacksLocked(mSubGroup, status);
}
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 1839e2a9cee4..e4cb15fe8d56 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -23,6 +23,8 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ApplicationExitInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.Debug;
import android.os.Handler;
import android.os.Message;
@@ -80,6 +82,8 @@ public final class CachedAppOptimizer {
"compact_full_delta_rss_throttle_kb";
@VisibleForTesting static final String KEY_COMPACT_PROC_STATE_THROTTLE =
"compact_proc_state_throttle";
+ @VisibleForTesting static final String KEY_FREEZER_DEBOUNCE_TIMEOUT =
+ "freeze_debounce_timeout";
// Phenotype sends int configurations and we map them to the strings we'll use on device,
// preventing a weird string value entering the kernel.
@@ -116,6 +120,10 @@ public final class CachedAppOptimizer {
// Format of this string should be a comma separated list of integers.
@VisibleForTesting static final String DEFAULT_COMPACT_PROC_STATE_THROTTLE =
String.valueOf(ActivityManager.PROCESS_STATE_RECEIVER);
+ @VisibleForTesting static final long DEFAULT_FREEZER_DEBOUNCE_TIMEOUT = 600_000L;
+
+ @VisibleForTesting static final Uri CACHED_APP_FREEZER_ENABLED_URI = Settings.Global.getUriFor(
+ Settings.Global.CACHED_APPS_FREEZER_ENABLED);
@VisibleForTesting
interface PropertyChangedCallbackForTest {
@@ -141,9 +149,6 @@ public final class CachedAppOptimizer {
static final int SET_FROZEN_PROCESS_MSG = 3;
static final int REPORT_UNFREEZE_MSG = 4;
- //TODO:change this static definition into a configurable flag.
- static final long FREEZE_TIMEOUT_MS = 600000;
-
static final int DO_FREEZE = 1;
static final int REPORT_UNFREEZE = 2;
@@ -198,6 +203,8 @@ public final class CachedAppOptimizer {
updateMinOomAdjThrottle();
} else if (KEY_COMPACT_THROTTLE_MAX_OOM_ADJ.equals(name)) {
updateMaxOomAdjThrottle();
+ } else if (KEY_FREEZER_DEBOUNCE_TIMEOUT.equals(name)) {
+ updateFreezerDebounceTimeout();
}
}
}
@@ -207,6 +214,23 @@ public final class CachedAppOptimizer {
}
};
+ private final class SettingsContentObserver extends ContentObserver {
+ SettingsContentObserver() {
+ super(mAm.mHandler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (CACHED_APP_FREEZER_ENABLED_URI.equals(uri)) {
+ synchronized (mPhenotypeFlagLock) {
+ updateUseFreezer();
+ }
+ }
+ }
+ }
+
+ private final SettingsContentObserver mSettingsObserver;
+
private final Object mPhenotypeFlagLock = new Object();
// Configured by phenotype. Updates from the server take effect immediately.
@@ -259,6 +283,8 @@ public final class CachedAppOptimizer {
@GuardedBy("mProcLock")
private boolean mFreezerOverride = false;
+ @VisibleForTesting volatile long mFreezerDebounceTimeout = DEFAULT_FREEZER_DEBOUNCE_TIMEOUT;
+
// Maps process ID to last compaction statistics for processes that we've fully compacted. Used
// when evaluating throttles that we only consider for "full" compaction, so we don't store
// data for "some" compactions. Uses LinkedHashMap to ensure insertion order is kept and
@@ -293,6 +319,7 @@ public final class CachedAppOptimizer {
mProcStateThrottle = new HashSet<>();
mProcessDependencies = processDependencies;
mTestCallback = callback;
+ mSettingsObserver = new SettingsContentObserver();
}
/**
@@ -303,6 +330,8 @@ public final class CachedAppOptimizer {
// TODO: initialize flags to default and only update them if values are set in DeviceConfig
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ActivityThread.currentApplication().getMainExecutor(), mOnFlagsChangedListener);
+ mAm.mContext.getContentResolver().registerContentObserver(
+ CACHED_APP_FREEZER_ENABLED_URI, false, mSettingsObserver);
synchronized (mPhenotypeFlagLock) {
updateUseCompaction();
updateCompactionActions();
@@ -315,6 +344,7 @@ public final class CachedAppOptimizer {
updateUseFreezer();
updateMinOomAdjThrottle();
updateMaxOomAdjThrottle();
+ updateFreezerDebounceTimeout();
}
}
@@ -367,6 +397,7 @@ public final class CachedAppOptimizer {
+ " processes.");
pw.println(" " + KEY_USE_FREEZER + "=" + mUseFreezer);
pw.println(" " + KEY_FREEZER_STATSD_SAMPLE_RATE + "=" + mFreezerStatsdSampleRate);
+ pw.println(" " + KEY_FREEZER_DEBOUNCE_TIMEOUT + "=" + mFreezerDebounceTimeout);
if (DEBUG_COMPACTION) {
for (Map.Entry<Integer, LastCompactionStats> entry
: mLastCompactionStats.entrySet()) {
@@ -627,21 +658,28 @@ public final class CachedAppOptimizer {
mUseFreezer = isFreezerSupported();
}
- if (mUseFreezer && mFreezeHandler == null) {
- Slog.d(TAG_AM, "Freezer enabled");
- enableFreezer(true);
+ final boolean useFreezer = mUseFreezer;
+ // enableFreezer() would need the global ActivityManagerService lock, post it.
+ mAm.mHandler.post(() -> {
+ if (useFreezer) {
+ Slog.d(TAG_AM, "Freezer enabled");
+ enableFreezer(true);
- if (!mCachedAppOptimizerThread.isAlive()) {
- mCachedAppOptimizerThread.start();
- }
+ if (!mCachedAppOptimizerThread.isAlive()) {
+ mCachedAppOptimizerThread.start();
+ }
- mFreezeHandler = new FreezeHandler();
+ if (mFreezeHandler == null) {
+ mFreezeHandler = new FreezeHandler();
+ }
- Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(),
- Process.THREAD_GROUP_SYSTEM);
- } else {
- enableFreezer(false);
- }
+ Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(),
+ Process.THREAD_GROUP_SYSTEM);
+ } else {
+ Slog.d(TAG_AM, "Freezer disabled");
+ enableFreezer(false);
+ }
+ });
}
@GuardedBy("mPhenotypeFlagLock")
@@ -794,6 +832,16 @@ public final class CachedAppOptimizer {
}
}
+ @GuardedBy("mPhenotypeFlagLock")
+ private void updateFreezerDebounceTimeout() {
+ mFreezerDebounceTimeout = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_FREEZER_DEBOUNCE_TIMEOUT, DEFAULT_FREEZER_DEBOUNCE_TIMEOUT);
+
+ if (mFreezerDebounceTimeout < 0) {
+ mFullDeltaRssThrottleKb = DEFAULT_FREEZER_DEBOUNCE_TIMEOUT;
+ }
+ }
+
private boolean parseProcStateThrottle(String procStateThrottleString) {
String[] procStates = TextUtils.split(procStateThrottleString, ",");
mProcStateThrottle.clear();
@@ -818,7 +866,7 @@ public final class CachedAppOptimizer {
return COMPACT_ACTION_STRING[action];
}
- // This will ensure app will be out of the freezer for at least FREEZE_TIMEOUT_MS
+ // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout.
@GuardedBy("mAm")
void unfreezeTemporarily(ProcessRecord app) {
if (mUseFreezer) {
@@ -838,7 +886,7 @@ public final class CachedAppOptimizer {
mFreezeHandler.sendMessageDelayed(
mFreezeHandler.obtainMessage(
SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app),
- FREEZE_TIMEOUT_MS);
+ mFreezerDebounceTimeout);
}
@GuardedBy({"mAm", "mProcLock"})
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 8ad11d161cdc..c8721cc209ce 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1864,6 +1864,7 @@ public final class OomAdjuster {
}
int capabilityFromFGS = 0; // capability from foreground service.
+ boolean scheduleLikeTopApp = false;
for (int is = psr.numberOfRunningServices() - 1;
is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
@@ -1975,6 +1976,8 @@ public final class OomAdjuster {
int clientAdj = cstate.getCurRawAdj();
int clientProcState = cstate.getCurRawProcState();
+ final boolean clientIsSystem = clientProcState < PROCESS_STATE_TOP;
+
// pass client's mAllowStartFgs to the app if client is not persistent process.
if (cstate.getAllowedStartFgs() != REASON_DENIED
&& cstate.getMaxAdj() >= ProcessList.FOREGROUND_APP_ADJ) {
@@ -2014,6 +2017,10 @@ public final class OomAdjuster {
}
String adjType = null;
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
+ // Similar to BIND_WAIVE_PRIORITY, keep it unfrozen.
+ if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) {
+ app.mOptRecord.setShouldNotFreeze(true);
+ }
// Not doing bind OOM management, so treat
// this guy more like a started service.
if (state.hasShownUi() && !state.getCachedIsHomeProcess()) {
@@ -2170,8 +2177,10 @@ public final class OomAdjuster {
}
if (schedGroup < ProcessList.SCHED_GROUP_TOP_APP
- && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) {
+ && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0
+ && clientIsSystem) {
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+ scheduleLikeTopApp = true;
}
if (!trackedProcState) {
@@ -2438,7 +2447,8 @@ public final class OomAdjuster {
// Put bound foreground services in a special sched group for additional
// restrictions on screen off
if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE
- && mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE) {
+ && mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
+ && !scheduleLikeTopApp) {
if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
}
diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
index f4ce7230f72a..026c1d3fd204 100644
--- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
+++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
@@ -28,6 +29,9 @@ final class ProcessCachedOptimizerRecord {
private final ActivityManagerGlobalLock mProcLock;
+ @VisibleForTesting
+ static final String IS_FROZEN = "isFrozen";
+
/**
* The last time that this process was compacted.
*/
@@ -169,5 +173,6 @@ final class ProcessCachedOptimizerRecord {
void dump(PrintWriter pw, String prefix, long nowUptime) {
pw.print(prefix); pw.print("lastCompactTime="); pw.print(mLastCompactTime);
pw.print(" lastCompactAction="); pw.println(mLastCompactAction);
+ pw.print(" " + IS_FROZEN + "="); pw.println(mFrozen);
}
}
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index 232005b7559b..f2e422d3ee7c 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -44,6 +44,7 @@ import android.os.FileUtils;
import android.os.Process;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
+import android.util.AtomicFile;
import android.util.Slog;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
@@ -83,7 +84,7 @@ import java.util.List;
*/
final class DiscreteRegistry {
- static final String TIMELINE_FILE_SUFFIX = "tl";
+ static final String DISCRETE_HISTORY_FILE_SUFFIX = "tl";
private static final String TAG = DiscreteRegistry.class.getSimpleName();
private static final String PROPERTY_DISCRETE_HISTORY_CUTOFF = "discrete_history_cutoff_millis";
@@ -194,17 +195,6 @@ final class DiscreteRegistry {
}
}
- private void createDiscreteAccessDir() {
- if (!mDiscreteAccessDir.exists()) {
- if (!mDiscreteAccessDir.mkdirs()) {
- Slog.e(TAG, "Failed to create DiscreteRegistry directory");
- }
- FileUtils.setPermissions(mDiscreteAccessDir.getPath(),
- FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
- }
- }
-
- /* can be called only after HistoricalRegistry.isPersistenceInitialized() check */
void recordDiscreteAccess(int uid, String packageName, int op, @Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, long accessTime,
long accessDuration) {
@@ -220,80 +210,34 @@ final class DiscreteRegistry {
void writeAndClearAccessHistory() {
synchronized (mOnDiskLock) {
if (mDiscreteAccessDir == null) {
- Slog.e(TAG, "State not saved - persistence not initialized.");
+ Slog.d(TAG, "State not saved - persistence not initialized.");
return;
}
- final File[] files = mDiscreteAccessDir.listFiles();
- if (files != null && files.length > 0) {
- for (File f : files) {
- final String fileName = f.getName();
- if (!fileName.endsWith(TIMELINE_FILE_SUFFIX)) {
- continue;
- }
- try {
- long timestamp = Long.valueOf(fileName.substring(0,
- fileName.length() - TIMELINE_FILE_SUFFIX.length()));
- if (Instant.now().minus(sDiscreteHistoryCutoff,
- ChronoUnit.MILLIS).toEpochMilli() > timestamp) {
- f.delete();
- Slog.e(TAG, "Deleting file " + fileName);
-
- }
- } catch (Throwable t) {
- Slog.e(TAG, "Error while cleaning timeline files: " + t.getMessage() + " "
- + t.getStackTrace());
- }
- }
- }
DiscreteOps discreteOps;
synchronized (mInMemoryLock) {
discreteOps = mDiscreteOps;
mDiscreteOps = new DiscreteOps();
mCachedOps = null;
}
- if (discreteOps.isEmpty()) {
- return;
- }
- long currentTimeStamp = Instant.now().toEpochMilli();
- try {
- final File file = new File(mDiscreteAccessDir,
- currentTimeStamp + TIMELINE_FILE_SUFFIX);
- discreteOps.writeToFile(file);
- } catch (Throwable t) {
- Slog.e(TAG,
- "Error writing timeline state: " + t.getMessage() + " "
- + Arrays.toString(t.getStackTrace()));
+ deleteOldDiscreteHistoryFilesLocked();
+ if (!discreteOps.isEmpty()) {
+ persistDiscreteOpsLocked(discreteOps);
}
}
}
- void getHistoricalDiscreteOps(AppOpsManager.HistoricalOps result, long beginTimeMillis,
- long endTimeMillis, @AppOpsManager.HistoricalOpsRequestFilter int filter, int uidFilter,
+ void addFilteredDiscreteOpsToHistoricalOps(AppOpsManager.HistoricalOps result,
+ long beginTimeMillis, long endTimeMillis,
+ @AppOpsManager.HistoricalOpsRequestFilter int filter, int uidFilter,
@Nullable String packageNameFilter, @Nullable String[] opNamesFilter,
@Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) {
- DiscreteOps discreteOps = getAndCacheDiscreteOps();
+ DiscreteOps discreteOps = getAllDiscreteOps();
discreteOps.filter(beginTimeMillis, endTimeMillis, filter, uidFilter, packageNameFilter,
opNamesFilter, attributionTagFilter, flagsFilter);
discreteOps.applyToHistoricalOps(result);
return;
}
- private DiscreteOps getAndCacheDiscreteOps() {
- DiscreteOps discreteOps = new DiscreteOps();
-
- synchronized (mOnDiskLock) {
- synchronized (mInMemoryLock) {
- discreteOps.merge(mDiscreteOps);
- }
- if (mCachedOps == null) {
- mCachedOps = new DiscreteOps();
- readDiscreteOpsFromDisk(mCachedOps);
- }
- discreteOps.merge(mCachedOps);
- }
- return discreteOps;
- }
-
private void readDiscreteOpsFromDisk(DiscreteOps discreteOps) {
synchronized (mOnDiskLock) {
long beginTimeMillis = Instant.now().minus(sDiscreteHistoryCutoff,
@@ -303,11 +247,11 @@ final class DiscreteRegistry {
if (files != null && files.length > 0) {
for (File f : files) {
final String fileName = f.getName();
- if (!fileName.endsWith(TIMELINE_FILE_SUFFIX)) {
+ if (!fileName.endsWith(DISCRETE_HISTORY_FILE_SUFFIX)) {
continue;
}
long timestamp = Long.valueOf(fileName.substring(0,
- fileName.length() - TIMELINE_FILE_SUFFIX.length()));
+ fileName.length() - DISCRETE_HISTORY_FILE_SUFFIX.length()));
if (timestamp < beginTimeMillis) {
continue;
}
@@ -322,8 +266,19 @@ final class DiscreteRegistry {
synchronized (mInMemoryLock) {
mDiscreteOps = new DiscreteOps();
}
- FileUtils.deleteContentsAndDir(mDiscreteAccessDir);
- createDiscreteAccessDir();
+ clearOnDiskHistoryLocked();
+ }
+ }
+
+ void clearHistory(int uid, String packageName) {
+ synchronized (mOnDiskLock) {
+ DiscreteOps discreteOps;
+ synchronized (mInMemoryLock) {
+ discreteOps = getAllDiscreteOps();
+ clearHistory();
+ }
+ discreteOps.clearHistory(uid, packageName);
+ persistDiscreteOpsLocked(discreteOps);
}
}
@@ -332,7 +287,7 @@ final class DiscreteRegistry {
@AppOpsManager.HistoricalOpsRequestFilter int filter, int dumpOp,
@NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix,
int nDiscreteOps) {
- DiscreteOps discreteOps = getAndCacheDiscreteOps();
+ DiscreteOps discreteOps = getAllDiscreteOps();
String[] opNamesFilter = dumpOp == OP_NONE ? null
: new String[]{AppOpsManager.opToPublicName(dumpOp)};
discreteOps.filter(0, Instant.now().toEpochMilli(), filter, uidFilter, packageNameFilter,
@@ -340,17 +295,26 @@ final class DiscreteRegistry {
discreteOps.dump(pw, sdf, date, prefix, nDiscreteOps);
}
- public static boolean isDiscreteOp(int op, int uid, @AppOpsManager.OpFlags int flags) {
- if (!ArrayUtils.contains(sDiscreteOps, op)) {
- return false;
- }
- if (uid < Process.FIRST_APPLICATION_UID) {
- return false;
- }
- if ((flags & (sDiscreteFlags)) == 0) {
- return false;
+ private void clearOnDiskHistoryLocked() {
+ mCachedOps = null;
+ FileUtils.deleteContentsAndDir(mDiscreteAccessDir);
+ createDiscreteAccessDir();
+ }
+
+ private DiscreteOps getAllDiscreteOps() {
+ DiscreteOps discreteOps = new DiscreteOps();
+
+ synchronized (mOnDiskLock) {
+ synchronized (mInMemoryLock) {
+ discreteOps.merge(mDiscreteOps);
+ }
+ if (mCachedOps == null) {
+ mCachedOps = new DiscreteOps();
+ readDiscreteOpsFromDisk(mCachedOps);
+ }
+ discreteOps.merge(mCachedOps);
+ return discreteOps;
}
- return true;
}
private final class DiscreteOps {
@@ -399,6 +363,15 @@ final class DiscreteRegistry {
}
}
+ private void clearHistory(int uid, String packageName) {
+ if (mUids.containsKey(uid)) {
+ mUids.get(uid).clearPackage(packageName);
+ if (mUids.get(uid).isEmpty()) {
+ mUids.remove(uid);
+ }
+ }
+ }
+
private void applyToHistoricalOps(AppOpsManager.HistoricalOps result) {
int nUids = mUids.size();
for (int i = 0; i < nUids; i++) {
@@ -406,8 +379,7 @@ final class DiscreteRegistry {
}
}
- private void writeToFile(File f) throws Exception {
- FileOutputStream stream = new FileOutputStream(f);
+ private void writeToStream(FileOutputStream stream) throws Exception {
TypedXmlSerializer out = Xml.resolveSerializer(stream);
out.startDocument(null, true);
@@ -423,7 +395,6 @@ final class DiscreteRegistry {
}
out.endTag(null, TAG_HISTORY);
out.endDocument();
- stream.close();
}
private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
@@ -475,6 +446,60 @@ final class DiscreteRegistry {
}
}
+ private void createDiscreteAccessDir() {
+ if (!mDiscreteAccessDir.exists()) {
+ if (!mDiscreteAccessDir.mkdirs()) {
+ Slog.e(TAG, "Failed to create DiscreteRegistry directory");
+ }
+ FileUtils.setPermissions(mDiscreteAccessDir.getPath(),
+ FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
+ }
+ }
+
+ private void persistDiscreteOpsLocked(DiscreteOps discreteOps) {
+ long currentTimeStamp = Instant.now().toEpochMilli();
+ final AtomicFile file = new AtomicFile(new File(mDiscreteAccessDir,
+ currentTimeStamp + DISCRETE_HISTORY_FILE_SUFFIX));
+ FileOutputStream stream = null;
+ try {
+ stream = file.startWrite();
+ discreteOps.writeToStream(stream);
+ file.finishWrite(stream);
+ } catch (Throwable t) {
+ Slog.e(TAG,
+ "Error writing timeline state: " + t.getMessage() + " "
+ + Arrays.toString(t.getStackTrace()));
+ if (stream != null) {
+ file.failWrite(stream);
+ }
+ }
+ }
+
+ private void deleteOldDiscreteHistoryFilesLocked() {
+ final File[] files = mDiscreteAccessDir.listFiles();
+ if (files != null && files.length > 0) {
+ for (File f : files) {
+ final String fileName = f.getName();
+ if (!fileName.endsWith(DISCRETE_HISTORY_FILE_SUFFIX)) {
+ continue;
+ }
+ try {
+ long timestamp = Long.valueOf(fileName.substring(0,
+ fileName.length() - DISCRETE_HISTORY_FILE_SUFFIX.length()));
+ if (Instant.now().minus(sDiscreteHistoryCutoff,
+ ChronoUnit.MILLIS).toEpochMilli() > timestamp) {
+ f.delete();
+ Slog.e(TAG, "Deleting file " + fileName);
+
+ }
+ } catch (Throwable t) {
+ Slog.e(TAG, "Error while cleaning timeline files: " + t.getMessage() + " "
+ + t.getStackTrace());
+ }
+ }
+ }
+ }
+
private void createDiscreteAccessDirLocked() {
if (!mDiscreteAccessDir.exists()) {
if (!mDiscreteAccessDir.mkdirs()) {
@@ -524,6 +549,10 @@ final class DiscreteRegistry {
}
}
+ private void clearPackage(String packageName) {
+ mPackages.remove(packageName);
+ }
+
void addDiscreteAccess(int op, @NonNull String packageName, @Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState,
long accessTime, long accessDuration) {
@@ -934,5 +963,25 @@ final class DiscreteRegistry {
}
return result;
}
+
+ private static boolean isDiscreteOp(int op, int uid, @AppOpsManager.OpFlags int flags) {
+ if (!ArrayUtils.contains(sDiscreteOps, op)) {
+ return false;
+ }
+ if (!isDiscreteUid(uid)) {
+ return false;
+ }
+ if ((flags & (sDiscreteFlags)) == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean isDiscreteUid(int uid) {
+ if (uid < Process.FIRST_APPLICATION_UID) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 9ff54926df3a..fcf82faca850 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -394,8 +394,8 @@ final class HistoricalRegistry {
}
if ((historyFlags & HISTORY_FLAG_DISCRETE) != 0) {
- mDiscreteRegistry.getHistoricalDiscreteOps(result, beginTimeMillis, endTimeMillis,
- filter, uid, packageName, opNames, attributionTag,
+ mDiscreteRegistry.addFilteredDiscreteOpsToHistoricalOps(result, beginTimeMillis,
+ endTimeMillis, filter, uid, packageName, opNames, attributionTag,
flags);
}
@@ -428,8 +428,8 @@ final class HistoricalRegistry {
inMemoryAdjEndTimeMillis);
if ((historyFlags & HISTORY_FLAG_DISCRETE) != 0) {
- mDiscreteRegistry.getHistoricalDiscreteOps(result, beginTimeMillis, endTimeMillis,
- filter, uid, packageName, opNames, attributionTag, flags);
+ mDiscreteRegistry.addFilteredDiscreteOpsToHistoricalOps(result, beginTimeMillis,
+ endTimeMillis, filter, uid, packageName, opNames, attributionTag, flags);
}
if ((historyFlags & HISTORY_FLAG_AGGREGATE) != 0) {
@@ -645,6 +645,7 @@ final class HistoricalRegistry {
mPersistence.clearHistoryDLocked(uid, packageName);
}
}
+ mDiscreteRegistry.clearHistory(uid, packageName);
}
void writeAndClearDiscreteHistory() {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
index a5e6ddb81669..ca9be67914e3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
@@ -48,7 +48,7 @@ import java.util.Set;
*/
public class BiometricTestSessionImpl extends ITestSession.Stub {
- private static final String TAG = "BiometricTestSessionImpl";
+ private static final String TAG = "face/aidl/BiometricTestSessionImpl";
@NonNull private final Context mContext;
private final int mSensorId;
@@ -230,10 +230,12 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
public void cleanupInternalState(int userId) {
Utils.checkPermission(mContext, TEST_BIOMETRIC);
+ Slog.d(TAG, "cleanupInternalState: " + userId);
mProvider.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() {
@Override
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
try {
+ Slog.d(TAG, "onClientStarted: " + clientMonitor);
mCallback.onCleanupStarted(clientMonitor.getTargetUserId());
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
@@ -244,6 +246,7 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
boolean success) {
try {
+ Slog.d(TAG, "onClientFinished: " + clientMonitor);
mCallback.onCleanupFinished(clientMonitor.getTargetUserId());
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index a9be8e1a707b..4fb71ffdaab0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -49,7 +49,6 @@ import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.InvalidationRequesterClient;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.PerformanceTracker;
@@ -443,7 +442,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
mContext.getOpPackageName(), sensorId, enrolledList,
FaceUtils.getInstance(sensorId),
mSensors.get(sensorId).getAuthenticatorIds());
- scheduleForSensor(sensorId, client);
+ scheduleForSensor(sensorId, client, callback);
});
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
index 20b32543f7a0..1c88d67cc96c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
@@ -45,7 +45,7 @@ import java.util.Set;
*/
class BiometricTestSessionImpl extends ITestSession.Stub {
- private static final String TAG = "BiometricTestSessionImpl";
+ private static final String TAG = "fp/aidl/BiometricTestSessionImpl";
@NonNull private final Context mContext;
private final int mSensorId;
@@ -198,10 +198,12 @@ class BiometricTestSessionImpl extends ITestSession.Stub {
public void cleanupInternalState(int userId) {
Utils.checkPermission(mContext, TEST_BIOMETRIC);
+ Slog.d(TAG, "cleanupInternalState: " + userId);
mProvider.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() {
@Override
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
try {
+ Slog.d(TAG, "onClientStarted: " + clientMonitor);
mCallback.onCleanupStarted(clientMonitor.getTargetUserId());
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
@@ -212,6 +214,7 @@ class BiometricTestSessionImpl extends ITestSession.Stub {
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
boolean success) {
try {
+ Slog.d(TAG, "onClientFinished: " + clientMonitor);
mCallback.onCleanupFinished(clientMonitor.getTargetUserId());
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 24e867afedd7..01fd6419aee0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -432,7 +432,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
mContext.getOpPackageName(), sensorId, enrolledList,
FingerprintUtils.getInstance(sensorId),
mSensors.get(sensorId).getAuthenticatorIds());
- scheduleForSensor(sensorId, client);
+ scheduleForSensor(sensorId, client, callback);
});
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index e149ca9428dd..243cc7cd9b00 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -119,6 +119,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
private int mCurrentUserId = UserHandle.USER_NULL;
private final boolean mIsUdfps;
private final int mSensorId;
+ private boolean mIsPowerbuttonFps;
private final class BiometricTaskStackListener extends TaskStackListener {
@Override
@@ -345,9 +346,18 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
mIsUdfps = !ArrayUtils.isEmpty(
mContext.getResources().getIntArray(R.array.config_udfps_sensor_props));
- final @FingerprintSensorProperties.SensorType int sensorType =
- mIsUdfps ? FingerprintSensorProperties.TYPE_UDFPS_OPTICAL
- : FingerprintSensorProperties.TYPE_REAR;
+ // config_is_powerbutton_fps indicates whether device has a power button fingerprint sensor.
+ mIsPowerbuttonFps = mContext.getResources().getBoolean(R.bool.config_is_powerbutton_fps);
+
+ final @FingerprintSensorProperties.SensorType int sensorType;
+ if (mIsUdfps) {
+ sensorType = FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
+ } else if (mIsPowerbuttonFps) {
+ sensorType = FingerprintSensorProperties.TYPE_POWER_BUTTON;
+ } else {
+ sensorType = FingerprintSensorProperties.TYPE_REAR;
+ }
+
// IBiometricsFingerprint@2.1 does not manage timeout below the HAL, so the Gatekeeper HAT
// cannot be checked
final boolean resetLockoutRequiresHardwareAuthToken = false;
@@ -835,6 +845,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
try {
dump.put("service", TAG);
dump.put("isUdfps", mIsUdfps);
+ dump.put("isPowerbuttonFps", mIsPowerbuttonFps);
JSONArray sets = new JSONArray();
for (UserInfo user : UserManager.get(mContext).getUsers()) {
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index cd2457635932..1bbcedeb0494 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -528,8 +528,13 @@ public class CameraServiceProxy extends SystemService
} catch (RemoteException e) {
Log.e(TAG, "Failed to register task stack listener!");
}
+ }
- CameraStatsJobService.schedule(mContext);
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_BOOT_COMPLETED) {
+ CameraStatsJobService.schedule(mContext);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 820198c285ec..33224f450c8e 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -102,7 +102,6 @@ import android.os.UserManager;
import android.provider.Settings;
import android.security.Credentials;
import android.security.KeyStore2;
-import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyProperties;
import android.system.keystore2.Domain;
import android.system.keystore2.KeyDescriptor;
@@ -2057,10 +2056,6 @@ public class Vpn {
if (alias == null) {
return null;
}
- // If Keystore 2.0 is not enabled the legacy private key prefix is used.
- if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
- return Credentials.USER_PRIVATE_KEY + alias;
- }
final KeyStore2 keystore2 = KeyStore2.getInstance();
KeyDescriptor key = new KeyDescriptor();
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 22a9a47c9651..71a5d1ce972d 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -98,6 +98,7 @@ import android.security.keystore.recovery.KeyChainProtectionParams;
import android.security.keystore.recovery.KeyChainSnapshot;
import android.security.keystore.recovery.RecoveryCertPath;
import android.security.keystore.recovery.WrappedApplicationKey;
+import android.security.keystore2.AndroidKeyStoreProvider;
import android.service.gatekeeper.GateKeeperResponse;
import android.service.gatekeeper.IGateKeeperService;
import android.text.TextUtils;
@@ -261,7 +262,7 @@ public class LockSettingsService extends ILockSettings.Stub {
@Override
public void onStart() {
- android.security.keystore2.AndroidKeyStoreProvider.install();
+ AndroidKeyStoreProvider.install();
mLockSettingsService = new LockSettingsService(getContext());
publishBinderService("lock_settings", mLockSettingsService);
}
@@ -788,10 +789,6 @@ public class LockSettingsService extends ILockSettings.Stub {
// Notify keystore that a new user was added.
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
AndroidKeyStoreMaintenance.onUserAdded(userHandle);
- final KeyStore ks = KeyStore.getInstance();
- final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
- final int parentHandle = parentInfo != null ? parentInfo.id : -1;
- ks.onUserAdded(userHandle, parentHandle);
} else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
mStorage.prefetchUser(userHandle);
@@ -1260,19 +1257,11 @@ public class LockSettingsService extends ILockSettings.Stub {
private void setKeystorePassword(byte[] password, int userHandle) {
AndroidKeyStoreMaintenance.onUserPasswordChanged(userHandle, password);
- final KeyStore ks = KeyStore.getInstance();
- // TODO(b/120484642): Update keystore to accept byte[] passwords
- String passwordString = password == null ? null : new String(password);
- ks.onUserPasswordChanged(userHandle, passwordString);
}
private void unlockKeystore(byte[] password, int userHandle) {
if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
Authorization.onLockScreenEvent(false, userHandle, password);
- // TODO(b/120484642): Update keystore to accept byte[] passwords
- String passwordString = password == null ? null : new String(password);
- final KeyStore ks = KeyStore.getInstance();
- ks.unlock(userHandle, passwordString);
}
@VisibleForTesting /** Note: this method is overridden in unit tests */
@@ -2287,8 +2276,6 @@ public class LockSettingsService extends ILockSettings.Stub {
mStrongAuth.removeUser(userId);
AndroidKeyStoreMaintenance.onUserRemoved(userId);
- final KeyStore ks = KeyStore.getInstance();
- ks.onUserRemoved(userId);
mManagedProfilePasswordCache.removePassword(userId);
gateKeeperClearSecureUserId(userId);
diff --git a/services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java b/services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java
index 7950fcf7234c..fa477c8fd35a 100644
--- a/services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java
+++ b/services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java
@@ -20,10 +20,10 @@ import android.annotation.Nullable;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
-import android.security.keystore.AndroidKeyStoreSpi;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.security.keystore.UserNotAuthenticatedException;
+import android.security.keystore2.AndroidKeyStoreSpi;
import android.util.Slog;
import android.util.SparseArray;
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowKeyStoreManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowKeyStoreManager.java
index bae029c79968..da29368df082 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowKeyStoreManager.java
@@ -16,11 +16,10 @@
package com.android.server.locksettings;
-import android.security.keystore.AndroidKeyStoreSpi;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
-import android.security.keystore2.AndroidKeyStoreProvider;
+import android.security.keystore2.AndroidKeyStoreSpi;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -67,9 +66,7 @@ public class RebootEscrowKeyStoreManager {
KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER);
KeyStore.LoadStoreParameter loadStoreParameter = null;
// Load from the specific namespace if keystore2 is enabled.
- if (AndroidKeyStoreProvider.isInstalled()) {
- loadStoreParameter = new AndroidKeyStoreLoadStoreParameter(KEY_STORE_NAMESPACE);
- }
+ loadStoreParameter = new AndroidKeyStoreLoadStoreParameter(KEY_STORE_NAMESPACE);
keyStore.load(loadStoreParameter);
return (SecretKey) keyStore.getKey(REBOOT_ESCROW_KEY_STORE_ENCRYPTION_KEY_NAME,
null);
@@ -91,9 +88,7 @@ public class RebootEscrowKeyStoreManager {
KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER);
KeyStore.LoadStoreParameter loadStoreParameter = null;
// Load from the specific namespace if keystore2 is enabled.
- if (AndroidKeyStoreProvider.isInstalled()) {
- loadStoreParameter = new AndroidKeyStoreLoadStoreParameter(KEY_STORE_NAMESPACE);
- }
+ loadStoreParameter = new AndroidKeyStoreLoadStoreParameter(KEY_STORE_NAMESPACE);
keyStore.load(loadStoreParameter);
keyStore.deleteEntry(REBOOT_ESCROW_KEY_STORE_ENCRYPTION_KEY_NAME);
} catch (IOException | GeneralSecurityException e) {
@@ -119,9 +114,7 @@ public class RebootEscrowKeyStoreManager {
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE);
// Generate the key with the correct namespace if keystore2 is enabled.
- if (AndroidKeyStoreProvider.isInstalled()) {
- parameterSpecBuilder.setNamespace(KEY_STORE_NAMESPACE);
- }
+ parameterSpecBuilder.setNamespace(KEY_STORE_NAMESPACE);
generator.init(parameterSpecBuilder.build());
return generator.generateKey();
} catch (GeneralSecurityException e) {
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
index 2398f56f847c..8582c67153ae 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
@@ -20,8 +20,6 @@ import static android.security.keystore.recovery.RecoveryController.ERROR_SERVIC
import android.annotation.Nullable;
import android.os.ServiceSpecificException;
-import android.security.Credentials;
-import android.security.KeyStore;
import android.security.KeyStore2;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
@@ -75,13 +73,7 @@ public class ApplicationKeyStorage {
public @Nullable String getGrantAlias(int userId, int uid, String alias) {
Log.i(TAG, String.format(Locale.US, "Get %d/%d/%s", userId, uid, alias));
String keystoreAlias = getInternalAlias(userId, uid, alias);
- if (useKeyStore2()) {
- return makeKeystoreEngineGrantString(uid, keystoreAlias);
- } else {
- // Aliases used by {@link KeyStore} are different than used by public API.
- // {@code USER_PRIVATE_KEY} prefix is used secret keys.
- return KeyStore.getInstance().grant(Credentials.USER_PRIVATE_KEY + keystoreAlias, uid);
- }
+ return makeKeystoreEngineGrantString(uid, keystoreAlias);
}
public void setSymmetricKeyEntry(int userId, int uid, String alias, byte[] secretKey)
@@ -148,9 +140,4 @@ public class ApplicationKeyStorage {
}
return String.format("%s%016X", APPLICATION_KEY_GRANT_PREFIX, key.nspace);
}
-
- private static boolean useKeyStore2() {
- return android.security.keystore2.AndroidKeyStoreProvider.isInstalled();
- }
-
}
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index b85cea7a637d..3d19b70ca95f 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -728,7 +728,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
clientRecord.mGroupId = groupId;
if (groupId != null) {
userRecord.addToGroup(groupId, clientRecord);
- userRecord.mHandler.obtainMessage(UserHandler.MSG_UPDATE_SELECTED_ROUTE, groupId)
+ userRecord.mHandler.obtainMessage(UserHandler.MSG_NOTIFY_GROUP_ROUTE_SELECTED, groupId)
.sendToTarget();
}
}
@@ -809,7 +809,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
if (group != null) {
group.mSelectedRouteId = routeId;
clientRecord.mUserRecord.mHandler.obtainMessage(
- UserHandler.MSG_UPDATE_SELECTED_ROUTE, clientRecord.mGroupId)
+ UserHandler.MSG_NOTIFY_GROUP_ROUTE_SELECTED, clientRecord.mGroupId)
.sendToTarget();
}
}
@@ -1079,7 +1079,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
public static final int MSG_REQUEST_UPDATE_VOLUME = 7;
private static final int MSG_UPDATE_CLIENT_STATE = 8;
private static final int MSG_CONNECTION_TIMED_OUT = 9;
- private static final int MSG_UPDATE_SELECTED_ROUTE = 10;
+ private static final int MSG_NOTIFY_GROUP_ROUTE_SELECTED = 10;
private static final int TIMEOUT_REASON_NOT_AVAILABLE = 1;
private static final int TIMEOUT_REASON_CONNECTION_LOST = 2;
@@ -1156,8 +1156,8 @@ public final class MediaRouterService extends IMediaRouterService.Stub
connectionTimedOut();
break;
}
- case MSG_UPDATE_SELECTED_ROUTE: {
- updateSelectedRoute((String) msg.obj);
+ case MSG_NOTIFY_GROUP_ROUTE_SELECTED: {
+ notifyGroupRouteSelected((String) msg.obj);
break;
}
}
@@ -1483,9 +1483,9 @@ public final class MediaRouterService extends IMediaRouterService.Stub
}
}
- private void updateSelectedRoute(String groupId) {
+ private void notifyGroupRouteSelected(String groupId) {
try {
- String selectedRouteId = null;
+ String selectedRouteId;
synchronized (mService.mLock) {
ClientGroup group = mUserRecord.mClientGroupMap.get(groupId);
if (group == null) {
@@ -1504,7 +1504,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
final int count = mTempClients.size();
for (int i = 0; i < count; i++) {
try {
- mTempClients.get(i).onSelectedRouteChanged(selectedRouteId);
+ mTempClients.get(i).onGroupRouteSelected(selectedRouteId);
} catch (RemoteException ex) {
Slog.w(TAG, "Failed to call onSelectedRouteChanged. Client probably died.");
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 7bd3ee2b33e3..352eac3567fe 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -435,8 +435,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/**
* Message to indicate that reasons for why an uid is blocked changed.
* arg1 = uid
- * arg2 = oldBlockedReasons
- * obj = newBlockedReasons
+ * arg2 = newBlockedReasons
+ * obj = oldBlockedReasons
*/
private static final int MSG_BLOCKED_REASON_CHANGED = 21;
@@ -643,6 +643,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@GuardedBy("mUidRulesFirstLock")
private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray();
+ /**
+ * Map of uid -> UidStateCallbackInfo objects holding the data received from
+ * {@link IUidObserver#onUidStateChanged(int, int, long, int)} callbacks. In order to avoid
+ * creating a new object for every callback received, we hold onto the object created for each
+ * uid and reuse it.
+ *
+ * Note that the lock used for accessing this object should not be used for anything else and we
+ * should not be acquiring new locks or doing any heavy work while this lock is held since this
+ * will be used in the callback from ActivityManagerService.
+ */
+ @GuardedBy("mUidStateCallbackInfos")
+ private final SparseArray<UidStateCallbackInfo> mUidStateCallbackInfos =
+ new SparseArray<>();
+
private RestrictedModeObserver mRestrictedModeObserver;
// TODO: keep allowlist of system-critical services that should never have
@@ -1022,11 +1036,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final private IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
@ProcessCapability int capability) {
- // TODO: Avoid creating a new UidStateCallbackInfo object every time
- // we get a callback for an uid
- mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED,
- new UidStateCallbackInfo(uid, procState, procStateSeq, capability))
+ synchronized (mUidStateCallbackInfos) {
+ UidStateCallbackInfo callbackInfo = mUidStateCallbackInfos.get(uid);
+ if (callbackInfo == null) {
+ callbackInfo = new UidStateCallbackInfo();
+ mUidStateCallbackInfos.put(uid, callbackInfo);
+ }
+ callbackInfo.update(uid, procState, procStateSeq, capability);
+ if (!callbackInfo.isPending) {
+ mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo)
.sendToTarget();
+ }
+ }
}
@Override public void onUidGone(int uid, boolean disabled) {
@@ -1044,14 +1065,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
};
private static final class UidStateCallbackInfo {
- public final int uid;
- public final int procState;
- public final long procStateSeq;
+ public int uid;
+ public int procState;
+ public long procStateSeq;
@ProcessCapability
- public final int capability;
+ public int capability;
+ public boolean isPending;
- UidStateCallbackInfo(int uid, int procState, long procStateSeq,
- @ProcessCapability int capability) {
+ public void update(int uid, int procState, long procStateSeq, int capability) {
this.uid = uid;
this.procState = procState;
this.procStateSeq = procStateSeq;
@@ -4495,6 +4516,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mPowerSaveTempWhitelistAppIds.delete(uid);
mAppIdleTempWhitelistAppIds.delete(uid);
mUidFirewallRestrictedModeRules.delete(uid);
+ synchronized (mUidStateCallbackInfos) {
+ mUidStateCallbackInfos.remove(uid);
+ }
// ...then update iptables asynchronously.
mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();
@@ -4641,7 +4665,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
+ ", oldRule=" + uidRulesToString(oldUidRules & MASK_METERED_NETWORKS)
+ ", newRule=" + uidRulesToString(newUidRules & MASK_METERED_NETWORKS)
+ ", newUidRules=" + uidRulesToString(newUidRules)
- + ", oldUidRules=" + uidRulesToString(oldUidRules));
+ + ", oldUidRules=" + uidRulesToString(oldUidRules)
+ + ", oldBlockedMeteredReasons=" + NetworkPolicyManager.blockedReasonsToString(
+ uidBlockedState.blockedReasons & BLOCKED_METERED_REASON_MASK)
+ + ", oldBlockedMeteredEffectiveReasons="
+ + NetworkPolicyManager.blockedReasonsToString(
+ uidBlockedState.effectiveBlockedReasons & BLOCKED_METERED_REASON_MASK)
+ + ", oldAllowedMeteredReasons=" + NetworkPolicyManager.blockedReasonsToString(
+ uidBlockedState.allowedReasons & BLOCKED_METERED_REASON_MASK));
}
if (newUidRules == RULE_NONE) {
@@ -5128,10 +5159,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
case UID_MSG_STATE_CHANGED: {
final UidStateCallbackInfo uidStateCallbackInfo =
(UidStateCallbackInfo) msg.obj;
- final int uid = uidStateCallbackInfo.uid;
- final int procState = uidStateCallbackInfo.procState;
- final long procStateSeq = uidStateCallbackInfo.procStateSeq;
- final int capability = uidStateCallbackInfo.capability;
+ final int uid;
+ final int procState;
+ final long procStateSeq;
+ final int capability;
+ synchronized (mUidStateCallbackInfos) {
+ uid = uidStateCallbackInfo.uid;
+ procState = uidStateCallbackInfo.procState;
+ procStateSeq = uidStateCallbackInfo.procStateSeq;
+ capability = uidStateCallbackInfo.capability;
+ uidStateCallbackInfo.isPending = false;
+ }
handleUidChanged(uid, procState, procStateSeq, capability);
return true;
@@ -5575,17 +5613,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
@Override
- public boolean checkUidNetworkingBlocked(int uid, int uidRules,
- boolean isNetworkMetered, boolean isBackgroundRestricted) {
- mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
- // Log of invoking this function is disabled because it will be called very frequently. And
- // metrics are unlikely needed on this method because the callers are external and this
- // method doesn't take any locks or perform expensive operations.
- return isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
- isBackgroundRestricted, null);
- }
-
- @Override
public boolean isUidRestrictedOnMeteredNetworks(int uid) {
mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
final int uidRules;
@@ -5877,6 +5904,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
effectiveBlockedReasons = blockedReasons;
// If the uid is not subject to any blocked reasons, then return early
if (blockedReasons == BLOCKED_REASON_NONE) {
+ if (LOGV) {
+ Log.v(TAG, "updateEffectiveBlockedReasons(): no blocked reasons");
+ }
return;
}
if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) {
@@ -5909,6 +5939,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) {
effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
}
+ if (LOGV) {
+ Log.v(TAG, "updateEffectiveBlockedReasons()"
+ + ": blockedReasons=" + Integer.toBinaryString(blockedReasons)
+ + ", effectiveReasons=" + Integer.toBinaryString(effectiveBlockedReasons));
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index b9984a5c24ee..8bd3b1e0b6ac 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -175,6 +175,11 @@ public class NotificationHistoryDatabase {
mFileWriteHandler.post(rcr);
}
+ public void deleteNotificationChannel(String pkg, String channelId) {
+ RemoveChannelRunnable rcr = new RemoveChannelRunnable(pkg, channelId);
+ mFileWriteHandler.post(rcr);
+ }
+
public void addNotification(final HistoricalNotification notification) {
synchronized (mLock) {
mBuffer.addNewNotificationToWrite(notification);
@@ -505,4 +510,47 @@ public class NotificationHistoryDatabase {
}
}
}
+
+ final class RemoveChannelRunnable implements Runnable {
+ private String mPkg;
+ private String mChannelId;
+ private NotificationHistory mNotificationHistory;
+
+ RemoveChannelRunnable(String pkg, String channelId) {
+ mPkg = pkg;
+ mChannelId = channelId;
+ }
+
+ @VisibleForTesting
+ void setNotificationHistory(NotificationHistory nh) {
+ mNotificationHistory = nh;
+ }
+
+ @Override
+ public void run() {
+ if (DEBUG) Slog.d(TAG, "RemoveChannelRunnable");
+ synchronized (mLock) {
+ // Remove from pending history
+ mBuffer.removeChannelFromWrite(mPkg, mChannelId);
+
+ Iterator<AtomicFile> historyFileItr = mHistoryFiles.iterator();
+ while (historyFileItr.hasNext()) {
+ final AtomicFile af = historyFileItr.next();
+ try {
+ NotificationHistory notificationHistory = mNotificationHistory != null
+ ? mNotificationHistory
+ : new NotificationHistory();
+ readLocked(af, notificationHistory,
+ new NotificationHistoryFilter.Builder().build());
+ if (notificationHistory.removeChannelFromWrite(mPkg, mChannelId)) {
+ writeLocked(af, notificationHistory);
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Cannot clean up file on channel removal "
+ + af.getBaseFile().getName(), e);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryManager.java b/services/core/java/com/android/server/notification/NotificationHistoryManager.java
index cf3530bfe7fc..6da898acdafe 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryManager.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryManager.java
@@ -183,6 +183,22 @@ public class NotificationHistoryManager {
}
}
+ public void deleteNotificationChannel(String pkg, int uid, String channelId) {
+ synchronized (mLock) {
+ int userId = UserHandle.getUserId(uid);
+ final NotificationHistoryDatabase userHistory =
+ getUserHistoryAndInitializeIfNeededLocked(userId);
+ // TODO: it shouldn't be possible to delete a notification entry while the user is
+ // locked but we should handle it
+ if (userHistory == null) {
+ Slog.w(TAG, "Attempted to remove channel for locked/gone/disabled user "
+ + userId);
+ return;
+ }
+ userHistory.deleteNotificationChannel(pkg, channelId);
+ }
+ }
+
public void triggerWriteToDisk() {
synchronized (mLock) {
final int userCount = mUserState.size();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4ee90d6e0956..6dcf39be5cb4 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3623,6 +3623,7 @@ public class NotificationManagerService extends SystemService {
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true,
callingUser, REASON_CHANNEL_REMOVED, null);
mPreferencesHelper.deleteNotificationChannel(pkg, callingUid, channelId);
+ mHistoryManager.deleteNotificationChannel(pkg, callingUid, channelId);
mListeners.notifyNotificationChannelChanged(pkg,
UserHandle.getUserHandleForUid(callingUid),
mPreferencesHelper.getNotificationChannel(pkg, callingUid, channelId, true),
@@ -4342,6 +4343,49 @@ public class NotificationManagerService extends SystemService {
}
/**
+ * Allows an app to set an initial notification listener filter
+ *
+ * @param token The binder for the listener, to check that the caller is allowed
+ */
+ @Override
+ public void migrateNotificationFilter(INotificationListener token, int defaultTypes,
+ List<String> disallowedApps) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mNotificationLock) {
+ final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
+
+ Pair key = Pair.create(info.component, info.userid);
+
+ NotificationListenerFilter nlf = mListeners.getNotificationListenerFilter(key);
+ if (nlf == null) {
+ nlf = new NotificationListenerFilter();
+ }
+ if (nlf.getDisallowedPackages().isEmpty() && disallowedApps != null) {
+ for (String pkg : disallowedApps) {
+ // block the current user's version and any work profile versions
+ for (int userId : mUm.getProfileIds(info.userid, false)) {
+ try {
+ int uid = getUidForPackageAndUser(pkg, UserHandle.of(userId));
+ VersionedPackage vp = new VersionedPackage(pkg, uid);
+ nlf.addPackage(vp);
+ } catch (Exception e) {
+ // pkg doesn't exist on that user; skip
+ }
+ }
+ }
+ }
+ if (nlf.areAllTypesAllowed()) {
+ nlf.setTypes(defaultTypes);
+ }
+ mListeners.setNotificationListenerFilter(key, nlf);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
* Allow an INotificationListener to simulate clearing (dismissing) a single notification.
*
* {@see com.android.server.StatusBarManagerService.NotificationCallbacks#onNotificationClear}
@@ -5239,7 +5283,7 @@ public class NotificationManagerService extends SystemService {
}
private int getUidForPackageAndUser(String pkg, UserHandle user) throws RemoteException {
- int uid = 0;
+ int uid = INVALID_UID;
final long identity = Binder.clearCallingIdentity();
try {
uid = mPackageManager.getPackageUid(pkg, 0, user.getIdentifier());
@@ -7076,6 +7120,7 @@ public class NotificationManagerService extends SystemService {
final PendingIntent pi = PendingIntent.getBroadcast(getContext(),
REQUEST_CODE_TIMEOUT,
new Intent(ACTION_NOTIFICATION_TIMEOUT)
+ .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
.setData(new Uri.Builder().scheme(SCHEME_TIMEOUT)
.appendPath(record.getKey()).build())
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
diff --git a/services/core/java/com/android/server/pm/IncrementalStates.java b/services/core/java/com/android/server/pm/IncrementalStates.java
index ecafdfdbd6f1..4fd360bcd453 100644
--- a/services/core/java/com/android/server/pm/IncrementalStates.java
+++ b/services/core/java/com/android/server/pm/IncrementalStates.java
@@ -293,11 +293,11 @@ public final class IncrementalStates {
Slog.i(TAG, "received progress update: " + progress);
}
mLoadingState.setProgress(progress);
- if (1 - progress < 0.001) {
+ if (Math.abs(1.0f - progress) < 0.00000001f) {
if (DEBUG) {
Slog.i(TAG, "package is fully loaded");
}
- mLoadingState.setProgress(1);
+ mLoadingState.setProgress(1.0f);
if (mLoadingState.isLoading()) {
mLoadingState.adoptNewLoadingStateLocked(false);
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 7b71be98834c..4eafe5143c8f 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -309,23 +309,24 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private final String mOriginalInstallerPackageName;
/** Uid of the owner of the installer session */
- @GuardedBy("mLock")
- private int mInstallerUid;
+ private volatile int mInstallerUid;
/** Where this install request came from */
@GuardedBy("mLock")
private InstallSource mInstallSource;
- @GuardedBy("mLock")
+ private final Object mProgressLock = new Object();
+
+ @GuardedBy("mProgressLock")
private float mClientProgress = 0;
- @GuardedBy("mLock")
+ @GuardedBy("mProgressLock")
private float mInternalProgress = 0;
- @GuardedBy("mLock")
+ @GuardedBy("mProgressLock")
private float mProgress = 0;
- @GuardedBy("mLock")
+ @GuardedBy("mProgressLock")
private float mReportedProgress = -1;
- @GuardedBy("mLock")
+ @GuardedBy("mProgressLock")
private float mIncrementalProgress = 0;
/** State of the session. */
@@ -571,7 +572,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
*/
@Override
public void installSession(IntentSender statusReceiver) {
- assertCallerIsOwnerOrRootOrSystemLocked();
+ assertCallerIsOwnerOrRootOrSystem();
assertNotChildLocked("StagedSession#installSession");
Preconditions.checkArgument(isCommitted() && isSessionReady());
@@ -670,7 +671,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final Runnable r;
synchronized (mLock) {
assertNotChildLocked("StagedSession#abandon");
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
if (isInTerminalState()) {
// We keep the session in the database if it's in a finalized state. It will be
// removed by PackageInstallerService when the last update time is old enough.
@@ -744,7 +745,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
*/
@Override
public void verifySession() {
- assertCallerIsOwnerOrRootOrSystemLocked();
+ assertCallerIsOwnerOrRootOrSystem();
Preconditions.checkArgument(isCommitted());
Preconditions.checkArgument(!mSessionApplied && !mSessionFailed);
verify();
@@ -1229,7 +1230,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- @GuardedBy("mLock")
+ @GuardedBy("mProgressLock")
private void setClientProgressLocked(float progress) {
// Always publish first staging movement
final boolean forcePublish = (mClientProgress == 0);
@@ -1239,21 +1240,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@Override
public void setClientProgress(float progress) {
- synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
+ synchronized (mProgressLock) {
setClientProgressLocked(progress);
}
}
@Override
public void addClientProgress(float progress) {
- synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
+ synchronized (mProgressLock) {
setClientProgressLocked(mClientProgress + progress);
}
}
- @GuardedBy("mLock")
+ @GuardedBy("mProgressLock")
private void computeProgressLocked(boolean forcePublish) {
if (!mCommitted) {
mProgress = MathUtils.constrain(mClientProgress * 0.8f, 0f, 0.8f)
@@ -1278,8 +1279,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@Override
public String[] getNames() {
+ assertCallerIsOwnerOrRoot();
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotCommittedOrDestroyedLocked("getNames");
return getNamesLocked();
@@ -1362,8 +1363,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
+ assertCallerIsOwnerOrRoot();
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotCommittedOrDestroyedLocked("addChecksums");
if (mChecksums.containsKey(name)) {
@@ -1384,8 +1385,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new IllegalStateException("Must specify package name to remove a split");
}
+ assertCallerIsOwnerOrRoot();
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotCommittedOrDestroyedLocked("removeSplit");
try {
@@ -1431,8 +1432,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new IllegalStateException(
"Cannot write regular files in a data loader installation session.");
}
+ assertCallerIsOwnerOrRoot();
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotSealedLocked("assertCanWrite");
}
if (reverseMode) {
@@ -1605,8 +1606,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new IllegalStateException(
"Cannot read regular files in a data loader installation session.");
}
+ assertCallerIsOwnerOrRoot();
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotCommittedOrDestroyedLocked("openRead");
try {
return openReadInternalLocked(name);
@@ -1634,8 +1635,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
* Check if the caller is the owner of this session. Otherwise throw a
* {@link SecurityException}.
*/
- @GuardedBy("mLock")
- private void assertCallerIsOwnerOrRootLocked() {
+ private void assertCallerIsOwnerOrRoot() {
final int callingUid = Binder.getCallingUid();
if (callingUid != Process.ROOT_UID && callingUid != mInstallerUid) {
throw new SecurityException("Session does not belong to uid " + callingUid);
@@ -1646,8 +1646,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
* Check if the caller is the owner of this session. Otherwise throw a
* {@link SecurityException}.
*/
- @GuardedBy("mLock")
- private void assertCallerIsOwnerOrRootOrSystemLocked() {
+ private void assertCallerIsOwnerOrRootOrSystem() {
final int callingUid = Binder.getCallingUid();
if (callingUid != Process.ROOT_UID && callingUid != mInstallerUid
&& callingUid != Process.SYSTEM_UID) {
@@ -1929,9 +1928,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
*/
private boolean markAsSealed(@NonNull IntentSender statusReceiver, boolean forTransfer) {
Objects.requireNonNull(statusReceiver);
+ assertCallerIsOwnerOrRoot();
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotDestroyedLocked("commit of session " + sessionId);
assertNoWriteFileTransfersOpenLocked();
@@ -2004,9 +2003,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
"Session destroyed");
}
if (!isIncrementalInstallation()) {
- // For non-incremental installs, client staging is fully done at this point
- mClientProgress = 1f;
- computeProgressLocked(true);
+ synchronized (mProgressLock) {
+ // For non-incremental installs, client staging is fully done at this point
+ mClientProgress = 1f;
+ computeProgressLocked(true);
+ }
}
// This ongoing commit should keep session active, even though client
@@ -2191,7 +2192,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
assertPreparedAndNotSealedLocked("transfer");
try {
@@ -2376,8 +2377,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
PackageLite result = parseApkLite();
if (result != null) {
mPackageLite = result;
- mInternalProgress = 0.5f;
- computeProgressLocked(true);
+ synchronized (mProgressLock) {
+ mInternalProgress = 0.5f;
+ computeProgressLocked(true);
+ }
extractNativeLibraries(
mPackageLite, stageDir, params.abiOverride, mayInheritNativeLibs());
@@ -3554,7 +3557,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
int activeCount;
synchronized (mLock) {
if (checkCaller) {
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
}
activeCount = mActiveCount.decrementAndGet();
@@ -3593,7 +3596,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private void abandonNonStaged() {
synchronized (mLock) {
assertNotChildLocked("abandonNonStaged");
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
if (mRelinquished) {
if (LOGD) Slog.d(TAG, "Ignoring abandon after commit relinquished control");
return;
@@ -3659,7 +3662,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
assertPreparedAndNotSealedLocked("addFile");
if (!mFiles.add(new FileEntry(mFiles.size(),
@@ -3680,7 +3683,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
assertPreparedAndNotSealedLocked("removeFile");
if (!mFiles.add(new FileEntry(mFiles.size(),
@@ -3893,7 +3896,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
new IPackageLoadingProgressCallback.Stub() {
@Override
public void onPackageLoadingProgressChanged(float progress) {
- synchronized (mLock) {
+ synchronized (mProgressLock) {
mIncrementalProgress = progress;
computeProgressLocked(true);
}
@@ -3993,7 +3996,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
+ " as it is in an invalid state.");
}
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
assertPreparedAndNotSealedLocked("addChildSessionId");
final int indexOfSession = mChildSessions.indexOfKey(childSessionId);
@@ -4012,7 +4015,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@Override
public void removeChildSessionId(int sessionId) {
synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
+ assertCallerIsOwnerOrRoot();
assertPreparedAndNotSealedLocked("removeChildSessionId");
final int indexOfSession = mChildSessions.indexOfKey(sessionId);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8383a7eca102..2dcc8d93abe4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7197,7 +7197,7 @@ public class PackageManagerService extends IPackageManager.Stub
updateSharedLibrariesLocked(pkg, stubPkgSetting, null, null,
Collections.unmodifiableMap(mPackages));
} catch (PackageManagerException e) {
- Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
+ Slog.w(TAG, "updateAllSharedLibrariesLPw failed: ", e);
}
final int[] userIds = mUserManager.getUserIds();
for (final int userId : userIds) {
@@ -7449,7 +7449,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (matches.size() == 1) {
return matches.get(0).getComponentInfo().packageName;
} else if (matches.size() == 0) {
- Log.e(TAG, "There should probably be a verifier, but, none were found");
+ Log.w(TAG, "There should probably be a verifier, but, none were found");
return null;
}
throw new RuntimeException("There must be exactly one verifier; found " + matches);
@@ -22826,7 +22826,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (matches.size() == 1) {
return matches.get(0).getComponentInfo().packageName;
} else {
- Slog.e(TAG, "There should probably be exactly one storage manager; found "
+ Slog.w(TAG, "There should probably be exactly one storage manager; found "
+ matches.size() + ": matches=" + matches);
return null;
}
@@ -25019,7 +25019,7 @@ public class PackageManagerService extends IPackageManager.Stub
// already held, since it's invoked as a side-effect of
// executeBatchLI()
if (e != null) {
- logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
+ logCriticalInfo(Log.WARN, "Failed to create app data for " + packageName
+ ", but trying to recover: " + e);
destroyAppDataLeafLIF(pkg, userId, flags);
try {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index b51b8330f911..4823c29b96f9 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1229,7 +1229,7 @@ public final class Settings implements Watchable, Snappable {
size++;
}
if (mAppIds.get(index) != null) {
- PackageManagerService.reportSettingsProblem(Log.ERROR,
+ PackageManagerService.reportSettingsProblem(Log.WARN,
"Adding duplicate app id: " + appId
+ " name=" + name);
return false;
@@ -1237,7 +1237,7 @@ public final class Settings implements Watchable, Snappable {
mAppIds.set(index, obj);
} else {
if (mOtherAppIds.get(appId) != null) {
- PackageManagerService.reportSettingsProblem(Log.ERROR,
+ PackageManagerService.reportSettingsProblem(Log.WARN,
"Adding duplicate shared id: " + appId
+ " name=" + name);
return false;
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 7aad179226be..fab0c00cb5ad 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -258,8 +258,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
private final PermissionRegistry mRegistry = new PermissionRegistry();
@NonNull
- private final AttributionSourceRegistry mAttributionSourceRegistry =
- new AttributionSourceRegistry();
+ private final AttributionSourceRegistry mAttributionSourceRegistry;
@GuardedBy("mLock")
@Nullable
@@ -379,6 +378,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
mSystemPermissions = systemConfig.getSystemPermissions();
mGlobalGids = systemConfig.getGlobalGids();
mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
+ mAttributionSourceRegistry = new AttributionSourceRegistry(context);
// propagate permission configuration
final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
@@ -5294,6 +5294,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
private static final class AttributionSourceRegistry {
private final Object mLock = new Object();
+ private final Context mContext;
+
+ AttributionSourceRegistry(@NonNull Context context) {
+ mContext = context;
+ }
+
private final WeakHashMap<IBinder, AttributionSource> mAttributions = new WeakHashMap<>();
public @NonNull AttributionSource registerAttributionSource(
@@ -5321,7 +5327,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// app passing the source, in which case you must trust the other side;
final int callingUid = Binder.getCallingUid();
- if (source.getUid() != callingUid) {
+ if (source.getUid() != callingUid && mContext.checkPermission(
+ Manifest.permission.UPDATE_APP_OPS_STATS, /*pid*/ -1, callingUid)
+ != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Cannot register attribution source for uid:"
+ source.getUid() + " from uid:" + callingUid);
}
diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java
index ff6c2f551bb3..5f5e6a3e6f46 100644
--- a/services/core/java/com/android/server/storage/StorageSessionController.java
+++ b/services/core/java/com/android/server/storage/StorageSessionController.java
@@ -147,17 +147,18 @@ public final class StorageSessionController {
return;
}
String sessionId = vol.getId();
- int userId = getConnectionUserIdForVolume(vol);
+ int connectionUserId = getConnectionUserIdForVolume(vol);
StorageUserConnection connection = null;
synchronized (mLock) {
- connection = mConnections.get(userId);
+ connection = mConnections.get(connectionUserId);
if (connection != null) {
Slog.i(TAG, "Notifying volume state changed for session with id: " + sessionId);
connection.notifyVolumeStateChanged(sessionId,
- vol.buildStorageVolume(mContext, userId, false));
+ vol.buildStorageVolume(mContext, vol.getMountUserId(), false));
} else {
- Slog.w(TAG, "No available storage user connection for userId : " + userId);
+ Slog.w(TAG, "No available storage user connection for userId : "
+ + connectionUserId);
}
}
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 4fbc79507b95..f014b0749396 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -56,7 +56,6 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.security.Authorization;
-import android.security.KeyStore;
import android.service.trust.TrustAgentService;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -704,13 +703,11 @@ public class TrustManagerService extends SystemService {
dispatchDeviceLocked(userId, locked);
Authorization.onLockScreenEvent(locked, userId, null);
- KeyStore.getInstance().onUserLockedStateChanged(userId, locked);
// Also update the user's profiles who have unified challenge, since they
// share the same unlocked state (see {@link #isDeviceLocked(int)})
for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) {
if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) {
mAuthorizationService.onLockScreenEvent(locked, profileHandle, null);
- KeyStore.getInstance().onUserLockedStateChanged(profileHandle, locked);
}
}
}
@@ -1262,7 +1259,6 @@ public class TrustManagerService extends SystemService {
}
Authorization.onLockScreenEvent(locked, userId, null);
- KeyStore.getInstance().onUserLockedStateChanged(userId, locked);
if (locked) {
try {
diff --git a/services/core/java/com/android/server/utils/Slogf.java b/services/core/java/com/android/server/utils/Slogf.java
new file mode 100644
index 000000000000..bbc541438c82
--- /dev/null
+++ b/services/core/java/com/android/server/utils/Slogf.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.utils;
+
+import android.annotation.Nullable;
+import android.os.Trace;
+import android.util.Log;
+import android.util.Slog;
+import android.util.TimingsTraceLog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.Formatter;
+import java.util.Locale;
+
+/**
+ * Extends {@link Slog} by providing overloaded methods that take string formatting.
+ *
+ * <p><strong>Note: </strong>the overloaded methods won't create the formatted message if the
+ * respective logging level is disabled for the tag, but the compiler will still create an
+ * intermediate array of the objects for the {@code vargars}, which could affect garbage collection.
+ * So, if you're calling these method in a critical path, make sure to explicitly check for the
+ * level before calling them.
+ */
+public final class Slogf {
+
+ @GuardedBy("sMessageBuilder")
+ private static final StringBuilder sMessageBuilder;
+
+ @GuardedBy("sMessageBuilder")
+ private static final Formatter sFormatter;
+
+ static {
+ TimingsTraceLog t = new TimingsTraceLog("SLog", Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("static_init");
+ sMessageBuilder = new StringBuilder();
+ sFormatter = new Formatter(sMessageBuilder, Locale.ENGLISH);
+ t.traceEnd();
+ }
+
+ private Slogf() {
+ throw new UnsupportedOperationException("provides only static methods");
+ }
+
+ /** Same as {@link Log#isLoggable(String, int)}. */
+ public static boolean isLoggable(String tag, int level) {
+ return Log.isLoggable(tag, level);
+ }
+
+ /** Same as {@link Slog#v(String, String)}. */
+ public static int v(String tag, String msg) {
+ return Slog.v(tag, msg);
+ }
+
+ /** Same as {@link Slog#v(String, String, Throwable)}. */
+ public static int v(String tag, String msg, Throwable tr) {
+ return Slog.v(tag, msg, tr);
+ }
+
+ /** Same as {@link Slog#d(String, String)}. */
+ public static int d(String tag, String msg) {
+ return Slog.d(tag, msg);
+ }
+
+ /** Same as {@link Slog#d(String, String, Throwable)}. */
+ public static int d(String tag, String msg, Throwable tr) {
+ return Slog.d(tag, msg, tr);
+ }
+
+ /** Same as {@link Slog#i(String, String)}. */
+ public static int i(String tag, String msg) {
+ return Slog.i(tag, msg);
+ }
+
+ /** Same as {@link Slog#i(String, String, Throwable)}. */
+ public static int i(String tag, String msg, Throwable tr) {
+ return Slog.i(tag, msg, tr);
+ }
+
+ /** Same as {@link Slog#w(String, String)}. */
+ public static int w(String tag, String msg) {
+ return Slog.w(tag, msg);
+ }
+
+ /** Same as {@link Slog#w(String, String, Throwable)}. */
+ public static int w(String tag, String msg, Throwable tr) {
+ return Slog.w(tag, msg, tr);
+ }
+
+ /** Same as {@link Slog#w(String, String)}. */
+ public static int w(String tag, Throwable tr) {
+ return Slog.w(tag, tr);
+ }
+
+ /** Same as {@link Slog#e(String, String)}. */
+ public static int e(String tag, String msg) {
+ return Slog.e(tag, msg);
+ }
+
+ /** Same as {@link Slog#e(String, String, Throwable)}. */
+ public static int e(String tag, String msg, Throwable tr) {
+ return Slog.e(tag, msg, tr);
+ }
+
+ /** Same as {@link Slog#wtf(String, String)}. */
+ public static int wtf(String tag, String msg) {
+ return Slog.wtf(tag, msg);
+ }
+
+ /** Same as {@link Slog#wtfQuiet(String, String)}. */
+ public static void wtfQuiet(String tag, String msg) {
+ Slog.wtfQuiet(tag, msg);
+ }
+
+ /** Same as {@link Slog#wtfStack(String, String). */
+ public static int wtfStack(String tag, String msg) {
+ return Slog.wtfStack(tag, msg);
+ }
+
+ /** Same as {@link Slog#wtf(String, Throwable). */
+ public static int wtf(String tag, Throwable tr) {
+ return Slog.wtf(tag, tr);
+ }
+
+ /** Same as {@link Slog#wtf(String, String, Throwable)}. */
+ public static int wtf(String tag, String msg, Throwable tr) {
+ return Slog.wtf(tag, msg, tr);
+ }
+
+ /** Same as {@link Slog#println(int, String, String)}. */
+ public static int println(int priority, String tag, String msg) {
+ return Slog.println(priority, tag, msg);
+ }
+
+ /**
+ * Logs a {@link Log.VERBOSE} message.
+ *
+ * <p><strong>Note: </strong>the message will only be formatted if {@link Log#VERBOSE} logging
+ * is enabled for the given {@code tag}, but the compiler will still create an intermediate
+ * array of the objects for the {@code vargars}, which could affect garbage collection. So, if
+ * you're calling this method in a critical path, make sure to explicitly do the check before
+ * calling it.
+ */
+ public static void v(String tag, String format, @Nullable Object... args) {
+ if (!isLoggable(tag, Log.VERBOSE)) return;
+
+ v(tag, getMessage(format, args));
+ }
+
+ /**
+ * Logs a {@link Log.DEBUG} message.
+ *
+ * <p><strong>Note: </strong>the message will only be formatted if {@link Log#DEBUG} logging is
+ * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+ * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+ * calling this method in a critical path, make sure to explicitly do the check before calling
+ * it.
+ */
+ public static void d(String tag, String format, @Nullable Object... args) {
+ if (!isLoggable(tag, Log.DEBUG)) return;
+
+ d(tag, getMessage(format, args));
+ }
+
+ /**
+ * Logs a {@link Log.INFO} message.
+ *
+ * <p><strong>Note: </strong>the message will only be formatted if {@link Log#INFO} logging is
+ * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+ * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+ * calling this method in a critical path, make sure to explicitly do the check before calling
+ * it.
+ */
+ public static void i(String tag, String format, @Nullable Object... args) {
+ if (!isLoggable(tag, Log.INFO)) return;
+
+ i(tag, getMessage(format, args));
+ }
+
+ /**
+ * Logs a {@link Log.WARN} message.
+ *
+ * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+ * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+ * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+ * calling this method in a critical path, make sure to explicitly do the check before calling
+ * it.
+ */
+ public static void w(String tag, String format, @Nullable Object... args) {
+ if (!isLoggable(tag, Log.WARN)) return;
+
+ w(tag, getMessage(format, args));
+ }
+
+ /**
+ * Logs a {@link Log.WARN} message with an exception
+ *
+ * <p><strong>Note: </strong>the message will only be formatted if {@link Log#WARN} logging is
+ * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+ * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+ * calling this method in a critical path, make sure to explicitly do the check before calling
+ * it.
+ */
+ public static void w(String tag, Exception exception, String format, @Nullable Object... args) {
+ if (!isLoggable(tag, Log.WARN)) return;
+
+ w(tag, getMessage(format, args), exception);
+ }
+ /**
+ * Logs a {@link Log.ERROR} message.
+ *
+ * <p><strong>Note: </strong>the message will only be formatted if {@link Log#ERROR} logging is
+ * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+ * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+ * calling this method in a critical path, make sure to explicitly do the check before calling
+ * it.
+ */
+ public static void e(String tag, String format, @Nullable Object... args) {
+ if (!isLoggable(tag, Log.ERROR)) return;
+
+ e(tag, getMessage(format, args));
+ }
+
+ /**
+ * Logs a {@link Log.ERROR} message with an exception
+ *
+ * <p><strong>Note: </strong>the message will only be formatted if {@link Log#ERROR} logging is
+ * enabled for the given {@code tag}, but the compiler will still create an intermediate array
+ * of the objects for the {@code vargars}, which could affect garbage collection. So, if you're
+ * calling this method in a critical path, make sure to explicitly do the check before calling
+ * it.
+ */
+ public static void e(String tag, Exception exception, String format, @Nullable Object... args) {
+ if (!isLoggable(tag, Log.ERROR)) return;
+
+ e(tag, getMessage(format, args), exception);
+ }
+
+ /**
+ * Logs a {@code wtf} message.
+ */
+ public static void wtf(String tag, String format, @Nullable Object... args) {
+ wtf(tag, getMessage(format, args));
+ }
+
+ /**
+ * Logs a {@code wtf} message with an exception.
+ */
+ public static void wtf(String tag, Exception exception, String format,
+ @Nullable Object... args) {
+ wtf(tag, getMessage(format, args), exception);
+ }
+
+ private static String getMessage(String format, @Nullable Object... args) {
+ synchronized (sMessageBuilder) {
+ sFormatter.format(format, args);
+ String message = sMessageBuilder.toString();
+ sMessageBuilder.setLength(0);
+ return message;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index 54689358802f..ae806aa500a6 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -17,6 +17,7 @@
package com.android.server.vcn;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
@@ -96,16 +97,20 @@ public class Vcn extends Handler {
*/
private static final int MSG_EVENT_GATEWAY_CONNECTION_QUIT = MSG_EVENT_BASE + 3;
- /** Triggers an immediate teardown of the entire Vcn, including GatewayConnections. */
- private static final int MSG_CMD_TEARDOWN = MSG_CMD_BASE;
-
/**
- * Causes this VCN to immediately enter safe mode.
+ * Triggers reevaluation of safe mode conditions.
+ *
+ * <p>Upon entering safe mode, the VCN will only provide gateway connections opportunistically,
+ * leaving the underlying networks marked as NOT_VCN_MANAGED.
*
- * <p>Upon entering safe mode, the VCN will unregister its RequestListener, tear down all of its
- * VcnGatewayConnections, and notify VcnManagementService that it is in safe mode.
+ * <p>Any VcnGatewayConnection in safe mode will result in the entire Vcn instance being put
+ * into safe mode. Upon receiving this message, the Vcn MUST query all VcnGatewayConnections to
+ * determine if any are in safe mode.
*/
- private static final int MSG_CMD_ENTER_SAFE_MODE = MSG_CMD_BASE + 1;
+ private static final int MSG_EVENT_SAFE_MODE_STATE_CHANGED = MSG_EVENT_BASE + 4;
+
+ /** Triggers an immediate teardown of the entire Vcn, including GatewayConnections. */
+ private static final int MSG_CMD_TEARDOWN = MSG_CMD_BASE;
@NonNull private final VcnContext mVcnContext;
@NonNull private final ParcelUuid mSubscriptionGroup;
@@ -233,6 +238,11 @@ public class Vcn extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
+ if (mCurrentStatus != VCN_STATUS_CODE_ACTIVE
+ && mCurrentStatus != VCN_STATUS_CODE_SAFE_MODE) {
+ return;
+ }
+
switch (msg.what) {
case MSG_EVENT_CONFIG_UPDATED:
handleConfigUpdated((VcnConfig) msg.obj);
@@ -246,12 +256,12 @@ public class Vcn extends Handler {
case MSG_EVENT_GATEWAY_CONNECTION_QUIT:
handleGatewayConnectionQuit((VcnGatewayConnectionConfig) msg.obj);
break;
+ case MSG_EVENT_SAFE_MODE_STATE_CHANGED:
+ handleSafeModeStatusChanged();
+ break;
case MSG_CMD_TEARDOWN:
handleTeardown();
break;
- case MSG_CMD_ENTER_SAFE_MODE:
- handleEnterSafeMode();
- break;
default:
Slog.wtf(getLogTag(), "Unknown msg.what: " + msg.what);
}
@@ -263,40 +273,28 @@ public class Vcn extends Handler {
mConfig = config;
- // TODO(b/183174340): Remove this once opportunistic safe mode is supported.
- if (mCurrentStatus == VCN_STATUS_CODE_ACTIVE) {
- // VCN is already active - teardown any GatewayConnections whose configs have been
- // removed and get all current requests
- for (final Entry<VcnGatewayConnectionConfig, VcnGatewayConnection> entry :
- mVcnGatewayConnections.entrySet()) {
- final VcnGatewayConnectionConfig gatewayConnectionConfig = entry.getKey();
- final VcnGatewayConnection gatewayConnection = entry.getValue();
-
- // GatewayConnectionConfigs must match exactly (otherwise authentication or
- // connection details may have changed).
- if (!mConfig.getGatewayConnectionConfigs().contains(gatewayConnectionConfig)) {
- if (gatewayConnection == null) {
- Slog.wtf(
- getLogTag(),
- "Found gatewayConnectionConfig without GatewayConnection");
- } else {
- gatewayConnection.teardownAsynchronously();
- }
+ // Teardown any GatewayConnections whose configs have been removed and get all current
+ // requests
+ for (final Entry<VcnGatewayConnectionConfig, VcnGatewayConnection> entry :
+ mVcnGatewayConnections.entrySet()) {
+ final VcnGatewayConnectionConfig gatewayConnectionConfig = entry.getKey();
+ final VcnGatewayConnection gatewayConnection = entry.getValue();
+
+ // GatewayConnectionConfigs must match exactly (otherwise authentication or
+ // connection details may have changed).
+ if (!mConfig.getGatewayConnectionConfigs().contains(gatewayConnectionConfig)) {
+ if (gatewayConnection == null) {
+ Slog.wtf(
+ getLogTag(), "Found gatewayConnectionConfig without GatewayConnection");
+ } else {
+ gatewayConnection.teardownAsynchronously();
}
}
-
- // Trigger a re-evaluation of all NetworkRequests (to make sure any that can be
- // satisfied start a new GatewayConnection)
- mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
- } else if (mCurrentStatus == VCN_STATUS_CODE_SAFE_MODE) {
- // If this VCN was not previously active, it is exiting Safe Mode. Re-register the
- // request listener to get NetworkRequests again (and all cached requests).
- mVcnContext.getVcnNetworkProvider().registerListener(mRequestListener);
- } else {
- // Ignored; VCN was not active; config updates ignored.
- return;
}
- mCurrentStatus = VCN_STATUS_CODE_ACTIVE;
+
+ // Trigger a re-evaluation of all NetworkRequests (to make sure any that can be
+ // satisfied start a new GatewayConnection)
+ mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
}
private void handleTeardown() {
@@ -309,21 +307,27 @@ public class Vcn extends Handler {
mCurrentStatus = VCN_STATUS_CODE_INACTIVE;
}
- private void handleEnterSafeMode() {
- // TODO(b/183174340): Remove this once opportunistic-safe-mode is supported
- handleTeardown();
+ private void handleSafeModeStatusChanged() {
+ boolean hasSafeModeGatewayConnection = false;
- mCurrentStatus = VCN_STATUS_CODE_SAFE_MODE;
- mVcnCallback.onEnteredSafeMode();
+ // If any VcnGatewayConnection is in safe mode, mark the entire VCN as being in safe mode
+ for (VcnGatewayConnection gatewayConnection : mVcnGatewayConnections.values()) {
+ if (gatewayConnection.isInSafeMode()) {
+ hasSafeModeGatewayConnection = true;
+ break;
+ }
+ }
+
+ final int oldStatus = mCurrentStatus;
+ mCurrentStatus =
+ hasSafeModeGatewayConnection ? VCN_STATUS_CODE_SAFE_MODE : VCN_STATUS_CODE_ACTIVE;
+ if (oldStatus != mCurrentStatus) {
+ mVcnCallback.onSafeModeStatusChanged(hasSafeModeGatewayConnection);
+ }
}
private void handleNetworkRequested(
@NonNull NetworkRequest request, int score, int providerId) {
- if (mCurrentStatus != VCN_STATUS_CODE_ACTIVE) {
- Slog.v(getLogTag(), "Received NetworkRequest while inactive. Ignore for now");
- return;
- }
-
if (score > getNetworkScore()) {
if (VDBG) {
Slog.v(
@@ -376,25 +380,23 @@ public class Vcn extends Handler {
mVcnGatewayConnections.remove(config);
// Trigger a re-evaluation of all NetworkRequests (to make sure any that can be satisfied
- // start a new GatewayConnection), but only if the Vcn is still alive
- if (mCurrentStatus == VCN_STATUS_CODE_ACTIVE) {
- mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
- }
+ // start a new GatewayConnection). VCN is always alive here, courtesy of the liveness check
+ // in handleMessage()
+ mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
}
private void handleSubscriptionsChanged(@NonNull TelephonySubscriptionSnapshot snapshot) {
mLastSnapshot = snapshot;
- if (mCurrentStatus == VCN_STATUS_CODE_ACTIVE) {
- for (VcnGatewayConnection gatewayConnection : mVcnGatewayConnections.values()) {
- gatewayConnection.updateSubscriptionSnapshot(mLastSnapshot);
- }
+ for (VcnGatewayConnection gatewayConnection : mVcnGatewayConnections.values()) {
+ gatewayConnection.updateSubscriptionSnapshot(mLastSnapshot);
}
}
private boolean isRequestSatisfiedByGatewayConnectionConfig(
@NonNull NetworkRequest request, @NonNull VcnGatewayConnectionConfig config) {
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
+ builder.addTransportType(TRANSPORT_CELLULAR);
builder.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
for (int cap : config.getAllExposedCapabilities()) {
builder.addCapability(cap);
@@ -418,8 +420,8 @@ public class Vcn extends Handler {
/** Callback used for passing status signals from a VcnGatewayConnection to its managing Vcn. */
@VisibleForTesting(visibility = Visibility.PACKAGE)
public interface VcnGatewayStatusCallback {
- /** Called by a VcnGatewayConnection to indicate that it has entered safe mode. */
- void onEnteredSafeMode();
+ /** Called by a VcnGatewayConnection to indicate that it's safe mode status has changed. */
+ void onSafeModeStatusChanged();
/** Callback by a VcnGatewayConnection to indicate that an error occurred. */
void onGatewayConnectionError(
@@ -445,8 +447,8 @@ public class Vcn extends Handler {
}
@Override
- public void onEnteredSafeMode() {
- sendMessage(obtainMessage(MSG_CMD_ENTER_SAFE_MODE));
+ public void onSafeModeStatusChanged() {
+ sendMessage(obtainMessage(MSG_EVENT_SAFE_MODE_STATE_CHANGED));
}
@Override
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 2ba8edd3b1d0..20c08eb2ce92 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -32,6 +32,7 @@ import static com.android.server.VcnManagementService.VDBG;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.net.ConnectivityManager;
import android.net.InetAddresses;
import android.net.IpPrefix;
import android.net.IpSecManager;
@@ -44,6 +45,7 @@ import android.net.Network;
import android.net.NetworkAgent;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
+import android.net.NetworkProvider;
import android.net.RouteInfo;
import android.net.TelephonyNetworkSpecifier;
import android.net.Uri;
@@ -92,6 +94,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
/**
* A single VCN Gateway Connection, providing a single public-facing VCN network.
@@ -504,6 +507,15 @@ public class VcnGatewayConnection extends StateMachine {
private boolean mIsQuitting = false;
/**
+ * Whether the VcnGatewayConnection is in safe mode.
+ *
+ * <p>Upon hitting the safe mode timeout, this will be set to {@code true}. In safe mode, this
+ * VcnGatewayConnection will continue attempting to connect, and if a successful connection is
+ * made, safe mode will be exited.
+ */
+ private boolean mIsInSafeMode = false;
+
+ /**
* The token used by the primary/current/active session.
*
* <p>This token MUST be updated when a new stateful/async session becomes the
@@ -562,8 +574,7 @@ public class VcnGatewayConnection extends StateMachine {
* <p>Set in Connected state, always @NonNull in Connected, Migrating states, @Nullable
* otherwise.
*/
- @VisibleForTesting(visibility = Visibility.PRIVATE)
- NetworkAgent mNetworkAgent;
+ private NetworkAgent mNetworkAgent;
@Nullable private WakeupMessage mTeardownTimeoutAlarm;
@Nullable private WakeupMessage mDisconnectRequestAlarm;
@@ -628,6 +639,14 @@ public class VcnGatewayConnection extends StateMachine {
start();
}
+ /** Queries whether this VcnGatewayConnection is in safe mode. */
+ public boolean isInSafeMode() {
+ // Accessing internal state; must only be done on looper thread.
+ mVcnContext.ensureRunningOnLooperThread();
+
+ return mIsInSafeMode;
+ }
+
/**
* Asynchronously tears down this GatewayConnection, and any resources used.
*
@@ -1162,6 +1181,15 @@ public class VcnGatewayConnection extends StateMachine {
}
}
+ protected void handleSafeModeTimeoutExceeded() {
+ mSafeModeTimeoutAlarm = null;
+
+ // Connectivity for this GatewayConnection is broken; tear down the Network.
+ teardownNetwork();
+ mIsInSafeMode = true;
+ mGatewayStatusCallback.onSafeModeStatusChanged();
+ }
+
protected void logUnexpectedEvent(int what) {
Slog.d(TAG, String.format(
"Unexpected event code %d in state %s", what, this.getClass().getSimpleName()));
@@ -1315,8 +1343,7 @@ public class VcnGatewayConnection extends StateMachine {
}
break;
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
- mGatewayStatusCallback.onEnteredSafeMode();
- mSafeModeTimeoutAlarm = null;
+ handleSafeModeTimeoutExceeded();
break;
default:
logUnhandledMessage(msg);
@@ -1401,8 +1428,7 @@ public class VcnGatewayConnection extends StateMachine {
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
break;
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
- mGatewayStatusCallback.onEnteredSafeMode();
- mSafeModeTimeoutAlarm = null;
+ handleSafeModeTimeoutExceeded();
break;
default:
logUnhandledMessage(msg);
@@ -1432,30 +1458,35 @@ public class VcnGatewayConnection extends StateMachine {
buildNetworkCapabilities(mConnectionConfig, mUnderlying);
final LinkProperties lp =
buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig);
+ final NetworkAgentConfig nac =
+ new NetworkAgentConfig.Builder()
+ .setLegacyType(ConnectivityManager.TYPE_MOBILE)
+ .build();
final NetworkAgent agent =
- new NetworkAgent(
- mVcnContext.getContext(),
- mVcnContext.getLooper(),
+ mDeps.newNetworkAgent(
+ mVcnContext,
TAG,
caps,
lp,
Vcn.getNetworkScore(),
- new NetworkAgentConfig.Builder().build(),
- mVcnContext.getVcnNetworkProvider()) {
- @Override
- public void onNetworkUnwanted() {
- Slog.d(TAG, "NetworkAgent was unwanted");
- teardownAsynchronously();
- }
-
- @Override
- public void onValidationStatus(int status, @Nullable Uri redirectUri) {
- if (status == NetworkAgent.VALIDATION_STATUS_VALID) {
- clearFailedAttemptCounterAndSafeModeAlarm();
- }
- }
- };
+ nac,
+ mVcnContext.getVcnNetworkProvider(),
+ () -> {
+ Slog.d(TAG, "NetworkAgent was unwanted");
+ // If network agent has already been torn down, skip sending the
+ // disconnect. Unwanted() is always called, even when networkAgents
+ // are unregistered in teardownNetwork(), so prevent duplicate
+ // notifications.
+ if (mNetworkAgent != null) {
+ teardownAsynchronously();
+ }
+ } /* networkUnwantedCallback */,
+ (status) -> {
+ if (status == NetworkAgent.VALIDATION_STATUS_VALID) {
+ clearFailedAttemptCounterAndSafeModeAlarm();
+ }
+ } /* validationStatusCallback */);
agent.register();
agent.markConnected();
@@ -1469,6 +1500,11 @@ public class VcnGatewayConnection extends StateMachine {
// Validated connection, clear failed attempt counter
mFailedAttempts = 0;
cancelSafeModeAlarm();
+
+ if (mIsInSafeMode) {
+ mIsInSafeMode = false;
+ mGatewayStatusCallback.onSafeModeStatusChanged();
+ }
}
protected void applyTransform(
@@ -1491,13 +1527,6 @@ public class VcnGatewayConnection extends StateMachine {
protected void setupInterface(
int token,
@NonNull IpSecTunnelInterface tunnelIface,
- @NonNull VcnChildSessionConfiguration childConfig) {
- setupInterface(token, tunnelIface, childConfig, null);
- }
-
- protected void setupInterface(
- int token,
- @NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig,
@Nullable VcnChildSessionConfiguration oldChildConfig) {
try {
@@ -1579,16 +1608,17 @@ public class VcnGatewayConnection extends StateMachine {
transformCreatedInfo.direction);
break;
case EVENT_SETUP_COMPLETED:
+ final VcnChildSessionConfiguration oldChildConfig = mChildConfig;
mChildConfig = ((EventSetupCompletedInfo) msg.obj).childSessionConfig;
- setupInterfaceAndNetworkAgent(mCurrentToken, mTunnelIface, mChildConfig);
+ setupInterfaceAndNetworkAgent(
+ mCurrentToken, mTunnelIface, mChildConfig, oldChildConfig);
break;
case EVENT_DISCONNECT_REQUESTED:
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
break;
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
- mGatewayStatusCallback.onEnteredSafeMode();
- mSafeModeTimeoutAlarm = null;
+ handleSafeModeTimeoutExceeded();
break;
default:
logUnhandledMessage(msg);
@@ -1626,8 +1656,9 @@ public class VcnGatewayConnection extends StateMachine {
protected void setupInterfaceAndNetworkAgent(
int token,
@NonNull IpSecTunnelInterface tunnelIface,
- @NonNull VcnChildSessionConfiguration childConfig) {
- setupInterface(token, tunnelIface, childConfig);
+ @NonNull VcnChildSessionConfiguration childConfig,
+ @NonNull VcnChildSessionConfiguration oldChildConfig) {
+ setupInterface(token, tunnelIface, childConfig, oldChildConfig);
if (mNetworkAgent == null) {
mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig);
@@ -1692,8 +1723,7 @@ public class VcnGatewayConnection extends StateMachine {
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
break;
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
- mGatewayStatusCallback.onEnteredSafeMode();
- mSafeModeTimeoutAlarm = null;
+ handleSafeModeTimeoutExceeded();
break;
default:
logUnhandledMessage(msg);
@@ -1935,6 +1965,16 @@ public class VcnGatewayConnection extends StateMachine {
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
+ NetworkAgent getNetworkAgent() {
+ return mNetworkAgent;
+ }
+
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
+ void setNetworkAgent(@Nullable NetworkAgent networkAgent) {
+ mNetworkAgent = networkAgent;
+ }
+
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
void sendDisconnectRequestedAndAcquireWakelock(String reason, boolean shouldQuit) {
sendMessageAndAcquireWakeLock(
EVENT_DISCONNECT_REQUESTED,
@@ -2018,6 +2058,38 @@ public class VcnGatewayConnection extends StateMachine {
return new WakeupMessage(vcnContext.getContext(), handler, tag, runnable);
}
+ /** Builds a new NetworkAgent. */
+ public NetworkAgent newNetworkAgent(
+ @NonNull VcnContext vcnContext,
+ @NonNull String tag,
+ @NonNull NetworkCapabilities caps,
+ @NonNull LinkProperties lp,
+ @NonNull int score,
+ @NonNull NetworkAgentConfig nac,
+ @NonNull NetworkProvider provider,
+ @NonNull Runnable networkUnwantedCallback,
+ @NonNull Consumer<Integer> validationStatusCallback) {
+ return new NetworkAgent(
+ vcnContext.getContext(),
+ vcnContext.getLooper(),
+ tag,
+ caps,
+ lp,
+ score,
+ nac,
+ provider) {
+ @Override
+ public void onNetworkUnwanted() {
+ networkUnwantedCallback.run();
+ }
+
+ @Override
+ public void onValidationStatus(int status, @Nullable Uri redirectUri) {
+ validationStatusCallback.accept(status);
+ }
+ };
+ }
+
/** Gets the elapsed real time since boot, in millis. */
public long getElapsedRealTime() {
return SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c9af62bcfd61..b1606c9e5d2d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -776,6 +776,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (mTmpInitial) {
w.resetContentChanged();
}
+ w.mSurfacePlacementNeeded = true;
w.mLayoutNeeded = false;
w.prelayout();
final boolean firstLayout = !w.isLaidOut();
@@ -818,6 +819,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
w.resetContentChanged();
}
+ w.mSurfacePlacementNeeded = true;
w.mLayoutNeeded = false;
w.prelayout();
getDisplayPolicy().layoutWindowLw(w, w.getParentWindow(), mDisplayFrames);
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index f31a64355aa0..510c62d9029f 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -240,6 +240,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
@Override
public void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
+ prefix = prefix + " ";
pw.print(prefix);
pw.print("mImeShowing=");
pw.print(mImeShowing);
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 7b0fb0146bc2..073231401715 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -63,7 +63,7 @@ import java.util.function.Consumer;
/**
* Controller for a specific inset source on the server. It's called provider as it provides the
- * {@link InsetsSource} to the client that uses it in {@link InsetsSourceConsumer}.
+ * {@link InsetsSource} to the client that uses it in {@link android.view.InsetsSourceConsumer}.
*/
class InsetsSourceProvider {
@@ -452,40 +452,36 @@ class InsetsSourceProvider {
}
public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "InsetsSourceProvider");
- pw.print(prefix + " mSource="); mSource.dump(prefix + " ", pw);
+ pw.println(prefix + getClass().getSimpleName());
+ prefix = prefix + " ";
+ pw.print(prefix + "mSource="); mSource.dump("", pw);
if (mControl != null) {
- pw.print(prefix + " mControl=");
- mControl.dump(prefix + " ", pw);
+ pw.print(prefix + "mControl=");
+ mControl.dump("", pw);
}
- pw.print(prefix + " mFakeControl="); mFakeControl.dump(prefix + " ", pw);
- pw.print(" mIsLeashReadyForDispatching="); pw.print(mIsLeashReadyForDispatching);
- pw.print(" mImeOverrideFrame="); pw.print(mImeOverrideFrame.toString());
+ pw.print(prefix);
+ pw.print("mIsLeashReadyForDispatching="); pw.print(mIsLeashReadyForDispatching);
+ pw.print(" mImeOverrideFrame="); pw.print(mImeOverrideFrame.toShortString());
+ pw.println();
if (mWin != null) {
- pw.print(prefix + " mWin=");
- mWin.dump(pw, prefix + " ", false /* dumpAll */);
+ pw.print(prefix + "mWin=");
+ pw.println(mWin);
}
if (mAdapter != null) {
- pw.print(prefix + " mAdapter=");
- mAdapter.dump(pw, prefix + " ");
+ pw.print(prefix + "mAdapter=");
+ mAdapter.dump(pw, "");
}
if (mControlTarget != null) {
- pw.print(prefix + " mControlTarget=");
- if (mControlTarget.getWindow() != null) {
- mControlTarget.getWindow().dump(pw, prefix + " ", false /* dumpAll */);
- }
+ pw.print(prefix + "mControlTarget=");
+ pw.println(mControlTarget.getWindow());
}
if (mPendingControlTarget != null) {
- pw.print(prefix + " mPendingControlTarget=");
- if (mPendingControlTarget.getWindow() != null) {
- mPendingControlTarget.getWindow().dump(pw, prefix + " ", false /* dumpAll */);
- }
+ pw.print(prefix + "mPendingControlTarget=");
+ pw.println(mPendingControlTarget.getWindow());
}
if (mFakeControlTarget != null) {
- pw.print(prefix + " mFakeControlTarget=");
- if (mFakeControlTarget.getWindow() != null) {
- mFakeControlTarget.getWindow().dump(pw, prefix + " ", false /* dumpAll */);
- }
+ pw.print(prefix + "mFakeControlTarget=");
+ pw.println(mFakeControlTarget.getWindow());
}
}
@@ -575,8 +571,9 @@ class InsetsSourceProvider {
@Override
public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "ControlAdapter");
- pw.print(prefix + " mCapturedLeash="); pw.print(mCapturedLeash);
+ pw.print(prefix + "ControlAdapter mCapturedLeash=");
+ pw.print(mCapturedLeash);
+ pw.println();
}
@Override
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index b6057c610277..655007cf3cd1 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -573,18 +573,17 @@ class InsetsStateController {
void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "WindowInsetsStateController");
- mState.dump(prefix + " ", pw);
- pw.println(prefix + " " + "Control map:");
+ prefix = prefix + " ";
+ mState.dump(prefix, pw);
+ pw.println(prefix + "Control map:");
for (int i = mTypeControlTargetMap.size() - 1; i >= 0; i--) {
pw.print(prefix + " ");
pw.println(InsetsState.typeToString(mTypeControlTargetMap.keyAt(i)) + " -> "
+ mTypeControlTargetMap.valueAt(i));
}
- pw.println(prefix + " " + "InsetsSourceProviders map:");
+ pw.println(prefix + "InsetsSourceProviders:");
for (int i = mProviders.size() - 1; i >= 0; i--) {
- pw.print(prefix + " ");
- pw.println(InsetsState.typeToString(mProviders.keyAt(i)) + " -> ");
- mProviders.valueAt(i).dump(pw, prefix);
+ mProviders.valueAt(i).dump(pw, prefix + " ");
}
}
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 4f8ea1ac377a..869133ae948c 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -171,7 +171,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
final boolean hasExistingActivity = targetActivity != null;
if (hasExistingActivity) {
mRestoreTargetBehindRootTask = getRootTaskAbove(targetRootTask);
- if (mRestoreTargetBehindRootTask == null) {
+ if (mRestoreTargetBehindRootTask == null
+ && targetRootTask.getTopMostTask() == targetActivity.getTask()) {
notifyAnimationCancelBeforeStart(recentsAnimationRunner);
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
"No root task above target root task=%s", targetRootTask);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 95f3c3711136..c7661254bed4 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -513,6 +513,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
*/
boolean mLayoutNeeded;
+ /**
+ * If the application is not currently visible but requires a layout,
+ * then make sure we call performSurfacePlacement as well. This is set
+ * in layout if mLayoutNeeded is set until surface placement is done.
+ */
+ boolean mSurfacePlacementNeeded;
+
/** Currently running an exit animation? */
boolean mAnimatingExit;
@@ -4281,7 +4288,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
pw.println(prefix + "mEmbeddedDisplayContents=" + mEmbeddedDisplayContents);
}
if (dumpAll) {
- pw.println(prefix + "mRequestedInsetsState: " + mRequestedInsetsState);
+ final String visibilityString = mRequestedInsetsState.toSourceVisibilityString();
+ if (!visibilityString.isEmpty()) {
+ pw.println(prefix + "Requested visibility: " + visibilityString);
+ }
}
}
@@ -5367,7 +5377,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mIsDimming = false;
applyDims();
updateSurfacePositionNonOrganized();
- // Send information to SufaceFlinger about the priority of the current window.
+ // Send information to SurfaceFlinger about the priority of the current window.
updateFrameRateSelectionPriorityIfNeeded();
if (isVisibleRequested()) updateGlobalScaleIfNeeded();
@@ -5381,13 +5391,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mSurfaceControl == null) {
return;
}
- if (mWmService.mWindowPlacerLocked.isLayoutDeferred() || isGoneForLayout()) {
+
+ if ((mWmService.mWindowPlacerLocked.isLayoutDeferred() || isGoneForLayout())
+ && !mSurfacePlacementNeeded) {
// Since this relies on mWindowFrames, changes made while layout is deferred are
// likely to be invalid. Similarly, if it's goneForLayout, mWindowFrames may not be
// up-to-date and thus can't be relied on.
return;
}
+ mSurfacePlacementNeeded = false;
transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
mSurfacePosition);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6f71e991bb96..fbf677dd0967 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -103,6 +103,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.ILockSettings;
import com.android.server.am.ActivityManagerService;
import com.android.server.appbinding.AppBindingService;
+import com.android.server.art.ArtManagerLocal;
import com.android.server.attention.AttentionManagerService;
import com.android.server.audio.AudioService;
import com.android.server.biometrics.AuthService;
@@ -2610,6 +2611,10 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(GAME_MANAGER_SERVICE_CLASS);
t.traceEnd();
+ t.traceBegin("ArtManagerLocal");
+ LocalManagerRegistry.addManager(ArtManagerLocal.class, new ArtManagerLocal());
+ t.traceEnd();
+
t.traceBegin("StartBootPhaseDeviceSpecificServicesReady");
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
t.traceEnd();
diff --git a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
index db4346830efb..5f435f91d62f 100644
--- a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
+++ b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
@@ -406,6 +406,8 @@ public class SmartspacePerUserService extends
+ callbackCount + " callbacks.");
}
service.onCreateSmartspaceSessionLocked(mSmartspaceConfig, mSessionId, token);
+ mCallbacks.broadcast(
+ callback -> service.registerSmartspaceUpdatesLocked(mSessionId, callback));
}
}
}
diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp
index 06313da58da1..b136d00fccac 100644
--- a/services/tests/PackageManagerServiceTests/host/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/Android.bp
@@ -46,15 +46,7 @@ java_test_host {
":PackageManagerTestAppVersion4",
":PackageManagerTestAppOriginalOverride",
":PackageManagerServiceDeviceSideTests",
- ":PackageManagerTestIntentVerifier",
- ":PackageManagerTestIntentVerifierTarget1",
- ":PackageManagerTestIntentVerifierTarget2",
- ":PackageManagerTestIntentVerifierTarget3",
- ":PackageManagerTestIntentVerifierTarget4Base",
- ":PackageManagerTestIntentVerifierTarget4NoAutoVerify",
- ":PackageManagerTestIntentVerifierTarget4Wildcard",
- ":PackageManagerTestIntentVerifierTarget4WildcardNoAutoVerify",
- ]
+ ],
}
genrule {
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/intent/verify/IntentFilterVerificationTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/intent/verify/IntentFilterVerificationTest.kt
deleted file mode 100644
index fffda8ebd36c..000000000000
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/intent/verify/IntentFilterVerificationTest.kt
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm.test.intent.verify
-
-import com.android.internal.util.test.SystemPreparer
-import com.android.server.pm.test.Partition
-import com.android.server.pm.test.deleteApkFolders
-import com.android.server.pm.test.installJavaResourceApk
-import com.android.server.pm.test.pushApk
-import com.android.server.pm.test.uninstallPackages
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.ClassRule
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.RuleChain
-import org.junit.rules.TemporaryFolder
-import org.junit.runner.RunWith
-import java.io.File
-import java.util.concurrent.TimeUnit
-
-@RunWith(DeviceJUnit4ClassRunner::class)
-class IntentFilterVerificationTest : BaseHostJUnit4Test() {
-
- companion object {
- private const val VERIFIER = "PackageManagerTestIntentVerifier.apk"
- private const val VERIFIER_PKG_NAME = "com.android.server.pm.test.intent.verifier"
- private const val TARGET_PKG_PREFIX = "$VERIFIER_PKG_NAME.target"
- private const val TARGET_APK_PREFIX = "PackageManagerTestIntentVerifierTarget"
- private const val TARGET_ONE = "${TARGET_APK_PREFIX}1.apk"
- private const val TARGET_ONE_PKG_NAME = "$TARGET_PKG_PREFIX.one"
- private const val TARGET_TWO = "${TARGET_APK_PREFIX}2.apk"
- private const val TARGET_TWO_PKG_NAME = "$TARGET_PKG_PREFIX.two"
- private const val TARGET_THREE = "${TARGET_APK_PREFIX}3.apk"
- private const val TARGET_THREE_PKG_NAME = "$TARGET_PKG_PREFIX.three"
- private const val TARGET_FOUR_BASE = "${TARGET_APK_PREFIX}4Base.apk"
- private const val TARGET_FOUR_PKG_NAME = "$TARGET_PKG_PREFIX.four"
- private const val TARGET_FOUR_NO_AUTO_VERIFY = "${TARGET_APK_PREFIX}4NoAutoVerify.apk"
- private const val TARGET_FOUR_WILDCARD = "${TARGET_APK_PREFIX}4Wildcard.apk"
- private const val TARGET_FOUR_WILDCARD_NO_AUTO_VERIFY =
- "${TARGET_APK_PREFIX}4WildcardNoAutoVerify.apk"
-
- @get:ClassRule
- val deviceRebootRule = SystemPreparer.TestRuleDelegate(true)
- }
-
- private val tempFolder = TemporaryFolder()
- private val preparer: SystemPreparer = SystemPreparer(tempFolder,
- SystemPreparer.RebootStrategy.FULL, deviceRebootRule) { this.device }
-
- @Rule
- @JvmField
- val rules = RuleChain.outerRule(tempFolder).around(preparer)!!
-
- private val permissionsFile = File("/system/etc/permissions" +
- "/privapp-PackageManagerIntentFilterVerificationTest-permissions.xml")
-
- @Before
- fun cleanupAndPushPermissionsFile() {
- // In order for the test app to be the verification agent, it needs a permission file
- // which can be pushed onto the system and removed afterwards.
- val file = tempFolder.newFile().apply {
- """
- <permissions>
- <privapp-permissions package="$VERIFIER_PKG_NAME">
- <permission name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"/>
- </privapp-permissions>
- </permissions>
- """
- .trimIndent()
- .let { writeText(it) }
- }
- device.uninstallPackages(TARGET_ONE_PKG_NAME, TARGET_TWO_PKG_NAME, TARGET_THREE_PKG_NAME,
- TARGET_FOUR_PKG_NAME)
- preparer.pushApk(VERIFIER, Partition.SYSTEM_PRIVILEGED)
- .pushFile(file, permissionsFile.toString())
- .reboot()
- runTest("clearResponse")
- }
-
- @After
- fun cleanupAndDeletePermissionsFile() {
- device.uninstallPackages(TARGET_ONE_PKG_NAME, TARGET_TWO_PKG_NAME, TARGET_THREE_PKG_NAME,
- TARGET_FOUR_PKG_NAME)
- preparer.deleteApkFolders(Partition.SYSTEM_PRIVILEGED, VERIFIER)
- .deleteFile(permissionsFile.toString())
- device.reboot()
- }
-
- @Test
- fun verifyOne() {
- installPackage(TARGET_ONE)
-
- assertReceivedRequests(true, VerifyRequest(
- scheme = "https",
- hosts = listOf(
- "https_only.pm.server.android.com",
- "other_activity.pm.server.android.com",
- "http_only.pm.server.android.com",
- "verify.pm.server.android.com",
- "https_plus_non_web_scheme.pm.server.android.com",
- "multiple.pm.server.android.com",
- // TODO(b/159952358): the following domain should not be
- // verified, this is because the verifier tries to verify all web domains,
- // even in intent filters not marked for auto verify
- "no_verify.pm.server.android.com"
- ),
- packageName = TARGET_ONE_PKG_NAME
- ))
-
- runTest(StartActivityParams(
- uri = "https://https_only.pm.server.android.com",
- expected = "$TARGET_ONE_PKG_NAME.TargetActivity"
- ))
- }
-
- @Test
- fun nonWebScheme() {
- installPackage(TARGET_TWO)
- assertReceivedRequests(null)
- }
-
- @Test
- fun verifyHttpNonSecureOnly() {
- installPackage(TARGET_THREE)
- assertReceivedRequests(true, VerifyRequest(
- scheme = "https",
- hosts = listOf(
- "multiple.pm.server.android.com"
- ),
- packageName = TARGET_THREE_PKG_NAME
- ))
-
- runTest(StartActivityParams(
- uri = "http://multiple.pm.server.android.com",
- expected = "$TARGET_THREE_PKG_NAME.TargetActivity"
- ))
- }
-
- @Test
- fun multipleResults() {
- installPackage(TARGET_ONE)
- installPackage(TARGET_THREE)
- assertReceivedRequests(true, VerifyRequest(
- scheme = "https",
- hosts = listOf(
- "https_only.pm.server.android.com",
- "other_activity.pm.server.android.com",
- "http_only.pm.server.android.com",
- "verify.pm.server.android.com",
- "https_plus_non_web_scheme.pm.server.android.com",
- "multiple.pm.server.android.com",
- // TODO(b/159952358): the following domain should not be
- // verified, this is because the verifier tries to verify all web domains,
- // even in intent filters not marked for auto verify
- "no_verify.pm.server.android.com"
- ),
- packageName = TARGET_ONE_PKG_NAME
- ), VerifyRequest(
- scheme = "https",
- hosts = listOf(
- "multiple.pm.server.android.com"
- ),
- packageName = TARGET_THREE_PKG_NAME
- ))
-
- // Target3 declares http non-s, so it should be included in the set here
- runTest(StartActivityParams(
- uri = "http://multiple.pm.server.android.com",
- expected = listOf(
- "$TARGET_ONE_PKG_NAME.TargetActivity2",
- "$TARGET_THREE_PKG_NAME.TargetActivity"
- )
- ))
-
- // But it excludes https, so it shouldn't resolve here
- runTest(StartActivityParams(
- uri = "https://multiple.pm.server.android.com",
- expected = "$TARGET_ONE_PKG_NAME.TargetActivity2"
- ))
-
- // Remove Target3 and return to single verified Target1 app for http non-s
- device.uninstallPackage(TARGET_THREE_PKG_NAME)
- runTest(StartActivityParams(
- uri = "http://multiple.pm.server.android.com",
- expected = "$TARGET_ONE_PKG_NAME.TargetActivity2"
- ))
- }
-
- @Test
- fun demoteAlways() {
- installPackage(TARGET_FOUR_BASE)
- assertReceivedRequests(false, VerifyRequest(
- scheme = "https",
- host = "failing.pm.server.android.com",
- packageName = TARGET_FOUR_PKG_NAME
- ))
-
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity",
- withBrowsers = true
- ))
- runTest(SetActivityAsAlwaysParams(
- uri = "https://failing.pm.server.android.com",
- packageName = TARGET_FOUR_PKG_NAME,
- activityName = "$TARGET_FOUR_PKG_NAME.TargetActivity"
- ))
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
- ))
-
- // Re-installing with same host/verify set will maintain always setting
- installPackage(TARGET_FOUR_BASE)
- assertReceivedRequests(null)
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
- ))
-
- // Installing with new wildcard host will downgrade out of always, re-including browsers
- installPackage(TARGET_FOUR_WILDCARD)
-
- // TODO(b/159952358): The first request without the wildcard should not be sent. This is
- // caused by the request being queued even if it should be dropped from the previous
- // install case since the host set didn't change.
- assertReceivedRequests(false, VerifyRequest(
- scheme = "https",
- hosts = listOf("failing.pm.server.android.com"),
- packageName = TARGET_FOUR_PKG_NAME
- ), VerifyRequest(
- scheme = "https",
- hosts = listOf("failing.pm.server.android.com", "wildcard.tld"),
- packageName = TARGET_FOUR_PKG_NAME
- ))
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity",
- withBrowsers = true
- ))
- }
-
- @Test
- fun unverifiedReinstallResendRequest() {
- installPackage(TARGET_FOUR_BASE)
- assertReceivedRequests(false, VerifyRequest(
- scheme = "https",
- host = "failing.pm.server.android.com",
- packageName = TARGET_FOUR_PKG_NAME
- ))
-
- installPackage(TARGET_FOUR_BASE)
-
- assertReceivedRequests(false, VerifyRequest(
- scheme = "https",
- host = "failing.pm.server.android.com",
- packageName = TARGET_FOUR_PKG_NAME
- ))
- }
-
- @Test
- fun unverifiedUpdateRemovingDomainNoRequestDemoteAlways() {
- installPackage(TARGET_FOUR_WILDCARD)
- assertReceivedRequests(false, VerifyRequest(
- scheme = "https",
- hosts = listOf("failing.pm.server.android.com", "wildcard.tld"),
- packageName = TARGET_FOUR_PKG_NAME
- ))
-
- runTest(SetActivityAsAlwaysParams(
- uri = "https://failing.pm.server.android.com",
- packageName = TARGET_FOUR_PKG_NAME,
- activityName = "$TARGET_FOUR_PKG_NAME.TargetActivity"
- ))
-
- // Re-installing with a smaller host/verify set will not request re-verification
- installPackage(TARGET_FOUR_BASE)
- assertReceivedRequests(null)
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
- ))
-
- // Re-installing with a (now) larger host/verify set will re-request and demote
- installPackage(TARGET_FOUR_WILDCARD)
- // TODO(b/159952358): The first request should not be sent. This is caused by the request
- // being queued even if it should be dropped from the previous install case.
- assertReceivedRequests(false, VerifyRequest(
- scheme = "https",
- host = "failing.pm.server.android.com",
- packageName = TARGET_FOUR_PKG_NAME
- ), VerifyRequest(
- scheme = "https",
- hosts = listOf("failing.pm.server.android.com", "wildcard.tld"),
- packageName = TARGET_FOUR_PKG_NAME
- ))
-
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity",
- withBrowsers = true
- ))
- }
-
- // TODO(b/159952358): I would expect this to demote
- // TODO(b/32810168)
- @Test
- fun verifiedUpdateRemovingAutoVerifyMaintainsAlways() {
- installPackage(TARGET_FOUR_BASE)
- assertReceivedRequests(true, VerifyRequest(
- scheme = "https",
- host = "failing.pm.server.android.com",
- packageName = TARGET_FOUR_PKG_NAME
- ))
-
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
- ))
-
- installPackage(TARGET_FOUR_NO_AUTO_VERIFY)
- assertReceivedRequests(null)
-
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
- ))
- }
-
- @Test
- fun verifiedUpdateRemovingAutoVerifyAddingDomainDemotesAlways() {
- installPackage(TARGET_FOUR_BASE)
-
- assertReceivedRequests(true, VerifyRequest(
- scheme = "https",
- host = "failing.pm.server.android.com",
- packageName = TARGET_FOUR_PKG_NAME
- ))
-
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
- ))
-
- installPackage(TARGET_FOUR_WILDCARD_NO_AUTO_VERIFY)
- assertReceivedRequests(null)
-
- runTest(StartActivityParams(
- uri = "https://failing.pm.server.android.com",
- expected = "$TARGET_FOUR_PKG_NAME.TargetActivity",
- withBrowsers = true
- ))
- }
-
- private fun installPackage(javaResourceName: String) {
- // Need to pass --user as verification is not currently run for all user installs
- assertThat(device.installJavaResourceApk(tempFolder, javaResourceName,
- extraArgs = arrayOf("--user", device.currentUser.toString()))).isNull()
- }
-
- private fun assertReceivedRequests(success: Boolean?, vararg expected: VerifyRequest?) {
- // TODO(b/159952358): This can probably be less than 10
- // Because tests have to assert that multiple broadcasts aren't received, there's no real
- // better way to await for a value than sleeping for a long enough time.
- TimeUnit.SECONDS.sleep(10)
-
- val params = mutableMapOf<String, String>()
- if (expected.any { it != null }) {
- params["expected"] = expected.filterNotNull()
- .joinToString(separator = "") { it.serializeToString() }
- }
- runTest("compareLastReceived", params)
-
- if (success != null) {
- if (success) {
- runTest("verifyPreviousReceivedSuccess")
- } else {
- runTest("verifyPreviousReceivedFailure")
- }
- runTest("clearResponse")
- }
- }
-
- private fun runTest(params: IntentVerifyTestParams) =
- runTest(params.methodName, params.toArgsMap())
-
- private fun runTest(testName: String, args: Map<String, String> = emptyMap()) {
- val escapedArgs = args.mapValues {
- // Need to escape strings so that args are passed properly through the shell command
- "\"${it.value.trim('"')}\""
- }
- runDeviceTests(device, null, VERIFIER_PKG_NAME, "$VERIFIER_PKG_NAME.VerifyReceiverTest",
- testName, null, 10 * 60 * 1000L, 10 * 60 * 1000L, 0L, true, false, escapedArgs)
- }
-}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/Android.bp
deleted file mode 100644
index 4f3f2eb1b58e..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/Android.bp
+++ /dev/null
@@ -1,37 +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 {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test_helper_app {
- name: "PackageManagerTestIntentVerifier",
- srcs: [ "src/**/*.kt" ],
- static_libs: [
- "androidx.test.core",
- "androidx.test.espresso.core",
- "androidx.test.runner",
- "compatibility-device-util-axt",
- "junit",
- "truth-prebuilt",
- "PackageManagerServiceHostTestsIntentVerifyUtils",
- ],
- platform_apis: true,
-}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/AndroidManifest.xml
deleted file mode 100644
index 17b50b0ec949..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.intent.verifier"
- >
-
- <uses-permission android:name="android.permission.INTENT_FILTER_VERIFICATION_AGENT" />
- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
- <uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
-
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.server.pm.test.intent.verifier"
- />
-
- <application>
- <receiver android:name=".VerifyReceiver" android:exported="true">
- <intent-filter android:priority="999">
- <action android:name="android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION"/>
- <data android:mimeType="application/vnd.android.package-archive"/>
- </intent-filter>
- </receiver>
- </application>
-
-</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/src/com/android/server/pm/test/intent/verifier/VerifyReceiver.kt b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/src/com/android/server/pm/test/intent/verifier/VerifyReceiver.kt
deleted file mode 100644
index 073c2be75424..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/src/com/android/server/pm/test/intent/verifier/VerifyReceiver.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm.test.intent.verifier
-
-import android.content.BroadcastReceiver
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.content.pm.PackageManager
-import com.android.server.pm.test.intent.verify.VerifyRequest
-
-class VerifyReceiver : BroadcastReceiver() {
-
- override fun onReceive(context: Context, intent: Intent) {
- if (intent.action != Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION) return
- val params = intent.toVerifyParams()
-
- // If the receiver is called for a normal request, proxy it to the real verifier on device
- if (params.hosts.none { it.contains("pm.server.android.com") }) {
- sendToRealVerifier(context, Intent(intent))
- return
- }
-
- // When the receiver is invoked for a test install, there is no direct connection to host,
- // so store the result in a file to read and assert on later. Append is intentional so that
- // amount of invocations and clean up can be verified.
- context.filesDir.resolve("test.txt")
- .appendText(params.serializeToString())
- }
-
- private fun sendToRealVerifier(context: Context, intent: Intent) {
- context.packageManager.queryBroadcastReceivers(intent, 0)
- .first { it.activityInfo?.packageName != context.packageName }
- .let { it.activityInfo!! }
- .let { intent.setComponent(ComponentName(it.packageName, it.name)) }
- .run { context.sendBroadcast(intent) }
- }
-
- private fun Intent.toVerifyParams() = VerifyRequest(
- id = getIntExtra(PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, -1),
- scheme = getStringExtra(PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME)!!,
- hosts = getStringExtra(PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS)!!
- .split(' '),
- packageName = getStringExtra(
- PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME)!!
-
- )
-}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/src/com/android/server/pm/test/intent/verifier/VerifyReceiverTest.kt b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/src/com/android/server/pm/test/intent/verifier/VerifyReceiverTest.kt
deleted file mode 100644
index 23ed278e04ef..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifier/src/com/android/server/pm/test/intent/verifier/VerifyReceiverTest.kt
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm.test.intent.verifier
-
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.content.pm.PackageManager
-import android.net.Uri
-import android.os.Bundle
-import android.os.UserHandle
-import androidx.test.InstrumentationRegistry
-import androidx.test.runner.AndroidJUnit4
-import com.android.compatibility.common.util.ShellIdentityUtils
-import com.android.server.pm.test.intent.verify.SetActivityAsAlwaysParams
-import com.android.server.pm.test.intent.verify.StartActivityParams
-import com.android.server.pm.test.intent.verify.VerifyRequest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import java.io.File
-
-@RunWith(AndroidJUnit4::class)
-class VerifyReceiverTest {
-
- val args: Bundle = InstrumentationRegistry.getArguments()
- val context: Context = InstrumentationRegistry.getContext()
-
- private val file = context.filesDir.resolve("test.txt")
-
- @Test
- fun clearResponse() {
- file.delete()
- }
-
- @Test
- fun compareLastReceived() {
- val lastReceivedText = file.readTextIfExists()
- val expectedText = args.getString("expected")
- if (expectedText.isNullOrEmpty()) {
- assertThat(lastReceivedText).isEmpty()
- return
- }
-
- val expectedParams = expectedText.parseParams()
- val lastReceivedParams = lastReceivedText.parseParams()
-
- assertThat(lastReceivedParams).hasSize(expectedParams.size)
-
- lastReceivedParams.zip(expectedParams).forEach { (actual, expected) ->
- assertThat(actual.hosts).containsExactlyElementsIn(expected.hosts)
- assertThat(actual.packageName).isEqualTo(expected.packageName)
- assertThat(actual.scheme).isEqualTo(expected.scheme)
- }
- }
-
- @Test
- fun setActivityAsAlways() {
- val params = SetActivityAsAlwaysParams.fromArgs(
- args.keySet().associateWith { args.getString(it)!! })
- val uri = Uri.parse(params.uri)
- val filter = IntentFilter().apply {
- addAction(Intent.ACTION_VIEW)
- addCategory(Intent.CATEGORY_DEFAULT)
- addCategory(Intent.CATEGORY_BROWSABLE)
- addDataScheme(uri.scheme)
- addDataAuthority(uri.authority, null)
- }
-
- val intent = Intent(Intent.ACTION_VIEW, uri).apply {
- addCategory(Intent.CATEGORY_DEFAULT)
- addCategory(Intent.CATEGORY_BROWSABLE)
- }
- val allResults = context.packageManager.queryIntentActivities(intent, 0)
- val allComponents = allResults
- .map { ComponentName(it.activityInfo.packageName, it.activityInfo.name) }
- .toTypedArray()
- val matchingInfo = allResults.first {
- it.activityInfo.packageName == params.packageName &&
- it.activityInfo.name == params.activityName
- }
-
- ShellIdentityUtils.invokeMethodWithShellPermissions(context.packageManager,
- ShellIdentityUtils.ShellPermissionMethodHelper<Unit, PackageManager> {
- it.addUniquePreferredActivity(filter, matchingInfo.match, allComponents,
- ComponentName(matchingInfo.activityInfo.packageName,
- matchingInfo.activityInfo.name))
- it.updateIntentVerificationStatusAsUser(params.packageName,
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
- UserHandle.myUserId())
- }, "android.permission.SET_PREFERRED_APPLICATIONS")
- }
-
- @Test
- fun verifyPreviousReceivedSuccess() {
- file.readTextIfExists()
- .parseParams()
- .forEach {
- context.packageManager.verifyIntentFilter(it.id,
- PackageManager.INTENT_FILTER_VERIFICATION_SUCCESS, emptyList())
- }
- }
-
- @Test
- fun verifyPreviousReceivedFailure() {
- file.readTextIfExists()
- .parseParams()
- .forEach {
- context.packageManager.verifyIntentFilter(it.id,
- PackageManager.INTENT_FILTER_VERIFICATION_FAILURE, it.hosts)
- }
- }
-
- @Test
- fun verifyActivityStart() {
- val params = StartActivityParams
- .fromArgs(args.keySet().associateWith { args.getString(it)!! })
- val uri = Uri.parse(params.uri)
- val intent = Intent(Intent.ACTION_VIEW).apply {
- data = uri
- addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- addCategory(Intent.CATEGORY_DEFAULT)
- addCategory(Intent.CATEGORY_BROWSABLE)
- }
-
- val expectedActivities = params.expected.toMutableList()
-
- if (params.withBrowsers) {
- // Since the host doesn't know what browsers the device has, query here and add it to
- // set if it's expected that browser are returned
- val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"))
- expectedActivities += context.packageManager.queryIntentActivities(browserIntent, 0)
- .map { it.activityInfo.name }
- }
-
- val infos = context.packageManager.queryIntentActivities(intent, 0)
- .map { it.activityInfo.name }
- assertThat(infos).containsExactlyElementsIn(expectedActivities)
- }
-
- private fun File.readTextIfExists() = if (exists()) readText() else ""
-
- // Rudimentary list deserialization by splitting text block into 4 line sections
- private fun String.parseParams() = trim()
- .lines()
- .windowed(4, 4)
- .map { it.joinToString(separator = "\n") }
- .map { VerifyRequest.deserialize(it) }
-}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/Android.bp
deleted file mode 100644
index 9f9ed24c63bc..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/Android.bp
+++ /dev/null
@@ -1,57 +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 {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test_helper_app {
- name: "PackageManagerTestIntentVerifierTarget1",
- manifest: "AndroidManifest1.xml",
-}
-
-android_test_helper_app {
- name: "PackageManagerTestIntentVerifierTarget2",
- manifest: "AndroidManifest2.xml",
-}
-
-android_test_helper_app {
- name: "PackageManagerTestIntentVerifierTarget3",
- manifest: "AndroidManifest3.xml",
-}
-
-android_test_helper_app {
- name: "PackageManagerTestIntentVerifierTarget4Base",
- manifest: "AndroidManifest4Base.xml",
-}
-
-android_test_helper_app {
- name: "PackageManagerTestIntentVerifierTarget4NoAutoVerify",
- manifest: "AndroidManifest4NoAutoVerify.xml",
-}
-
-android_test_helper_app {
- name: "PackageManagerTestIntentVerifierTarget4Wildcard",
- manifest: "AndroidManifest4Wildcard.xml",
-}
-
-android_test_helper_app {
- name: "PackageManagerTestIntentVerifierTarget4WildcardNoAutoVerify",
- manifest: "AndroidManifest4WildcardNoAutoVerify.xml",
-}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest1.xml b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest1.xml
deleted file mode 100644
index 6cf5c7619a30..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest1.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.intent.verifier.target.one" android:versionCode="1">
-
- <application>
- <activity android:name=".TargetActivity" android:exported="true">
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:host="verify.pm.server.android.com" />
- </intent-filter>
-
- <intent-filter android:autoVerify="false">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:host="no_verify.pm.server.android.com" />
- </intent-filter>
-
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:host="http_only.pm.server.android.com" />
- </intent-filter>
-
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="https" />
- <data android:host="https_only.pm.server.android.com" />
- </intent-filter>
-
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="htttps" />
- <data android:host="non_http.pm.server.android.com" />
- </intent-filter>
-
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="https" />
- <data android:scheme="non_web_scheme" />
- <data android:host="https_plus_non_web_scheme.pm.server.android.com" />
- </intent-filter>
- </activity>
-
- <activity android:name=".TargetActivity2" android:exported="true">
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:host="other_activity.pm.server.android.com" />
- </intent-filter>
-
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:host="multiple.pm.server.android.com" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest2.xml b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest2.xml
deleted file mode 100644
index 087ef70595f9..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest2.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.intent.verifier.target.two"
- android:versionCode="1">
-
- <application>
- <activity android:name=".TargetActivity" android:exported="true">
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:scheme="non_web_scheme" />
- <data android:host="only_https_plus_non_web_scheme.pm.server.android.com" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest3.xml b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest3.xml
deleted file mode 100644
index eb75b5e53bc8..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest3.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.intent.verifier.target.three"
- android:versionCode="1">
-
- <application>
- <activity android:name=".TargetActivity" android:exported="true">
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:host="multiple.pm.server.android.com" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4Base.xml b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4Base.xml
deleted file mode 100644
index 7eacb8bc8fb7..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4Base.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.intent.verifier.target.four"
- android:versionCode="1">
-
- <application>
- <activity android:name=".TargetActivity" android:exported="true">
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:host="failing.pm.server.android.com" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4NoAutoVerify.xml b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4NoAutoVerify.xml
deleted file mode 100644
index ecfee55b9c4a..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4NoAutoVerify.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.intent.verifier.target.four"
- android:versionCode="1">
-
- <application>
- <activity android:name=".TargetActivity" android:exported="true">
- <intent-filter android:autoVerify="false">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:host="failing.pm.server.android.com" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4Wildcard.xml b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4Wildcard.xml
deleted file mode 100644
index 0f0f53ba07e9..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4Wildcard.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.intent.verifier.target.four"
- android:versionCode="1">
-
- <application>
- <activity android:name=".TargetActivity" android:exported="true">
- <intent-filter android:autoVerify="true">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:host="failing.pm.server.android.com" />
- <data android:host="*.wildcard.tld" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4WildcardNoAutoVerify.xml b/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4WildcardNoAutoVerify.xml
deleted file mode 100644
index d5652e1b924d..000000000000
--- a/services/tests/PackageManagerServiceTests/host/test-apps/IntentVerifierTarget/AndroidManifest4WildcardNoAutoVerify.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.intent.verifier.target.four"
- android:versionCode="1">
-
- <application>
- <activity android:name=".TargetActivity" android:exported="true">
- <intent-filter android:autoVerify="false">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:host="failing.pm.server.android.com" />
- <data android:host="*.wildcard.tld" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 1c45203bb3c9..3404aff976d0 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -1361,6 +1361,52 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_ScheduleLikeTop() {
+ final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+ final ProcessRecord client1 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
+ MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
+ final ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID,
+ MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false));
+ bindService(app1, client1, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
+ mock(IBinder.class));
+ bindService(app2, client2, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
+ mock(IBinder.class));
+ client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
+ client2.mServices.setHasForegroundServices(true, 0);
+
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app1, false, OomAdjuster.OOM_ADJ_REASON_NONE);
+ sService.mOomAdjuster.updateOomAdjLocked(app2, false, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app1, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, VISIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+
+ bindService(app1, client1, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, mock(IBinder.class));
+ bindService(app2, client2, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, mock(IBinder.class));
+ sService.mOomAdjuster.updateOomAdjLocked(app1, false, OomAdjuster.OOM_ADJ_REASON_NONE);
+ sService.mOomAdjuster.updateOomAdjLocked(app2, false, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app1, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, VISIBLE_APP_ADJ,
+ SCHED_GROUP_TOP_APP);
+ assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_ASLEEP);
+ sService.mOomAdjuster.updateOomAdjLocked(app1, false, OomAdjuster.OOM_ADJ_REASON_NONE);
+ sService.mOomAdjuster.updateOomAdjLocked(app2, false, OomAdjuster.OOM_ADJ_REASON_NONE);
+ assertProcStates(app1, PROCESS_STATE_IMPORTANT_FOREGROUND, VISIBLE_APP_ADJ,
+ SCHED_GROUP_TOP_APP);
+ assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_UidIdle_StopService() {
final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 1b8f9c767e3e..0cd470ae7ec4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -654,7 +654,7 @@ public class ConnectivityControllerTest {
generalCallback.onCapabilitiesChanged(net, caps);
if (uidCallback != null) {
uidCallback.onAvailable(net);
- uidCallback.onBlockedStatusChanged(net, false);
+ uidCallback.onBlockedStatusChanged(net, ConnectivityManager.BLOCKED_REASON_NONE);
uidCallback.onCapabilitiesChanged(net, caps);
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/utils/SlogfTest.java b/services/tests/mockingservicestests/src/com/android/server/utils/SlogfTest.java
new file mode 100644
index 000000000000..3e8cef9afc15
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/utils/SlogfTest.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.utils;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+
+import android.util.Log;
+import android.util.Slog;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+/**
+ * Run it as {@code atest FrameworksMockingServicesTests:SlogfTest}
+ */
+public final class SlogfTest {
+
+ private static final String TAG = SlogfTest.class.getSimpleName();
+
+ private MockitoSession mSession;
+
+ private final Exception mException = new Exception("D'OH!");
+
+ @Before
+ public void setup() {
+ mSession = mockitoSession()
+ .initMocks(this)
+ .mockStatic(Slog.class)
+ .spyStatic(Slogf.class) // for isLoggable only
+ .strictness(Strictness.LENIENT)
+ .startMocking();
+ }
+
+ @After
+ public void tearDown() {
+ if (mSession == null) {
+ Log.w(TAG, "finishSession(): no session");
+ } else {
+ mSession.finishMocking();
+ }
+ }
+
+ @Test
+ public void testIsLoggable() {
+ assertThat(Slogf.isLoggable(TAG, Log.VERBOSE)).isEqualTo(Log.isLoggable(TAG, Log.VERBOSE));
+ }
+
+ @Test
+ public void testV_msg() {
+ Slogf.v(TAG, "msg");
+
+ verify(()-> Slog.v(TAG, "msg"));
+ }
+
+ @Test
+ public void testV_msgAndException() {
+ Slogf.v(TAG, "msg", mException);
+
+ verify(()-> Slog.v(TAG, "msg", mException));
+ }
+
+ @Test
+ public void testV_msgFormatted_enabled() {
+ enableLogging(Log.VERBOSE);
+
+ Slogf.v(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.v(TAG, "msg in a bottle"));
+ }
+
+ @Test
+ public void testV_msgFormatted_disabled() {
+ disableLogging(Log.VERBOSE);
+
+ Slogf.v(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.v(eq(TAG), any()), never());
+ }
+
+ @Test
+ public void testD_msg() {
+ Slogf.d(TAG, "msg");
+
+ verify(()-> Slog.d(TAG, "msg"));
+ }
+
+ @Test
+ public void testD_msgAndException() {
+ Slogf.d(TAG, "msg", mException);
+
+ verify(()-> Slog.d(TAG, "msg", mException));
+ }
+
+ @Test
+ public void testD_msgFormatted_enabled() {
+ enableLogging(Log.DEBUG);
+
+ Slogf.d(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.d(TAG, "msg in a bottle"));
+ }
+
+ @Test
+ public void testD_msgFormatted_disabled() {
+ disableLogging(Log.DEBUG);
+
+ Slogf.d(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.d(eq(TAG), any()), never());
+ }
+
+ @Test
+ public void testI_msg() {
+ Slogf.i(TAG, "msg");
+
+ verify(()-> Slog.i(TAG, "msg"));
+ }
+
+ @Test
+ public void testI_msgAndException() {
+ Slogf.i(TAG, "msg", mException);
+
+ verify(()-> Slog.i(TAG, "msg", mException));
+ }
+
+ @Test
+ public void testI_msgFormatted_enabled() {
+ enableLogging(Log.INFO);
+
+ Slogf.i(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.i(TAG, "msg in a bottle"));
+ }
+
+ @Test
+ public void testI_msgFormatted_disabled() {
+ disableLogging(Log.INFO);
+
+ Slogf.i(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.i(eq(TAG), any()), never());
+ }
+
+ @Test
+ public void testW_msg() {
+ Slogf.w(TAG, "msg");
+
+ verify(()-> Slog.w(TAG, "msg"));
+ }
+
+ @Test
+ public void testW_msgAndException() {
+ Slogf.w(TAG, "msg", mException);
+
+ verify(()-> Slog.w(TAG, "msg", mException));
+ }
+
+ @Test
+ public void testW_exception() {
+ Slogf.w(TAG, mException);
+
+ verify(()-> Slog.w(TAG, mException));
+ }
+
+ @Test
+ public void testW_msgFormatted_enabled() {
+ enableLogging(Log.WARN);
+
+ Slogf.w(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.w(TAG, "msg in a bottle"));
+ }
+
+ @Test
+ public void testW_msgFormatted_disabled() {
+ disableLogging(Log.WARN);
+
+ Slogf.w(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.w(eq(TAG), any(String.class)), never());
+ }
+
+ @Test
+ public void testW_msgFormattedWithException_enabled() {
+ enableLogging(Log.WARN);
+
+ Slogf.w(TAG, mException, "msg in a %s", "bottle");
+
+ verify(()-> Slog.w(TAG, "msg in a bottle", mException));
+ }
+
+ @Test
+ public void testW_msgFormattedWithException_disabled() {
+ disableLogging(Log.WARN);
+
+ Slogf.w(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.w(eq(TAG), any(String.class), any(Throwable.class)), never());
+ }
+
+ @Test
+ public void testE_msg() {
+ Slogf.e(TAG, "msg");
+
+ verify(()-> Slog.e(TAG, "msg"));
+ }
+
+ @Test
+ public void testE_msgAndException() {
+ Slogf.e(TAG, "msg", mException);
+
+ verify(()-> Slog.e(TAG, "msg", mException));
+ }
+
+ @Test
+ public void testE_msgFormatted_enabled() {
+ enableLogging(Log.ERROR);
+
+ Slogf.e(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.e(TAG, "msg in a bottle"));
+ }
+
+ @Test
+ public void testE_msgFormatted_disabled() {
+ disableLogging(Log.ERROR);
+
+ Slogf.e(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.e(eq(TAG), any()), never());
+ }
+
+ @Test
+ public void testE_msgFormattedWithException_enabled() {
+ enableLogging(Log.ERROR);
+
+ Slogf.e(TAG, mException, "msg in a %s", "bottle");
+
+ verify(()-> Slog.e(TAG, "msg in a bottle", mException));
+ }
+
+ @Test
+ public void testE_msgFormattedWithException_disabled() {
+ disableLogging(Log.ERROR);
+
+ Slogf.e(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.e(eq(TAG), any(String.class), any(Throwable.class)), never());
+ }
+
+ @Test
+ public void testWtf_msg() {
+ Slogf.wtf(TAG, "msg");
+
+ verify(()-> Slog.wtf(TAG, "msg"));
+ }
+
+ @Test
+ public void testWtf_msgAndException() {
+ Slogf.wtf(TAG, "msg", mException);
+
+ verify(()-> Slog.wtf(TAG, "msg", mException));
+ }
+
+ @Test
+ public void testWtf_exception() {
+ Slogf.wtf(TAG, mException);
+
+ verify(()-> Slog.wtf(TAG, mException));
+ }
+
+ @Test
+ public void testWtf_msgFormatted() {
+ Slogf.wtf(TAG, "msg in a %s", "bottle");
+
+ verify(()-> Slog.wtf(TAG, "msg in a bottle"));
+ }
+
+ @Test
+ public void testWtfQuiet() {
+ Slogf.wtfQuiet(TAG, "msg");
+
+ verify(()-> Slog.wtfQuiet(TAG, "msg"));
+ }
+
+ @Test
+ public void testWtfStack() {
+ Slogf.wtfStack(TAG, "msg");
+
+ verify(()-> Slog.wtfStack(TAG, "msg"));
+ }
+
+ @Test
+ public void testPrintln() {
+ Slogf.println(42, TAG, "msg");
+
+ verify(()-> Slog.println(42, TAG, "msg"));
+ }
+
+ @Test
+ public void testWtf_msgFormattedWithException() {
+ Slogf.wtf(TAG, mException, "msg in a %s", "bottle");
+
+ verify(()-> Slog.wtf(TAG, "msg in a bottle", mException));
+ }
+
+ private void enableLogging(@Log.Level int level) {
+ setIsLogging(level, true);
+ }
+
+ private void disableLogging(@Log.Level int level) {
+ setIsLogging(level, false);
+ }
+
+ private void setIsLogging(@Log.Level int level, boolean value) {
+ doReturn(value).when(() -> Slogf.isLoggable(TAG, level));
+ }
+}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 68f547979ce0..d7fbd4913b2c 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -42,6 +42,7 @@ android_test {
"androidx.test.ext.truth",
"androidx.test.runner",
"androidx.test.rules",
+ "cts-wm-util",
"platform-compat-test-rules",
"mockito-target-minus-junit4",
"platform-test-annotations",
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
index e04841bf2335..6bca5e449b34 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -46,6 +46,9 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.server.wm.settings.SettingsSession;
import android.support.test.uiautomator.UiDevice;
import android.test.suitebuilder.annotation.LargeTest;
import android.text.TextUtils;
@@ -61,6 +64,8 @@ import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Tests for {@link ActivityManager}.
@@ -316,6 +321,102 @@ public class ActivityManagerTest {
}
}
+ @LargeTest
+ @Test
+ public void testAppFreezerWithAllowOomAdj() throws Exception {
+ final long waitFor = 5000;
+ boolean freezerWasEnabled = isFreezerEnabled();
+ SettingsSession<String> freezerEnabled = null;
+ SettingsSession<String> amConstantsSettings = null;
+ DeviceConfigSession<Long> freezerDebounceTimeout = null;
+ MyServiceConnection autoConnection = null;
+ try {
+ if (!freezerWasEnabled) {
+ freezerEnabled = new SettingsSession<>(
+ Settings.Global.getUriFor(Settings.Global.CACHED_APPS_FREEZER_ENABLED),
+ Settings.Global::getString, Settings.Global::putString);
+ freezerEnabled.set("enabled");
+ Thread.sleep(waitFor);
+ if (!isFreezerEnabled()) {
+ // Still not enabled? Probably because the device doesn't support it.
+ return;
+ }
+ }
+ freezerDebounceTimeout = new DeviceConfigSession<>(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ CachedAppOptimizer.KEY_FREEZER_DEBOUNCE_TIMEOUT,
+ DeviceConfig::getLong, CachedAppOptimizer.DEFAULT_FREEZER_DEBOUNCE_TIMEOUT);
+ freezerDebounceTimeout.set(waitFor);
+
+ final String activityManagerConstants = Settings.Global.ACTIVITY_MANAGER_CONSTANTS;
+ amConstantsSettings = new SettingsSession<>(
+ Settings.Global.getUriFor(activityManagerConstants),
+ Settings.Global::getString, Settings.Global::putString);
+
+ amConstantsSettings.set(
+ ActivityManagerConstants.KEY_MAX_SERVICE_INACTIVITY + "=" + waitFor);
+
+ final Intent intent = new Intent();
+ intent.setClassName(TEST_APP, TEST_CLASS);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ autoConnection = new MyServiceConnection(latch);
+ mContext.bindService(intent, autoConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_OOM_MANAGEMENT);
+ try {
+ assertTrue("Timeout to bind to service " + intent.getComponent(),
+ latch.await(AWAIT_TIMEOUT, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail("Unable to bind to service " + intent.getComponent());
+ }
+ assertFalse(TEST_APP + " shouldn't be frozen now.", isAppFrozen(TEST_APP));
+
+ // Trigger oomAdjUpdate/
+ toggleScreenOn(false);
+ toggleScreenOn(true);
+
+ // Wait for the freezer kick in if there is any.
+ Thread.sleep(waitFor * 4);
+
+ // It still shouldn't be frozen, although it's been in cached state.
+ assertFalse(TEST_APP + " shouldn't be frozen now.", isAppFrozen(TEST_APP));
+ } finally {
+ toggleScreenOn(true);
+ if (amConstantsSettings != null) {
+ amConstantsSettings.close();
+ }
+ if (freezerEnabled != null) {
+ freezerEnabled.close();
+ }
+ if (freezerDebounceTimeout != null) {
+ freezerDebounceTimeout.close();
+ }
+ if (autoConnection != null) {
+ mContext.unbindService(autoConnection);
+ }
+ }
+ }
+
+ private boolean isFreezerEnabled() throws Exception {
+ final String output = runShellCommand("dumpsys activity settings");
+ final Matcher matcher = Pattern.compile("\\b" + CachedAppOptimizer.KEY_USE_FREEZER
+ + "\\b=\\b(true|false)\\b").matcher(output);
+ if (matcher.find()) {
+ return Boolean.parseBoolean(matcher.group(1));
+ }
+ return false;
+ }
+
+ private boolean isAppFrozen(String packageName) throws Exception {
+ final String output = runShellCommand("dumpsys activity p " + packageName);
+ final Matcher matcher = Pattern.compile("\\b" + ProcessCachedOptimizerRecord.IS_FROZEN
+ + "\\b=\\b(true|false)\\b").matcher(output);
+ if (matcher.find()) {
+ return Boolean.parseBoolean(matcher.group(1));
+ }
+ return false;
+ }
+
/**
* Make sure the screen state.
*/
diff --git a/services/tests/servicestests/src/com/android/server/am/DeviceConfigSession.java b/services/tests/servicestests/src/com/android/server/am/DeviceConfigSession.java
new file mode 100644
index 000000000000..03cf17c37647
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/DeviceConfigSession.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.annotation.NonNull;
+import android.provider.DeviceConfig;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.internal.util.function.TriFunction;
+
+/**
+ * An utility class to set/restore the given device_config item.
+ */
+public class DeviceConfigSession<T> implements AutoCloseable {
+ private final TriFunction<String, String, T, T> mGetter;
+
+ private final String mNamespace;
+ private final String mKey;
+ private final T mInitialValue;
+ private final T mDefaultValue;
+ private boolean mHasInitalValue;
+
+ DeviceConfigSession(String namespace, String key,
+ TriFunction<String, String, T, T> getter, T defaultValue) {
+ mNamespace = namespace;
+ mKey = key;
+ mGetter = getter;
+ mDefaultValue = defaultValue;
+ // Try {@DeviceConfig#getString} firstly since the DeviceConfig API doesn't
+ // support "not found" exception.
+ final String initialStringValue = DeviceConfig.getString(namespace, key, null);
+ if (initialStringValue == null) {
+ mHasInitalValue = false;
+ mInitialValue = defaultValue;
+ } else {
+ mHasInitalValue = true;
+ mInitialValue = getter.apply(namespace, key, defaultValue);
+ }
+ }
+
+ public void set(final @NonNull T value) {
+ DeviceConfig.setProperty(mNamespace, mKey,
+ value == null ? null : value.toString(), false);
+ }
+
+ public T get() {
+ return mGetter.apply(mNamespace, mKey, mDefaultValue);
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (mHasInitalValue) {
+ set(mInitialValue);
+ } else {
+ SystemUtil.runShellCommand("device_config delete " + mNamespace + " " + mKey);
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 100d3ea87a89..f5876faad6cb 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -33,12 +33,6 @@ import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
-import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
-import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
-import static android.net.NetworkPolicyManager.RULE_NONE;
-import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
-import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
-import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
import static android.net.NetworkPolicyManager.uidPoliciesToString;
import static android.net.NetworkPolicyManager.uidRulesToString;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
@@ -49,7 +43,6 @@ import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.os.Process.SYSTEM_UID;
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
@@ -141,7 +134,6 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.DataUnit;
import android.util.Log;
-import android.util.Pair;
import android.util.Range;
import android.util.RecurrenceRule;
@@ -1844,68 +1836,6 @@ public class NetworkPolicyManagerServiceTest {
reset(mStatsService);
}
- /**
- * Exhaustively test checkUidNetworkingBlocked to output the expected results based on external
- * conditions.
- */
- @Test
- public void testCheckUidNetworkingBlocked() {
- final ArrayList<Pair<Boolean, Integer>> expectedBlockedStates = new ArrayList<>();
-
- // Metered network. Data saver on.
- expectedBlockedStates.add(new Pair<>(true, RULE_NONE));
- expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
- expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
- expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_METERED));
- expectedBlockedStates.add(new Pair<>(true, RULE_ALLOW_ALL));
- expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
- verifyNetworkBlockedState(
- true /* metered */, true /* backgroundRestricted */, expectedBlockedStates);
- expectedBlockedStates.clear();
-
- // Metered network. Data saver off.
- expectedBlockedStates.add(new Pair<>(false, RULE_NONE));
- expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
- expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
- expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_METERED));
- expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_ALL));
- expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
- verifyNetworkBlockedState(
- true /* metered */, false /* backgroundRestricted */, expectedBlockedStates);
- expectedBlockedStates.clear();
-
- // Non-metered network. Data saver on.
- expectedBlockedStates.add(new Pair<>(false, RULE_NONE));
- expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
- expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
- expectedBlockedStates.add(new Pair<>(false, RULE_REJECT_METERED));
- expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_ALL));
- expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
- verifyNetworkBlockedState(
- false /* metered */, true /* backgroundRestricted */, expectedBlockedStates);
-
- // Non-metered network. Data saver off. The result is the same as previous case since
- // the network is blocked only for RULE_REJECT_ALL regardless of data saver.
- verifyNetworkBlockedState(
- false /* metered */, false /* backgroundRestricted */, expectedBlockedStates);
- expectedBlockedStates.clear();
- }
-
- private void verifyNetworkBlockedState(boolean metered, boolean backgroundRestricted,
- ArrayList<Pair<Boolean, Integer>> expectedBlockedStateForRules) {
-
- for (Pair<Boolean, Integer> pair : expectedBlockedStateForRules) {
- final boolean expectedResult = pair.first;
- final int rule = pair.second;
- assertEquals(formatBlockedStateError(UID_A, rule, metered, backgroundRestricted),
- expectedResult, mService.checkUidNetworkingBlocked(UID_A, rule,
- metered, backgroundRestricted));
- assertFalse(formatBlockedStateError(SYSTEM_UID, rule, metered, backgroundRestricted),
- mService.checkUidNetworkingBlocked(SYSTEM_UID, rule, metered,
- backgroundRestricted));
- }
- }
-
private void enableRestrictedMode(boolean enable) throws Exception {
mService.mRestrictedNetworkingMode = enable;
mService.updateRestrictedModeAllowlistUL();
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 f6d6624d7e1c..809b6d561362 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -350,6 +350,52 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
}
@Test
+ public void testRemoveChannelRunnable() throws Exception {
+ NotificationHistory nh = mock(NotificationHistory.class);
+ NotificationHistoryDatabase.RemoveChannelRunnable rcr =
+ mDataBase.new RemoveChannelRunnable("pkg", "channel");
+ rcr.setNotificationHistory(nh);
+
+ AtomicFile af = mock(AtomicFile.class);
+ when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
+ mDataBase.mHistoryFiles.addLast(af);
+
+ when(nh.removeChannelFromWrite("pkg", "channel")).thenReturn(true);
+
+ mDataBase.mBuffer = mock(NotificationHistory.class);
+
+ rcr.run();
+
+ verify(mDataBase.mBuffer).removeChannelFromWrite("pkg", "channel");
+ verify(af).openRead();
+ verify(nh).removeChannelFromWrite("pkg", "channel");
+ verify(af).startWrite();
+ }
+
+ @Test
+ public void testRemoveChannelRunnable_noChanges() throws Exception {
+ NotificationHistory nh = mock(NotificationHistory.class);
+ NotificationHistoryDatabase.RemoveChannelRunnable rcr =
+ mDataBase.new RemoveChannelRunnable("pkg", "channel");
+ rcr.setNotificationHistory(nh);
+
+ AtomicFile af = mock(AtomicFile.class);
+ when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
+ mDataBase.mHistoryFiles.addLast(af);
+
+ when(nh.removeChannelFromWrite("pkg", "channel")).thenReturn(false);
+
+ mDataBase.mBuffer = mock(NotificationHistory.class);
+
+ rcr.run();
+
+ verify(mDataBase.mBuffer).removeChannelFromWrite("pkg", "channel");
+ verify(af).openRead();
+ verify(nh).removeChannelFromWrite("pkg", "channel");
+ verify(af, never()).startWrite();
+ }
+
+ @Test
public void testWriteBufferRunnable() throws Exception {
NotificationHistory nh = mock(NotificationHistory.class);
when(nh.getPooledStringsToWrite()).thenReturn(new String[]{});
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java
index a0293b7ad12a..5892793fdb72 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java
@@ -366,7 +366,7 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase {
@Test
public void testDeleteConversation_userUnlocked() {
String pkg = "pkg";
- Set<String> convos = Set.of("convo", "another");
+ Set<String> convos = Set.of("convo", "another");
NotificationHistoryDatabase userHistory = mock(NotificationHistoryDatabase.class);
mHistoryManager.onUserUnlocked(USER_SYSTEM);
@@ -378,6 +378,20 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase {
}
@Test
+ public void testDeleteNotificationChannel_userUnlocked() {
+ String pkg = "pkg";
+ String channelId = "channelId";
+ NotificationHistoryDatabase userHistory = mock(NotificationHistoryDatabase.class);
+
+ mHistoryManager.onUserUnlocked(USER_SYSTEM);
+ mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistory);
+
+ mHistoryManager.deleteNotificationChannel(pkg, 1, channelId);
+
+ verify(userHistory, times(1)).deleteNotificationChannel(pkg, channelId);
+ }
+
+ @Test
public void testTriggerWriteToDisk() {
NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class);
NotificationHistoryDatabase userHistoryAll = mock(NotificationHistoryDatabase.class);
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 9a63782a4079..8be19f002fa5 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -56,6 +56,9 @@ import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
@@ -90,6 +93,7 @@ import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
+import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.AutomaticZenRule;
import android.app.IActivityManager;
@@ -124,6 +128,7 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.UserInfo;
+import android.content.pm.VersionedPackage;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Icon;
@@ -183,12 +188,15 @@ import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
+import com.android.server.pm.PackageManagerService;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.utils.quota.MultiRateLimiter;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
+import com.google.common.collect.ImmutableList;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -301,6 +309,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Mock
StatsManager mStatsManager;
@Mock
+ AlarmManager mAlarmManager;
+ @Mock
MultiRateLimiter mToastRateLimiter;
BroadcastReceiver mPackageIntentReceiver;
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
@@ -422,6 +432,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
LocalServices.addService(DeviceIdleInternal.class, deviceIdleInternal);
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
LocalServices.addService(ActivityManagerInternal.class, mAmi);
+ mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager);
doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
@@ -899,6 +910,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testLimitTimeOutBroadcast() {
+ NotificationChannel channel = new NotificationChannel("id", "name",
+ NotificationManager.IMPORTANCE_HIGH);
+ Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setTimeoutAfter(1);
+
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
+
+ mService.scheduleTimeoutLocked(r);
+ ArgumentCaptor<PendingIntent> captor = ArgumentCaptor.forClass(PendingIntent.class);
+ verify(mAlarmManager).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture());
+ assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME,
+ captor.getValue().getIntent().getPackage());
+ }
+
+ @Test
public void testDefaultAssistant_overrideDefault() {
final int userId = mContext.getUserId();
final String testComponent = "package/class";
@@ -7585,4 +7616,106 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), r.getSbn().getId(),
r.getSbn().getTag(), r,false);
}
+
+ @Test
+ public void testMigrateNotificationFilter_migrationAllAllowed() throws Exception {
+ int uid = 9000;
+ int[] userIds = new int[] {UserHandle.getUserId(mUid), 1000};
+ when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(userIds);
+ List<String> disallowedApps = ImmutableList.of("apples", "bananas", "cherries");
+ for (int userId : userIds) {
+ for (String pkg : disallowedApps) {
+ when(mPackageManager.getPackageUid(pkg, 0, userId)).thenReturn(uid++);
+ }
+ }
+
+ when(mListeners.getNotificationListenerFilter(any())).thenReturn(
+ new NotificationListenerFilter());
+
+ mBinderService.migrateNotificationFilter(null,
+ FLAG_FILTER_TYPE_CONVERSATIONS | FLAG_FILTER_TYPE_ONGOING,
+ disallowedApps);
+
+ ArgumentCaptor<NotificationListenerFilter> captor =
+ ArgumentCaptor.forClass(NotificationListenerFilter.class);
+ verify(mListeners).setNotificationListenerFilter(any(), captor.capture());
+
+ assertEquals(FLAG_FILTER_TYPE_CONVERSATIONS | FLAG_FILTER_TYPE_ONGOING,
+ captor.getValue().getTypes());
+ assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 9000)));
+ assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("cherries", 9002)));
+ assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 9003)));
+
+ // hypothetical other user untouched
+ assertTrue(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 10000)));
+ }
+
+ @Test
+ public void testMigrateNotificationFilter_noPreexistingFilter() throws Exception {
+ int[] userIds = new int[] {UserHandle.getUserId(mUid)};
+ when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(userIds);
+ List<String> disallowedApps = ImmutableList.of("apples");
+ when(mPackageManager.getPackageUid("apples", 0, UserHandle.getUserId(mUid)))
+ .thenReturn(1001);
+
+ when(mListeners.getNotificationListenerFilter(any())).thenReturn(null);
+
+ mBinderService.migrateNotificationFilter(null, FLAG_FILTER_TYPE_ONGOING,
+ disallowedApps);
+
+ ArgumentCaptor<NotificationListenerFilter> captor =
+ ArgumentCaptor.forClass(NotificationListenerFilter.class);
+ verify(mListeners).setNotificationListenerFilter(any(), captor.capture());
+
+ assertEquals(FLAG_FILTER_TYPE_ONGOING, captor.getValue().getTypes());
+ assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 1001)));
+ }
+
+ @Test
+ public void testMigrateNotificationFilter_existingTypeFilter() throws Exception {
+ int[] userIds = new int[] {UserHandle.getUserId(mUid)};
+ when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(userIds);
+ List<String> disallowedApps = ImmutableList.of("apples");
+ when(mPackageManager.getPackageUid("apples", 0, UserHandle.getUserId(mUid)))
+ .thenReturn(1001);
+
+ when(mListeners.getNotificationListenerFilter(any())).thenReturn(
+ new NotificationListenerFilter(FLAG_FILTER_TYPE_CONVERSATIONS, new ArraySet<>()));
+
+ mBinderService.migrateNotificationFilter(null, FLAG_FILTER_TYPE_ONGOING,
+ disallowedApps);
+
+ ArgumentCaptor<NotificationListenerFilter> captor =
+ ArgumentCaptor.forClass(NotificationListenerFilter.class);
+ verify(mListeners).setNotificationListenerFilter(any(), captor.capture());
+
+ // type isn't saved but pkg list is
+ assertEquals(FLAG_FILTER_TYPE_CONVERSATIONS, captor.getValue().getTypes());
+ assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 1001)));
+ }
+
+ @Test
+ public void testMigrateNotificationFilter_existingPkgFilter() throws Exception {
+ int[] userIds = new int[] {UserHandle.getUserId(mUid)};
+ when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(userIds);
+ List<String> disallowedApps = ImmutableList.of("apples");
+ when(mPackageManager.getPackageUid("apples", 0, UserHandle.getUserId(mUid)))
+ .thenReturn(1001);
+
+ NotificationListenerFilter preexisting = new NotificationListenerFilter();
+ preexisting.addPackage(new VersionedPackage("test", 1002));
+ when(mListeners.getNotificationListenerFilter(any())).thenReturn(preexisting);
+
+ mBinderService.migrateNotificationFilter(null, FLAG_FILTER_TYPE_ONGOING,
+ disallowedApps);
+
+ ArgumentCaptor<NotificationListenerFilter> captor =
+ ArgumentCaptor.forClass(NotificationListenerFilter.class);
+ verify(mListeners).setNotificationListenerFilter(any(), captor.capture());
+
+ // type is saved but pkg list isn't
+ assertEquals(FLAG_FILTER_TYPE_ONGOING, captor.getValue().getTypes());
+ assertTrue(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 1001)));
+ assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("test", 1002)));
+ }
}
diff --git a/telephony/java/android/telephony/ims/SipMessage.java b/telephony/java/android/telephony/ims/SipMessage.java
index ad6d73c39962..b5295637d4dd 100644
--- a/telephony/java/android/telephony/ims/SipMessage.java
+++ b/telephony/java/android/telephony/ims/SipMessage.java
@@ -24,6 +24,7 @@ import android.annotation.SystemApi;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
import com.android.internal.telephony.SipMessageParsingUtils;
@@ -60,14 +61,19 @@ public final class SipMessage implements Parcelable {
*/
public SipMessage(@NonNull String startLine, @NonNull String headerSection,
@NonNull byte[] content) {
- if (startLine == null || headerSection == null || content == null) {
- throw new IllegalArgumentException("One or more null parameters entered");
- }
+ Objects.requireNonNull(startLine, "Required parameter is null: startLine");
+ Objects.requireNonNull(headerSection, "Required parameter is null: headerSection");
+ Objects.requireNonNull(content, "Required parameter is null: content");
+
mStartLine = startLine;
mHeaderSection = headerSection;
mContent = content;
mViaBranchParam = SipMessageParsingUtils.getTransactionId(mHeaderSection);
+ if (TextUtils.isEmpty(mViaBranchParam)) {
+ throw new IllegalArgumentException("header section MUST contain a branch parameter "
+ + "inside of the Via header.");
+ }
mCallIdParam = SipMessageParsingUtils.getCallId(mHeaderSection);
}
@@ -107,11 +113,9 @@ public final class SipMessage implements Parcelable {
/**
* @return the branch parameter enclosed in the Via header key's value. See RFC 3261 section
- * 20.42 for more information on the Via header. If {@code null}, then there was either no
- * Via parameter found in this SIP message's headers or no branch parameter found in the
- * Via header.
+ * 20.42 for more information on the Via header.
*/
- public @Nullable String getViaBranchParameter() {
+ public @NonNull String getViaBranchParameter() {
return mViaBranchParam;
}
diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
index 739946be2e5b..5c9ec53d713b 100644
--- a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
@@ -28,8 +28,6 @@ import android.telephony.ims.SipDelegateImsConfiguration;
import android.telephony.ims.SipDelegateManager;
import android.telephony.ims.SipMessage;
import android.telephony.ims.stub.SipDelegate;
-import android.text.TextUtils;
-import android.util.Log;
import java.util.ArrayList;
import java.util.Set;
@@ -187,11 +185,6 @@ public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMe
private void notifyLocalMessageFailedToBeReceived(SipMessage m, int reason) {
String transactionId = m.getViaBranchParameter();
- if (TextUtils.isEmpty(transactionId)) {
- Log.w(LOG_TAG, "failure to parse SipMessage.");
- throw new IllegalArgumentException("Malformed SipMessage, can not determine "
- + "transaction ID.");
- }
SipDelegate d = mDelegate;
if (d != null) {
mExecutor.execute(() -> d.notifyMessageReceiveError(transactionId, reason));
diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java
index 3cd27264295c..ad02fe55902f 100644
--- a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java
@@ -28,7 +28,6 @@ import android.telephony.ims.SipMessage;
import android.telephony.ims.stub.DelegateConnectionMessageCallback;
import android.telephony.ims.stub.DelegateConnectionStateCallback;
import android.telephony.ims.stub.SipDelegate;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
@@ -267,12 +266,6 @@ public class SipDelegateConnectionAidlWrapper implements SipDelegateConnection,
private void notifyLocalMessageFailedToSend(SipMessage m, int reason) {
String transactionId = m.getViaBranchParameter();
- if (TextUtils.isEmpty(transactionId)) {
- Log.w(LOG_TAG, "sendMessage detected a malformed SipMessage and can not get a "
- + "transaction ID.");
- throw new IllegalArgumentException("Could not send SipMessage due to malformed header");
- }
- mExecutor.execute(() ->
- mMessageCallback.onMessageSendFailure(transactionId, reason));
+ mExecutor.execute(() -> mMessageCallback.onMessageSendFailure(transactionId, reason));
}
}
diff --git a/tests/ActivityManagerPerfTests/tests/Android.bp b/tests/ActivityManagerPerfTests/tests/Android.bp
index c8dbf811c69b..e5813aec9f43 100644
--- a/tests/ActivityManagerPerfTests/tests/Android.bp
+++ b/tests/ActivityManagerPerfTests/tests/Android.bp
@@ -28,6 +28,7 @@ android_test {
"androidx.test.rules",
"apct-perftests-utils",
"ActivityManagerPerfTestsUtils",
+ "collector-device-lib-platform",
],
platform_apis: true,
min_sdk_version: "25",
diff --git a/tests/ActivityManagerPerfTests/tests/AndroidTest.xml b/tests/ActivityManagerPerfTests/tests/AndroidTest.xml
index 475bb82a9856..e753b704a3ae 100644
--- a/tests/ActivityManagerPerfTests/tests/AndroidTest.xml
+++ b/tests/ActivityManagerPerfTests/tests/AndroidTest.xml
@@ -28,5 +28,22 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.frameworks.perftests.amtests"/>
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
+
+ <!-- TODO: Add PerfettoListener to automatically capture perfetto traces for each test-->
+ <!-- Listener related args for collecting the traces and waiting for the device
+ to stabilize. -->
+ <option name="device-listeners"
+ value="android.device.collectors.ProcLoadListener" />
+ <!-- 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" />
+
+ <!-- ProcLoadListener related arguments -->
+ <!-- Wait for device last minute threshold to reach 3 with 2 minute timeout before
+ starting the test run -->
+ <option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
+ <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
+ <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
+ <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
</test>
</configuration>
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index e7718b546c1e..6d852bf0387a 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -48,6 +48,7 @@ import static android.os.Process.INVALID_UID;
import static com.android.modules.utils.build.SdkLevel.isAtLeastR;
import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
+import static com.android.net.module.util.NetworkCapabilitiesUtils.TRANSPORT_USB;
import static com.android.testutils.MiscAsserts.assertEmpty;
import static com.android.testutils.MiscAsserts.assertThrows;
import static com.android.testutils.ParcelUtils.assertParcelSane;
@@ -959,6 +960,11 @@ public class NetworkCapabilitiesTest {
assertNotEquals(512, nc.getLinkUpstreamBandwidthKbps());
}
+ private int getMaxTransport() {
+ if (!isAtLeastS() && MAX_TRANSPORT == TRANSPORT_USB) return MAX_TRANSPORT - 1;
+ return MAX_TRANSPORT;
+ }
+
@Test
public void testSignalStrength() {
final NetworkCapabilities nc = new NetworkCapabilities();
@@ -970,7 +976,7 @@ public class NetworkCapabilitiesTest {
}
private void assertNoTransport(NetworkCapabilities nc) {
- for (int i = MIN_TRANSPORT; i <= MAX_TRANSPORT; i++) {
+ for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
assertFalse(nc.hasTransport(i));
}
}
@@ -987,7 +993,7 @@ public class NetworkCapabilitiesTest {
assertFalse(nc.hasTransport(i));
}
}
- for (int i = MAX_TRANSPORT; i > maxTransportType; i--) {
+ for (int i = getMaxTransport(); i > maxTransportType; i--) {
if (positiveSequence) {
assertFalse(nc.hasTransport(i));
} else {
@@ -1001,12 +1007,12 @@ public class NetworkCapabilitiesTest {
final NetworkCapabilities nc = new NetworkCapabilities();
assertNoTransport(nc);
// Test adding multiple transport types.
- for (int i = MIN_TRANSPORT; i <= MAX_TRANSPORT; i++) {
+ for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
nc.addTransportType(i);
checkCurrentTransportTypes(nc, i, true /* positiveSequence */);
}
// Test removing multiple transport types.
- for (int i = MIN_TRANSPORT; i <= MAX_TRANSPORT; i++) {
+ for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
nc.removeTransportType(i);
checkCurrentTransportTypes(nc, i, false /* positiveSequence */);
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index b15d25250d4d..af7eb59a3d55 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -18,8 +18,12 @@ package com.android.server;
import static android.Manifest.permission.CHANGE_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
+import static android.Manifest.permission.NETWORK_FACTORY;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
+import static android.content.Intent.ACTION_PACKAGE_REMOVED;
+import static android.content.Intent.ACTION_PACKAGE_REPLACED;
import static android.content.Intent.ACTION_USER_ADDED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.ACTION_USER_UNLOCKED;
@@ -577,6 +581,7 @@ public class ConnectivityServiceTest {
final UserManager umMock = createContextAsUser(userHandle, 0 /* flags */)
.getSystemService(UserManager.class);
doReturn(value).when(umMock).isManagedProfile();
+ doReturn(value).when(mUserManager).isManagedProfile(eq(userHandle.getIdentifier()));
}
@Override
@@ -2781,10 +2786,14 @@ public class ConnectivityServiceTest {
}
private void grantUsingBackgroundNetworksPermissionForUid(final int uid) throws Exception {
- final String myPackageName = mContext.getPackageName();
- when(mPackageManager.getPackageInfo(eq(myPackageName), eq(GET_PERMISSIONS)))
+ grantUsingBackgroundNetworksPermissionForUid(uid, mContext.getPackageName());
+ }
+
+ private void grantUsingBackgroundNetworksPermissionForUid(
+ final int uid, final String packageName) throws Exception {
+ when(mPackageManager.getPackageInfo(eq(packageName), eq(GET_PERMISSIONS)))
.thenReturn(buildPackageInfo(true, uid));
- mService.mPermissionMonitor.onPackageAdded(myPackageName, uid);
+ mService.mPermissionMonitor.onPackageAdded(packageName, uid);
}
@Test
@@ -10431,6 +10440,12 @@ public class ConnectivityServiceTest {
.thenReturn(applicationInfo);
}
+ private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName)
+ throws Exception {
+ when(mPackageManager.getApplicationInfo(eq(packageName), anyInt()))
+ .thenThrow(new PackageManager.NameNotFoundException(packageName));
+ }
+
private void mockHasSystemFeature(@NonNull final String featureName,
@NonNull final boolean hasFeature) {
when(mPackageManager.hasSystemFeature(eq(featureName)))
@@ -10887,15 +10902,23 @@ public class ConnectivityServiceTest {
@NonNull final UidRangeParcel[] uidRanges,
@NonNull final String testPackageName)
throws Exception {
- mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
-
// These tests work off a single UID therefore using 'start' is valid.
mockGetApplicationInfo(testPackageName, uidRanges[0].start);
+ setOemNetworkPreference(networkPrefToSetup, testPackageName);
+ }
+
+ private void setOemNetworkPreference(final int networkPrefToSetup,
+ @NonNull final String... testPackageNames)
+ throws Exception {
+ mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
+
// Build OemNetworkPreferences object
- final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
- .addNetworkPreference(testPackageName, networkPrefToSetup)
- .build();
+ final OemNetworkPreferences.Builder builder = new OemNetworkPreferences.Builder();
+ for (final String packageName : testPackageNames) {
+ builder.addNetworkPreference(packageName, networkPrefToSetup);
+ }
+ final OemNetworkPreferences pref = builder.build();
// Act on ConnectivityService.setOemNetworkPreference()
final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback();
@@ -11494,8 +11517,7 @@ public class ConnectivityServiceTest {
// Arrange PackageManager mocks
final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
final UidRangeParcel[] uidRangesSingleUser =
- toUidRangeStableParcels(
- uidRangesForUids(TEST_PACKAGE_UID));
+ toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
final UidRangeParcel[] uidRangesBothUsers =
toUidRangeStableParcels(
uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid));
@@ -11542,6 +11564,84 @@ public class ConnectivityServiceTest {
false /* shouldDestroyNetwork */);
}
+ @Test
+ public void testMultilayerForPackageChangesEvaluatesCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID;
+ final String packageScheme = "package:";
+
+ // Arrange PackageManager mocks
+ final String packageToInstall = "package.to.install";
+ final int packageToInstallUid = 81387;
+ final UidRangeParcel[] uidRangesSinglePackage =
+ toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
+ mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID);
+ mockGetApplicationInfoThrowsNameNotFound(packageToInstall);
+ setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall);
+ grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall);
+
+ // Verify the starting state. No networks should be connected.
+ verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Test that we correctly add the expected values for installed packages.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Set the system to recognize the package to be installed
+ mockGetApplicationInfo(packageToInstall, packageToInstallUid);
+ final UidRangeParcel[] uidRangesAllPackages =
+ toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID, packageToInstallUid));
+
+ // Send a broadcast indicating a package was installed.
+ final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED);
+ addedIntent.setData(Uri.parse(packageScheme + packageToInstall));
+ processBroadcast(addedIntent);
+
+ // Test the single package is removed and the combined packages are added.
+ verifySetOemNetworkPreferenceForPreference(uidRangesAllPackages, uidRangesSinglePackage,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Set the system to no longer recognize the package to be installed
+ mockGetApplicationInfoThrowsNameNotFound(packageToInstall);
+
+ // Send a broadcast indicating a package was removed.
+ final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED);
+ removedIntent.setData(Uri.parse(packageScheme + packageToInstall));
+ processBroadcast(removedIntent);
+
+ // Test the combined packages are removed and the single package is added.
+ verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, uidRangesAllPackages,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Set the system to change the installed package's uid
+ final int replacedTestPackageUid = TEST_PACKAGE_UID + 1;
+ mockGetApplicationInfo(TEST_PACKAGE_NAME, replacedTestPackageUid);
+ final UidRangeParcel[] uidRangesReplacedPackage =
+ toUidRangeStableParcels(uidRangesForUids(replacedTestPackageUid));
+
+ // Send a broadcast indicating a package was replaced.
+ final Intent replacedIntent = new Intent(ACTION_PACKAGE_REPLACED);
+ replacedIntent.setData(Uri.parse(packageScheme + TEST_PACKAGE_NAME));
+ processBroadcast(replacedIntent);
+
+ // Test the original uid is removed and is replaced with the new uid.
+ verifySetOemNetworkPreferenceForPreference(uidRangesReplacedPackage, uidRangesSinglePackage,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ false /* shouldDestroyNetwork */);
+ }
+
/**
* Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order:
* NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback
@@ -12474,4 +12574,68 @@ public class ConnectivityServiceTest {
mCm.setProfileNetworkPreference(testHandle,
PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null));
}
+
+ @Test
+ public void testSubIdsClearedWithoutNetworkFactoryPermission() throws Exception {
+ mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED);
+ final NetworkCapabilities nc = new NetworkCapabilities();
+ nc.setSubIds(Collections.singleton(Process.myUid()));
+
+ final NetworkCapabilities result =
+ mService.networkCapabilitiesRestrictedForCallerPermissions(
+ nc, Process.myPid(), Process.myUid());
+ assertTrue(result.getSubIds().isEmpty());
+ }
+
+ @Test
+ public void testSubIdsExistWithNetworkFactoryPermission() throws Exception {
+ mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED);
+
+ final Set<Integer> subIds = Collections.singleton(Process.myUid());
+ final NetworkCapabilities nc = new NetworkCapabilities();
+ nc.setSubIds(subIds);
+
+ final NetworkCapabilities result =
+ mService.networkCapabilitiesRestrictedForCallerPermissions(
+ nc, Process.myPid(), Process.myUid());
+ assertEquals(subIds, result.getSubIds());
+ }
+
+ private NetworkRequest getRequestWithSubIds() {
+ return new NetworkRequest.Builder()
+ .setSubIds(Collections.singleton(Process.myUid()))
+ .build();
+ }
+
+ @Test
+ public void testNetworkRequestWithSubIdsWithNetworkFactoryPermission() throws Exception {
+ mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED);
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(
+ mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE);
+ final NetworkCallback networkCallback1 = new NetworkCallback();
+ final NetworkCallback networkCallback2 = new NetworkCallback();
+
+ mCm.requestNetwork(getRequestWithSubIds(), networkCallback1);
+ mCm.requestNetwork(getRequestWithSubIds(), pendingIntent);
+ mCm.registerNetworkCallback(getRequestWithSubIds(), networkCallback2);
+
+ mCm.unregisterNetworkCallback(networkCallback1);
+ mCm.releaseNetworkRequest(pendingIntent);
+ mCm.unregisterNetworkCallback(networkCallback2);
+ }
+
+ @Test
+ public void testNetworkRequestWithSubIdsWithoutNetworkFactoryPermission() throws Exception {
+ mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED);
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(
+ mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE);
+
+ final Class<SecurityException> expected = SecurityException.class;
+ assertThrows(
+ expected, () -> mCm.requestNetwork(getRequestWithSubIds(), new NetworkCallback()));
+ assertThrows(expected, () -> mCm.requestNetwork(getRequestWithSubIds(), pendingIntent));
+ assertThrows(
+ expected,
+ () -> mCm.registerNetworkCallback(getRequestWithSubIds(), new NetworkCallback()));
+ }
}
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 4ad7136aabb2..43e6676e1d4c 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.net.ConnectivityManager.NetworkCallback;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -55,8 +57,10 @@ import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
+import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkCapabilities.Transport;
+import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -258,6 +262,10 @@ public class VcnManagementServiceTest {
verify(mConnMgr).registerNetworkProvider(any(VcnNetworkProvider.class));
verify(mSubscriptionTracker).register();
+ verify(mConnMgr)
+ .registerNetworkCallback(
+ eq(new NetworkRequest.Builder().clearCapabilities().build()),
+ any(NetworkCallback.class));
}
@Test
@@ -529,17 +537,6 @@ public class VcnManagementServiceTest {
}
@Test
- public void testSetVcnConfigInSafeModeNotifiesStatusCallback() throws Exception {
- setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */);
- mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
- verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
-
- mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
-
- verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
- }
-
- @Test
public void testClearVcnConfigRequiresNonSystemServer() throws Exception {
doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid();
@@ -706,10 +703,8 @@ public class VcnManagementServiceTest {
.checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any());
}
- private VcnUnderlyingNetworkPolicy startVcnAndGetPolicyForTransport(
- int subId, ParcelUuid subGrp, boolean isVcnActive, int transport) {
- setupSubscriptionAndStartVcn(subId, subGrp, isVcnActive);
-
+ private NetworkCapabilities.Builder getNetworkCapabilitiesBuilderForTransport(
+ int subId, int transport) {
final NetworkCapabilities.Builder ncBuilder =
new NetworkCapabilities.Builder()
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
@@ -718,7 +713,16 @@ public class VcnManagementServiceTest {
ncBuilder.setSubIds(Collections.singleton(subId));
}
- return mVcnMgmtSvc.getUnderlyingNetworkPolicy(ncBuilder.build(), new LinkProperties());
+ return ncBuilder;
+ }
+
+ private VcnUnderlyingNetworkPolicy startVcnAndGetPolicyForTransport(
+ int subId, ParcelUuid subGrp, boolean isVcnActive, int transport) {
+ setupSubscriptionAndStartVcn(subId, subGrp, isVcnActive);
+
+ return mVcnMgmtSvc.getUnderlyingNetworkPolicy(
+ getNetworkCapabilitiesBuilderForTransport(subId, transport).build(),
+ new LinkProperties());
}
@Test
@@ -780,6 +784,53 @@ public class VcnManagementServiceTest {
true /* isRestricted */);
}
+ private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) {
+ mVcnMgmtSvc.systemReady();
+
+ final ArgumentCaptor<NetworkCallback> captor =
+ ArgumentCaptor.forClass(NetworkCallback.class);
+ verify(mConnMgr)
+ .registerNetworkCallback(
+ eq(new NetworkRequest.Builder().clearCapabilities().build()),
+ captor.capture());
+ captor.getValue().onCapabilitiesChanged(new Network(0), caps);
+ }
+
+ @Test
+ public void testGetUnderlyingNetworkPolicyVcnWifi_unrestrictingExistingNetworkRequiresRestart()
+ throws Exception {
+ final NetworkCapabilities existingNetworkCaps =
+ getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
+ .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ .build();
+ setupTrackedCarrierWifiNetwork(existingNetworkCaps);
+
+ // Trigger test without VCN instance alive; expect restart due to change of NOT_RESTRICTED
+ // immutable capability
+ final VcnUnderlyingNetworkPolicy policy =
+ mVcnMgmtSvc.getUnderlyingNetworkPolicy(
+ getNetworkCapabilitiesBuilderForTransport(
+ TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
+ .build(),
+ new LinkProperties());
+ assertTrue(policy.isTeardownRequested());
+ }
+
+ @Test
+ public void testGetUnderlyingNetworkPolicyVcnWifi_restrictingExistingNetworkRequiresRestart()
+ throws Exception {
+ final NetworkCapabilities existingNetworkCaps =
+ getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
+ .build();
+ setupTrackedCarrierWifiNetwork(existingNetworkCaps);
+
+ final VcnUnderlyingNetworkPolicy policy =
+ startVcnAndGetPolicyForTransport(
+ TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */, TRANSPORT_WIFI);
+
+ assertTrue(policy.isTeardownRequested());
+ }
+
@Test
public void testGetUnderlyingNetworkPolicyNonVcnNetwork() throws Exception {
setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_1, true /* isActive */);
@@ -840,7 +891,9 @@ public class VcnManagementServiceTest {
}
private void triggerVcnSafeMode(
- @NonNull ParcelUuid subGroup, @NonNull TelephonySubscriptionSnapshot snapshot)
+ @NonNull ParcelUuid subGroup,
+ @NonNull TelephonySubscriptionSnapshot snapshot,
+ boolean isInSafeMode)
throws Exception {
verify(mMockDeps)
.newVcn(
@@ -851,22 +904,32 @@ public class VcnManagementServiceTest {
mVcnCallbackCaptor.capture());
VcnCallback vcnCallback = mVcnCallbackCaptor.getValue();
- vcnCallback.onEnteredSafeMode();
+ vcnCallback.onSafeModeStatusChanged(isInSafeMode);
}
- @Test
- public void testVcnEnteringSafeModeNotifiesPolicyListeners() throws Exception {
+ private void verifyVcnSafeModeChangesNotifiesPolicyListeners(boolean enterSafeMode)
+ throws Exception {
TelephonySubscriptionSnapshot snapshot =
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
- triggerVcnSafeMode(TEST_UUID_1, snapshot);
+ triggerVcnSafeMode(TEST_UUID_1, snapshot, enterSafeMode);
verify(mMockPolicyListener).onPolicyChanged();
}
- private void triggerVcnStatusCallbackOnEnteredSafeMode(
+ @Test
+ public void testVcnEnteringSafeModeNotifiesPolicyListeners() throws Exception {
+ verifyVcnSafeModeChangesNotifiesPolicyListeners(true /* enterSafeMode */);
+ }
+
+ @Test
+ public void testVcnExitingSafeModeNotifiesPolicyListeners() throws Exception {
+ verifyVcnSafeModeChangesNotifiesPolicyListeners(false /* enterSafeMode */);
+ }
+
+ private void triggerVcnStatusCallbackOnSafeModeStatusChanged(
@NonNull ParcelUuid subGroup,
@NonNull String pkgName,
int uid,
@@ -889,12 +952,13 @@ public class VcnManagementServiceTest {
mVcnMgmtSvc.registerVcnStatusCallback(subGroup, mMockStatusCallback, pkgName);
- triggerVcnSafeMode(subGroup, snapshot);
+ triggerVcnSafeMode(subGroup, snapshot, true /* enterSafeMode */);
}
@Test
- public void testVcnStatusCallbackOnEnteredSafeModeWithCarrierPrivileges() throws Exception {
- triggerVcnStatusCallbackOnEnteredSafeMode(
+ public void testVcnStatusCallbackOnSafeModeStatusChangedWithCarrierPrivileges()
+ throws Exception {
+ triggerVcnStatusCallbackOnSafeModeStatusChanged(
TEST_UUID_1,
TEST_PACKAGE_NAME,
TEST_UID,
@@ -905,8 +969,9 @@ public class VcnManagementServiceTest {
}
@Test
- public void testVcnStatusCallbackOnEnteredSafeModeWithoutCarrierPrivileges() throws Exception {
- triggerVcnStatusCallbackOnEnteredSafeMode(
+ public void testVcnStatusCallbackOnSafeModeStatusChangedWithoutCarrierPrivileges()
+ throws Exception {
+ triggerVcnStatusCallbackOnSafeModeStatusChanged(
TEST_UUID_1,
TEST_PACKAGE_NAME,
TEST_UID,
@@ -918,8 +983,9 @@ public class VcnManagementServiceTest {
}
@Test
- public void testVcnStatusCallbackOnEnteredSafeModeWithoutLocationPermission() throws Exception {
- triggerVcnStatusCallbackOnEnteredSafeMode(
+ public void testVcnStatusCallbackOnSafeModeStatusChangedWithoutLocationPermission()
+ throws Exception {
+ triggerVcnStatusCallbackOnSafeModeStatusChanged(
TEST_UUID_1,
TEST_PACKAGE_NAME,
TEST_UID,
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 2fadd44440f3..34c00182f855 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -32,6 +32,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -40,6 +41,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.net.ConnectivityManager;
+import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
@@ -58,19 +61,29 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
/** Tests for VcnGatewayConnection.ConnectedState */
@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase {
private VcnIkeSession mIkeSession;
+ private NetworkAgent mNetworkAgent;
@Before
public void setUp() throws Exception {
super.setUp();
+ mNetworkAgent = mock(NetworkAgent.class);
+ doReturn(mNetworkAgent)
+ .when(mDeps)
+ .newNetworkAgent(any(), any(), any(), any(), anyInt(), any(), any(), any(), any());
+
mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
mIkeSession = mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_1.network);
@@ -159,21 +172,44 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
}
- @Test
- public void testChildOpenedRegistersNetwork() throws Exception {
- // Verify scheduled but not canceled when entering ConnectedState
- verifySafeModeTimeoutAlarmAndGetCallback(false /* expectCanceled */);
+ private void triggerChildOpened() {
+ triggerChildOpened(Collections.singletonList(TEST_INTERNAL_ADDR), TEST_DNS_ADDR);
+ }
+ private void triggerChildOpened(List<LinkAddress> internalAddresses, InetAddress dnsAddress) {
final VcnChildSessionConfiguration mMockChildSessionConfig =
mock(VcnChildSessionConfiguration.class);
- doReturn(Collections.singletonList(TEST_INTERNAL_ADDR))
- .when(mMockChildSessionConfig)
- .getInternalAddresses();
- doReturn(Collections.singletonList(TEST_DNS_ADDR))
+ doReturn(internalAddresses).when(mMockChildSessionConfig).getInternalAddresses();
+ doReturn(Collections.singletonList(dnsAddress))
.when(mMockChildSessionConfig)
.getInternalDnsServers();
getChildSessionCallback().onOpened(mMockChildSessionConfig);
+ }
+
+ private void triggerValidation(int status) {
+ final ArgumentCaptor<Consumer<Integer>> validationCallbackCaptor =
+ ArgumentCaptor.forClass(Consumer.class);
+ verify(mDeps)
+ .newNetworkAgent(
+ any(),
+ any(),
+ any(),
+ any(),
+ anyInt(),
+ any(),
+ any(),
+ any(),
+ validationCallbackCaptor.capture());
+
+ validationCallbackCaptor.getValue().accept(status);
+ }
+
+ @Test
+ public void testChildOpenedRegistersNetwork() throws Exception {
+ // Verify scheduled but not canceled when entering ConnectedState
+ verifySafeModeTimeoutAlarmAndGetCallback(false /* expectCanceled */);
+ triggerChildOpened();
mTestLooper.dispatchAll();
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
@@ -182,15 +218,20 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
ArgumentCaptor.forClass(LinkProperties.class);
final ArgumentCaptor<NetworkCapabilities> ncCaptor =
ArgumentCaptor.forClass(NetworkCapabilities.class);
- verify(mConnMgr)
- .registerNetworkAgent(
- any(),
- any(),
- lpCaptor.capture(),
+ verify(mDeps)
+ .newNetworkAgent(
+ eq(mVcnContext),
+ any(String.class),
ncCaptor.capture(),
+ lpCaptor.capture(),
+ anyInt(),
+ argThat(nac -> nac.getLegacyType() == ConnectivityManager.TYPE_MOBILE),
any(),
any(),
- anyInt());
+ any());
+ verify(mNetworkAgent).register();
+ verify(mNetworkAgent).markConnected();
+
verify(mIpSecSvc)
.addAddressToTunnelInterface(
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_INTERNAL_ADDR), any());
@@ -208,9 +249,78 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
// Now that Vcn Network is up, notify it as validated and verify the SafeMode alarm is
// canceled
- mGatewayConnection.mNetworkAgent.onValidationStatus(
- NetworkAgent.VALIDATION_STATUS_VALID, null /* redirectUri */);
+ triggerValidation(NetworkAgent.VALIDATION_STATUS_VALID);
verify(mSafeModeTimeoutAlarm).cancel();
+ assertFalse(mGatewayConnection.isInSafeMode());
+ }
+
+ @Test
+ public void testInternalAndDnsAddressesChanged() throws Exception {
+ final List<LinkAddress> startingInternalAddrs =
+ Arrays.asList(new LinkAddress[] {TEST_INTERNAL_ADDR, TEST_INTERNAL_ADDR_2});
+ triggerChildOpened(startingInternalAddrs, TEST_DNS_ADDR);
+ mTestLooper.dispatchAll();
+
+ for (LinkAddress addr : startingInternalAddrs) {
+ verify(mIpSecSvc)
+ .addAddressToTunnelInterface(
+ eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(addr), any());
+ }
+
+ verify(mDeps)
+ .newNetworkAgent(
+ any(),
+ any(),
+ any(),
+ argThat(
+ lp ->
+ startingInternalAddrs.equals(lp.getLinkAddresses())
+ && Collections.singletonList(TEST_DNS_ADDR)
+ .equals(lp.getDnsServers())),
+ anyInt(),
+ any(),
+ any(),
+ any(),
+ any());
+
+ // Trigger another connection event, and verify that the addresses change
+ final List<LinkAddress> newInternalAddrs =
+ Arrays.asList(new LinkAddress[] {TEST_INTERNAL_ADDR_2, TEST_INTERNAL_ADDR_3});
+ triggerChildOpened(newInternalAddrs, TEST_DNS_ADDR_2);
+ mTestLooper.dispatchAll();
+
+ // Verify addresses on tunnel network added/removed
+ for (LinkAddress addr : newInternalAddrs) {
+ verify(mIpSecSvc)
+ .addAddressToTunnelInterface(
+ eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(addr), any());
+ }
+ verify(mIpSecSvc)
+ .removeAddressFromTunnelInterface(
+ eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_INTERNAL_ADDR), any());
+
+ // TODO(b/184579891): Also verify link properties updated and sent when sendLinkProperties
+ // is mockable
+
+ // Verify that IpSecTunnelInterface only created once
+ verify(mIpSecSvc).createTunnelInterface(any(), any(), any(), any(), any());
+ verifyNoMoreInteractions(mIpSecSvc);
+ }
+
+ @Test
+ public void testSuccessfulConnectionExitsSafeMode() throws Exception {
+ verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(
+ mGatewayConnection.mConnectedState);
+
+ assertTrue(mGatewayConnection.isInSafeMode());
+ assertFalse(mGatewayConnection.isQuitting());
+
+ triggerChildOpened();
+ mTestLooper.dispatchAll();
+
+ triggerValidation(NetworkAgent.VALIDATION_STATUS_VALID);
+
+ assertFalse(mGatewayConnection.isInSafeMode());
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index 7afa4494ee8b..bfe8c73d6389 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -118,8 +118,9 @@ public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectio
}
@Test
- public void testSafeModeTimeoutNotifiesCallback() {
- verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mConnectingState);
+ public void testSafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent() {
+ verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(
+ mGatewayConnection.mConnectingState);
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 99feffdebc8e..9da8b451c9fc 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -86,8 +86,9 @@ public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnec
}
@Test
- public void testSafeModeTimeoutNotifiesCallback() {
- verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mDisconnectingState);
+ public void testSafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent() {
+ verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(
+ mGatewayConnection.mDisconnectingState);
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
index 85a0277f8b48..6dbf7d552bb6 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
@@ -96,8 +96,9 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect
}
@Test
- public void testSafeModeTimeoutNotifiesCallback() {
- verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mRetryTimeoutState);
+ public void testSafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent() {
+ verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(
+ mGatewayConnection.mRetryTimeoutState);
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
index a660735470a4..c5ed8f6ddcc7 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
@@ -21,6 +21,8 @@ import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
import static com.android.server.vcn.VcnTestUtils.setupIpSecManager;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
@@ -42,6 +44,7 @@ import android.net.IpSecTunnelInterfaceResponse;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
+import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
import android.net.ipsec.ike.ChildSessionCallback;
import android.net.ipsec.ike.IkeSessionCallback;
@@ -71,8 +74,14 @@ public class VcnGatewayConnectionTestBase {
protected static final ParcelUuid TEST_SUB_GRP = new ParcelUuid(UUID.randomUUID());
protected static final InetAddress TEST_DNS_ADDR =
InetAddresses.parseNumericAddress("2001:DB8:0:1::");
+ protected static final InetAddress TEST_DNS_ADDR_2 =
+ InetAddresses.parseNumericAddress("2001:DB8:0:2::");
protected static final LinkAddress TEST_INTERNAL_ADDR =
- new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:0:2::"), 64);
+ new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:1::"), 64);
+ protected static final LinkAddress TEST_INTERNAL_ADDR_2 =
+ new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:2::"), 64);
+ protected static final LinkAddress TEST_INTERNAL_ADDR_3 =
+ new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:3::"), 64);
protected static final int TEST_IPSEC_SPI_VALUE = 0x1234;
protected static final int TEST_IPSEC_SPI_RESOURCE_ID = 1;
@@ -267,7 +276,12 @@ public class VcnGatewayConnectionTestBase {
expectCanceled);
}
- protected void verifySafeModeTimeoutNotifiesCallback(@NonNull State expectedState) {
+ protected void verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(
+ @NonNull State expectedState) {
+ // Set a NetworkAgent, and expect it to be unregistered and cleared
+ final NetworkAgent mockNetworkAgent = mock(NetworkAgent.class);
+ mGatewayConnection.setNetworkAgent(mockNetworkAgent);
+
// SafeMode timer starts when VcnGatewayConnection exits DisconnectedState (the initial
// state)
final Runnable delayedEvent =
@@ -275,7 +289,11 @@ public class VcnGatewayConnectionTestBase {
delayedEvent.run();
mTestLooper.dispatchAll();
- verify(mGatewayStatusCallback).onEnteredSafeMode();
+ verify(mGatewayStatusCallback).onSafeModeStatusChanged();
assertEquals(expectedState, mGatewayConnection.getCurrentState());
+ assertTrue(mGatewayConnection.isInSafeMode());
+
+ verify(mockNetworkAgent).unregister();
+ assertNull(mGatewayConnection.getNetworkAgent());
}
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 540be38ed798..90eb75e865e7 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -19,14 +19,13 @@ package com.android.server.vcn;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
-import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
@@ -54,7 +53,6 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@@ -136,6 +134,7 @@ public class VcnTest {
private void startVcnGatewayWithCapabilities(
NetworkRequestListener requestListener, int... netCapabilities) {
final NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
+ requestBuilder.addTransportType(TRANSPORT_CELLULAR);
for (final int netCapability : netCapabilities) {
requestBuilder.addCapability(netCapability);
}
@@ -160,8 +159,7 @@ public class VcnTest {
mTestLooper.dispatchAll();
for (final VcnGatewayConnection gateway : gatewayConnections) {
- verify(gateway, status == VCN_STATUS_CODE_ACTIVE ? times(1) : never())
- .updateSubscriptionSnapshot(eq(updatedSnapshot));
+ verify(gateway).updateSubscriptionSnapshot(eq(updatedSnapshot));
}
}
@@ -202,32 +200,53 @@ public class VcnTest {
private void verifySafeMode(
NetworkRequestListener requestListener,
- Set<VcnGatewayConnection> expectedGatewaysTornDown) {
- assertEquals(VCN_STATUS_CODE_SAFE_MODE, mVcn.getStatus());
- for (final VcnGatewayConnection gatewayConnection : expectedGatewaysTornDown) {
- verify(gatewayConnection).teardownAsynchronously();
+ Set<VcnGatewayConnection> activeGateways,
+ boolean expectInSafeMode) {
+ for (VcnGatewayConnection gatewayConnection : activeGateways) {
+ verify(gatewayConnection, never()).teardownAsynchronously();
}
- verify(mVcnNetworkProvider).unregisterListener(requestListener);
- verify(mVcnCallback).onEnteredSafeMode();
+
+ assertEquals(
+ expectInSafeMode ? VCN_STATUS_CODE_SAFE_MODE : VCN_STATUS_CODE_ACTIVE,
+ mVcn.getStatus());
+ verify(mVcnCallback).onSafeModeStatusChanged(expectInSafeMode);
}
@Test
- public void testGatewayEnteringSafeModeNotifiesVcn() {
+ public void testGatewayEnteringAndExitingSafeModeNotifiesVcn() {
final NetworkRequestListener requestListener = verifyAndGetRequestListener();
final Set<VcnGatewayConnection> gatewayConnections =
startGatewaysAndGetGatewayConnections(requestListener);
- // Doesn't matter which callback this gets - any Gateway entering Safemode should shut down
- // all Gateways
+ // Doesn't matter which callback this gets, or which VCN is in safe mode - any Gateway
+ // entering Safemode should trigger safe mode
final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
- statusCallback.onEnteredSafeMode();
+ final VcnGatewayConnection gatewayConnection = gatewayConnections.iterator().next();
+
+ doReturn(true).when(gatewayConnection).isInSafeMode();
+ statusCallback.onSafeModeStatusChanged();
+ mTestLooper.dispatchAll();
+
+ verifySafeMode(requestListener, gatewayConnections, true /* expectInSafeMode */);
+
+ // Verify that when all GatewayConnections exit safe mode, the VCN also exits safe mode
+ doReturn(false).when(gatewayConnection).isInSafeMode();
+ statusCallback.onSafeModeStatusChanged();
+ mTestLooper.dispatchAll();
+
+ verifySafeMode(requestListener, gatewayConnections, false /* expectInSafeMode */);
+
+ // Re-trigger, verify safe mode callback does not get fired again for identical state
+ statusCallback.onSafeModeStatusChanged();
mTestLooper.dispatchAll();
- verifySafeMode(requestListener, gatewayConnections);
+ // Expect only once still; from above.
+ verify(mVcnCallback).onSafeModeStatusChanged(false);
}
- @Test
- public void testGatewayQuit() {
+ private void verifyGatewayQuit(int status) {
+ mVcn.setStatus(status);
+
final NetworkRequestListener requestListener = verifyAndGetRequestListener();
final Set<VcnGatewayConnection> gatewayConnections =
new ArraySet<>(startGatewaysAndGetGatewayConnections(requestListener));
@@ -240,7 +259,7 @@ public class VcnTest {
assertEquals(1, mVcn.getVcnGatewayConnections().size());
verify(mVcnNetworkProvider).resendAllRequests(requestListener);
- // Verify that the VcnGatewayConnection is restarted
+ // Verify that the VcnGatewayConnection is restarted if a request exists for it
triggerVcnRequestListeners(requestListener);
mTestLooper.dispatchAll();
assertEquals(2, mVcn.getVcnGatewayConnections().size());
@@ -254,21 +273,13 @@ public class VcnTest {
}
@Test
- public void testGatewayQuitWhileInactive() {
- final NetworkRequestListener requestListener = verifyAndGetRequestListener();
- final Set<VcnGatewayConnection> gatewayConnections =
- new ArraySet<>(startGatewaysAndGetGatewayConnections(requestListener));
-
- mVcn.teardownAsynchronously();
- mTestLooper.dispatchAll();
-
- final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
- statusCallback.onQuit();
- mTestLooper.dispatchAll();
+ public void testGatewayQuitReevaluatesRequests() {
+ verifyGatewayQuit(VCN_STATUS_CODE_ACTIVE);
+ }
- // Verify that the VCN requests the networkRequests be resent
- assertEquals(1, mVcn.getVcnGatewayConnections().size());
- verify(mVcnNetworkProvider, never()).resendAllRequests(requestListener);
+ @Test
+ public void testGatewayQuitReevaluatesRequestsInSafeMode() {
+ verifyGatewayQuit(VCN_STATUS_CODE_SAFE_MODE);
}
@Test
@@ -298,49 +309,4 @@ public class VcnTest {
verify(removedGatewayConnection).teardownAsynchronously();
verify(mVcnNetworkProvider).resendAllRequests(requestListener);
}
-
- @Test
- public void testUpdateConfigExitsSafeMode() {
- final NetworkRequestListener requestListener = verifyAndGetRequestListener();
- final Set<VcnGatewayConnection> gatewayConnections =
- new ArraySet<>(startGatewaysAndGetGatewayConnections(requestListener));
-
- final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
- statusCallback.onEnteredSafeMode();
- mTestLooper.dispatchAll();
- verifySafeMode(requestListener, gatewayConnections);
-
- doAnswer(invocation -> {
- final NetworkRequestListener listener = invocation.getArgument(0);
- triggerVcnRequestListeners(listener);
- return null;
- }).when(mVcnNetworkProvider).registerListener(eq(requestListener));
-
- mVcn.updateConfig(mConfig);
- mTestLooper.dispatchAll();
-
- // Registered on start, then re-registered with new configs
- verify(mVcnNetworkProvider, times(2)).registerListener(eq(requestListener));
- assertEquals(VCN_STATUS_CODE_ACTIVE, mVcn.getStatus());
- for (final int[] caps : TEST_CAPS) {
- // Expect each gateway connection created only on initial startup
- verify(mDeps)
- .newVcnGatewayConnection(
- eq(mVcnContext),
- eq(TEST_SUB_GROUP),
- eq(mSubscriptionSnapshot),
- argThat(config -> Arrays.equals(caps, config.getExposedCapabilities())),
- any());
- }
- }
-
- @Test
- public void testIgnoreNetworkRequestWhileInactive() {
- mVcn.setStatus(VCN_STATUS_CODE_INACTIVE);
-
- final NetworkRequestListener requestListener = verifyAndGetRequestListener();
- triggerVcnRequestListeners(requestListener);
-
- verify(mDeps, never()).newVcnGatewayConnection(any(), any(), any(), any(), any());
- }
}